[pkg-opensc-maint] Bug#1011065: libengine-pkcs11-openssl1.1: Drop transitional package
Bastian Germann
bage at debian.org
Fri Dec 9 13:15:30 GMT 2022
I have uploaded a NMU to DELAYED/3. debdiff attached.
-------------- next part --------------
diff -Nru libp11-0.4.11/aclocal.m4 libp11-0.4.12/aclocal.m4
--- libp11-0.4.11/aclocal.m4 2020-10-11 15:46:56.000000000 +0200
+++ libp11-0.4.12/aclocal.m4 2022-07-15 21:56:26.000000000 +0200
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.4 -*- Autoconf -*-
-# Copyright (C) 1996-2020 Free Software Foundation, Inc.
+# Copyright (C) 1996-2021 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -296,7 +296,7 @@
AS_VAR_IF([$1], [""], [$5], [$4])dnl
])dnl PKG_CHECK_VAR
-# Copyright (C) 2002-2020 Free Software Foundation, Inc.
+# Copyright (C) 2002-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -311,7 +311,7 @@
[am__api_version='1.16'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.16.2], [],
+m4_if([$1], [1.16.4], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -327,14 +327,14 @@
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.16.2])dnl
+[AM_AUTOMAKE_VERSION([1.16.4])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001-2020 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -386,7 +386,7 @@
# AM_CONDITIONAL -*- Autoconf -*-
-# Copyright (C) 1997-2020 Free Software Foundation, Inc.
+# Copyright (C) 1997-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -417,7 +417,7 @@
Usually this means the macro was only invoked conditionally.]])
fi])])
-# Copyright (C) 1999-2020 Free Software Foundation, Inc.
+# Copyright (C) 1999-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -608,7 +608,7 @@
# Generate code to set up dependency tracking. -*- Autoconf -*-
-# Copyright (C) 1999-2020 Free Software Foundation, Inc.
+# Copyright (C) 1999-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -676,7 +676,7 @@
# Do all the work for Automake. -*- Autoconf -*-
-# Copyright (C) 1996-2020 Free Software Foundation, Inc.
+# Copyright (C) 1996-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -740,7 +740,7 @@
[_AM_SET_OPTIONS([$1])dnl
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
m4_if(
- m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]),
[ok:ok],,
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
@@ -792,6 +792,20 @@
[m4_define([AC_PROG_OBJCXX],
m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
])
+# Variables for tags utilities; see am/tags.am
+if test -z "$CTAGS"; then
+ CTAGS=ctags
+fi
+AC_SUBST([CTAGS])
+if test -z "$ETAGS"; then
+ ETAGS=etags
+fi
+AC_SUBST([ETAGS])
+if test -z "$CSCOPE"; then
+ CSCOPE=cscope
+fi
+AC_SUBST([CSCOPE])
+
AC_REQUIRE([AM_SILENT_RULES])dnl
dnl The testsuite driver may need to know about EXEEXT, so add the
dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
@@ -873,7 +887,7 @@
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-# Copyright (C) 2001-2020 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -894,7 +908,7 @@
fi
AC_SUBST([install_sh])])
-# Copyright (C) 2003-2020 Free Software Foundation, Inc.
+# Copyright (C) 2003-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -915,7 +929,7 @@
# Check to see how 'make' treats includes. -*- Autoconf -*-
-# Copyright (C) 2001-2020 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -958,7 +972,7 @@
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-# Copyright (C) 1997-2020 Free Software Foundation, Inc.
+# Copyright (C) 1997-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -979,12 +993,7 @@
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([missing])dnl
if test x"${MISSING+set}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
- *)
- MISSING="\${SHELL} $am_aux_dir/missing" ;;
- esac
+ MISSING="\${SHELL} '$am_aux_dir/missing'"
fi
# Use eval to expand $SHELL
if eval "$MISSING --is-lightweight"; then
@@ -997,7 +1006,7 @@
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001-2020 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1026,7 +1035,7 @@
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-# Copyright (C) 1999-2020 Free Software Foundation, Inc.
+# Copyright (C) 1999-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1073,7 +1082,7 @@
# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
-# Copyright (C) 2001-2020 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1092,7 +1101,7 @@
# Check to make sure that the build environment is sane. -*- Autoconf -*-
-# Copyright (C) 1996-2020 Free Software Foundation, Inc.
+# Copyright (C) 1996-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1173,7 +1182,7 @@
rm -f conftest.file
])
-# Copyright (C) 2009-2020 Free Software Foundation, Inc.
+# Copyright (C) 2009-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1233,7 +1242,7 @@
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
])
-# Copyright (C) 2001-2020 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1261,7 +1270,7 @@
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
-# Copyright (C) 2006-2020 Free Software Foundation, Inc.
+# Copyright (C) 2006-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1280,7 +1289,7 @@
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004-2020 Free Software Foundation, Inc.
+# Copyright (C) 2004-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1411,6 +1420,7 @@
AC_SUBST([am__untar])
]) # _AM_PROG_TAR
+m4_include([m4/ax_pthread.m4])
m4_include([m4/ld-version-script.m4])
m4_include([m4/libtool.m4])
m4_include([m4/ltoptions.m4])
diff -Nru libp11-0.4.11/compile libp11-0.4.12/compile
--- libp11-0.4.11/compile 2018-10-02 20:47:03.000000000 +0200
+++ libp11-0.4.12/compile 2022-03-15 18:14:17.000000000 +0100
@@ -3,7 +3,7 @@
scriptversion=2018-03-07.03; # UTC
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey at cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
@@ -53,7 +53,7 @@
MINGW*)
file_conv=mingw
;;
- CYGWIN*)
+ CYGWIN* | MSYS*)
file_conv=cygwin
;;
*)
@@ -67,7 +67,7 @@
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
- cygwin/*)
+ cygwin/* | msys/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
diff -Nru libp11-0.4.11/config.guess libp11-0.4.12/config.guess
--- libp11-0.4.11/config.guess 2018-10-02 20:47:03.000000000 +0200
+++ libp11-0.4.12/config.guess 2022-03-15 18:14:17.000000000 +0100
@@ -2,7 +2,7 @@
# Attempt to guess a canonical system name.
# Copyright 1992-2018 Free Software Foundation, Inc.
-timestamp='2018-03-08'
+timestamp='2018-02-24'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -1046,7 +1046,11 @@
echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
exit ;;
x86_64:Linux:*:*)
- echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
+ if objdump -f /bin/sh | grep -q elf32-x86-64; then
+ echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32
+ else
+ echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
+ fi
exit ;;
xtensa*:Linux:*:*)
echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
@@ -1469,7 +1473,7 @@
exit 1
# Local variables:
-# eval: (add-hook 'before-save-hook 'time-stamp)
+# eval: (add-hook 'write-file-functions 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff -Nru libp11-0.4.11/config.sub libp11-0.4.12/config.sub
--- libp11-0.4.11/config.sub 2018-10-02 20:47:03.000000000 +0200
+++ libp11-0.4.12/config.sub 2022-03-15 18:14:17.000000000 +0100
@@ -2,7 +2,7 @@
# Configuration validation subroutine script.
# Copyright 1992-2018 Free Software Foundation, Inc.
-timestamp='2018-03-08'
+timestamp='2018-02-22'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -1376,7 +1376,7 @@
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* | -hcos* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
@@ -1794,7 +1794,7 @@
exit
# Local variables:
-# eval: (add-hook 'before-save-hook 'time-stamp)
+# eval: (add-hook 'write-file-functions 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff -Nru libp11-0.4.11/configure libp11-0.4.12/configure
--- libp11-0.4.11/configure 2020-10-11 15:46:57.000000000 +0200
+++ libp11-0.4.12/configure 2022-07-15 21:56:26.000000000 +0200
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for libp11 0.4.11.
+# Generated by GNU Autoconf 2.69 for libp11 0.4.12.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@
# Identity of this package.
PACKAGE_NAME='libp11'
PACKAGE_TARNAME='libp11'
-PACKAGE_VERSION='0.4.11'
-PACKAGE_STRING='libp11 0.4.11'
+PACKAGE_VERSION='0.4.12'
+PACKAGE_STRING='libp11 0.4.12'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -653,6 +653,11 @@
pkgconfigdir
OPENSSL_LIBS
OPENSSL_CFLAGS
+PTHREAD_CFLAGS
+PTHREAD_LIBS
+PTHREAD_CXX
+PTHREAD_CC
+ax_pthread_config
DOXYGEN
RC
LT_SYS_LIBRARY_PATH
@@ -700,18 +705,13 @@
LDFLAGS
CFLAGS
CC
-host_os
-host_vendor
-host_cpu
-host
-build_os
-build_vendor
-build_cpu
-build
AM_BACKSLASH
AM_DEFAULT_VERBOSITY
AM_DEFAULT_V
AM_V
+CSCOPE
+ETAGS
+CTAGS
am__untar
am__tar
AMTAR
@@ -735,6 +735,18 @@
INSTALL_DATA
INSTALL_SCRIPT
INSTALL_PROGRAM
+target_os
+target_vendor
+target_cpu
+target
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
target_alias
host_alias
build_alias
@@ -1363,7 +1375,7 @@
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures libp11 0.4.11 to adapt to many kinds of systems.
+\`configure' configures libp11 0.4.12 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1429,12 +1441,13 @@
System types:
--build=BUILD configure for building on BUILD [guessed]
--host=HOST cross-compile to build programs to run on HOST [BUILD]
+ --target=TARGET configure for building compilers for TARGET [HOST]
_ACEOF
fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of libp11 0.4.11:";;
+ short | recursive ) echo "Configuration of libp11 0.4.12:";;
esac
cat <<\_ACEOF
@@ -1565,7 +1578,7 @@
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-libp11 configure 0.4.11
+libp11 configure 0.4.12
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1930,7 +1943,7 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by libp11 $as_me 0.4.11, which was
+It was created by libp11 $as_me 0.4.12, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2310,6 +2323,116 @@
ac_config_headers="$ac_config_headers src/config.h"
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
+$as_echo_n "checking target system type... " >&6; }
+if ${ac_cv_target+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$target_alias" = x; then
+ ac_cv_target=$ac_cv_host
+else
+ ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
+$as_echo "$ac_cv_target" >&6; }
+case $ac_cv_target in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
+esac
+target=$ac_cv_target
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_target
+shift
+target_cpu=$1
+target_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+target_os=$*
+IFS=$ac_save_IFS
+case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
am__api_version='1.16'
# Find a good install program. We prefer a C program (faster),
@@ -2486,12 +2609,7 @@
am_aux_dir=`cd "$ac_aux_dir" && pwd`
if test x"${MISSING+set}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
- *)
- MISSING="\${SHELL} $am_aux_dir/missing" ;;
- esac
+ MISSING="\${SHELL} '$am_aux_dir/missing'"
fi
# Use eval to expand $SHELL
if eval "$MISSING --is-lightweight"; then
@@ -2796,7 +2914,7 @@
# Define the identity of the package.
PACKAGE='libp11'
- VERSION='0.4.11'
+ VERSION='0.4.12'
cat >>confdefs.h <<_ACEOF
@@ -2846,6 +2964,20 @@
+# Variables for tags utilities; see am/tags.am
+if test -z "$CTAGS"; then
+ CTAGS=ctags
+fi
+
+if test -z "$ETAGS"; then
+ ETAGS=etags
+fi
+
+if test -z "$CSCOPE"; then
+ CSCOPE=cscope
+fi
+
+
# POSIX will say in a future version that running "rm -f" with no argument
# is OK; and we want to be able to make that assumption in our Makefile
@@ -2892,7 +3024,7 @@
LIBP11_VERSION_MAJOR="0"
LIBP11_VERSION_MINOR="4"
-LIBP11_VERSION_FIX="11"
+LIBP11_VERSION_FIX="12"
@@ -2937,76 +3069,6 @@
AM_BACKSLASH='\'
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
- as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
-$as_echo_n "checking build system type... " >&6; }
-if ${ac_cv_build+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_build_alias=$build_alias
-test "x$ac_build_alias" = x &&
- ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
-test "x$ac_build_alias" = x &&
- as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
-$as_echo "$ac_cv_build" >&6; }
-case $ac_cv_build in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
-esac
-build=$ac_cv_build
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_build
-shift
-build_cpu=$1
-build_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-build_os=$*
-IFS=$ac_save_IFS
-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
-$as_echo_n "checking host system type... " >&6; }
-if ${ac_cv_host+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test "x$host_alias" = x; then
- ac_cv_host=$ac_cv_build
-else
- ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
-$as_echo "$ac_cv_host" >&6; }
-case $ac_cv_host in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
-esac
-host=$ac_cv_host
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_host
-shift
-host_cpu=$1
-host_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-host_os=$*
-IFS=$ac_save_IFS
-case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
-
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@@ -4818,8 +4880,8 @@
# the openssl version we link to. If the ABI is broken on a later
# release, we should either stick to supporting a single openssl ABI
# or bump the LT_OLDEST version sufficiently to avoid clashes.
-LIBP11_LT_REVISION="3"
-LIBP11_LT_CURRENT="7"
+LIBP11_LT_REVISION="0"
+LIBP11_LT_CURRENT="8"
LIBP11_LT_AGE="$((${LIBP11_LT_CURRENT}-${LIBP11_LT_OLDEST}))"
@@ -4911,7 +4973,7 @@
case "${host}" in
*-mingw*|*-winnt*)
WIN32="yes"
- CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN"
+ CPPFLAGS="${CPPFLAGS} -D_WIN32_WINNT=0x0600 -DWIN32_LEAN_AND_MEAN"
WIN_LIBPREFIX="lib"
;;
*-cygwin*)
@@ -5267,8 +5329,8 @@
-macro_version='2.4.6.42-b88ce'
-macro_revision='2.4.6.42'
+macro_version='2.4.6'
+macro_revision='2.4.6'
@@ -6353,7 +6415,7 @@
lt_cv_deplibs_check_method=pass_all
;;
-netbsd*)
+netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
else
@@ -6712,29 +6774,13 @@
fi
: ${AR=ar}
+: ${AR_FLAGS=cr}
-# Use ARFLAGS variable as AR's operation code to sync the variable naming with
-# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
-# higher priority because thats what people were doing historically (setting
-# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS
-# variable obsoleted/removed.
-
-test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
-lt_ar_flags=$AR_FLAGS
-
-
-
-
-
-
-# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override
-# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
-
@@ -7183,7 +7229,7 @@
if test "$lt_cv_nm_interface" = "MS dumpbin"; then
# Fake it for dumpbin and say T for any non-static function,
# D for any global variable and I for any imported variable.
- # Also find C++ and __fastcall symbols from MSVC++ or ICC,
+ # Also find C++ and __fastcall symbols from MSVC++,
# which start with @ or ?.
lt_cv_sys_global_symbol_pipe="$AWK '"\
" {last_section=section; section=\$ 3};"\
@@ -7229,11 +7275,8 @@
test $ac_status = 0; }; then
# Now try to grab the symbols.
nlist=conftest.nm
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
- (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s "$nlist"; then
+ $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5
+ if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then
# Try sorting and uniquifying the output.
if sort "$nlist" | uniq > "$nlist"T; then
mv -f "$nlist"T "$nlist"
@@ -8452,8 +8495,8 @@
_LT_EOF
echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
$LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
- echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5
- $AR $AR_FLAGS libconftest.a conftest.o 2>&5
+ echo "$AR cr libconftest.a conftest.o" >&5
+ $AR cr libconftest.a conftest.o 2>&5
echo "$RANLIB libconftest.a" >&5
$RANLIB libconftest.a 2>&5
cat > conftest.c << _LT_EOF
@@ -8485,11 +8528,11 @@
# to the OS version, if on x86, and 10.4, the deployment
# target defaults to 10.4. Don't you love it?
case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
- 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ 10.0,*86*-darwin8*|10.0,*-darwin[912]*)
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
10.[012][,.]*)
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
- 10.*)
+ 10.*|11.*)
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
esac
;;
@@ -9147,8 +9190,8 @@
ofile=libtool
can_build_shared=yes
-# All known linkers require a '.a' archive for static linking (except MSVC and
-# ICC, which need '.lib').
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
libext=a
with_gnu_ld=$lt_cv_prog_gnu_ld
@@ -9613,6 +9656,12 @@
lt_prog_compiler_pic='-KPIC'
lt_prog_compiler_static='-static'
;;
+ # flang / f18. f95 an alias for gfortran or flang on Debian
+ flang* | f18* | f95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
# icc used to be incompatible with GCC.
# ICC 10 doesn't accept -KPIC any more.
icc* | ifort*)
@@ -10075,20 +10124,23 @@
case $host_os in
cygwin* | mingw* | pw32* | cegcc*)
- # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
- # Microsoft Visual C++ or Intel C++ Compiler.
+ # Microsoft Visual C++.
if test yes != "$GCC"; then
with_gnu_ld=no
fi
;;
interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
with_gnu_ld=yes
;;
openbsd* | bitrig*)
with_gnu_ld=no
;;
+ linux* | k*bsd*-gnu | gnu*)
+ link_all_deplibs=no
+ ;;
esac
ld_shlibs=yes
@@ -10247,7 +10299,6 @@
emximp -o $lib $output_objdir/$libname.def'
old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
enable_shared_with_static_runtimes=yes
- file_list_spec='@'
;;
interix[3-9]*)
@@ -10344,7 +10395,7 @@
fi
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
@@ -10465,7 +10516,7 @@
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
else
- export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
fi
aix_use_runtimelinking=no
@@ -10732,12 +10783,12 @@
cygwin* | mingw* | pw32* | cegcc*)
# When not using gcc, we currently assume that we are using
- # Microsoft Visual C++ or Intel C++ Compiler.
+ # Microsoft Visual C++.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
case $cc_basename in
- cl* | icl*)
- # Native MSVC or ICC
+ cl*)
+ # Native MSVC
hardcode_libdir_flag_spec=' '
allow_undefined_flag=unsupported
always_export_symbols=yes
@@ -10778,7 +10829,7 @@
fi'
;;
*)
- # Assume MSVC and ICC wrapper
+ # Assume MSVC wrapper
hardcode_libdir_flag_spec=' '
allow_undefined_flag=unsupported
# Tell ltmain to make .lib files, not .a files.
@@ -11014,6 +11065,7 @@
if test yes = "$lt_cv_irix_exported_symbol"; then
archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
fi
+ link_all_deplibs=no
else
archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -11035,7 +11087,7 @@
esac
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
@@ -11102,7 +11154,6 @@
emximp -o $lib $output_objdir/$libname.def'
old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
enable_shared_with_static_runtimes=yes
- file_list_spec='@'
;;
osf3*)
@@ -11810,8 +11861,8 @@
dynamic_linker='Win32 ld.exe'
;;
- *,cl* | *,icl*)
- # Native MSVC or ICC
+ *,cl*)
+ # Native MSVC
libname_spec='$name'
soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
library_names_spec='$libname.dll.lib'
@@ -11867,7 +11918,7 @@
;;
*)
- # Assume MSVC and ICC wrapper
+ # Assume MSVC wrapper
library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
dynamic_linker='Win32 ld.exe'
;;
@@ -12151,6 +12202,18 @@
dynamic_linker='GNU/Linux ld.so'
;;
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
netbsd*)
version_type=sunos
need_lib_prefix=no
@@ -13046,41 +13109,30 @@
old_striplib=
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
$as_echo_n "checking whether stripping libraries is possible... " >&6; }
-if test -z "$STRIP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-else
- if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
- old_striplib="$STRIP --strip-debug"
- striplib="$STRIP --strip-unneeded"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- else
- case $host_os in
- darwin*)
- # FIXME - insert some real tests, host_os isn't really good enough
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
striplib="$STRIP -x"
old_striplib="$STRIP -S"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- ;;
- freebsd*)
- if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
- old_striplib="$STRIP --strip-debug"
- striplib="$STRIP --strip-unneeded"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- fi
- ;;
- *)
+ else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- ;;
- esac
- fi
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
fi
@@ -13617,17 +13669,733 @@
fi
- for ac_func in __register_atfork
-do :
- ac_fn_c_check_func "$LINENO" "__register_atfork" "ac_cv_func___register_atfork"
-if test "x$ac_cv_func___register_atfork" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE___REGISTER_ATFORK 1
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on Tru64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
+ ax_pthread_save_CC="$CC"
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ ax_pthread_save_LIBS="$LIBS"
+ if test "x$PTHREAD_CC" != "x"; then :
+ CC="$PTHREAD_CC"
+fi
+ if test "x$PTHREAD_CXX" != "x"; then :
+ CXX="$PTHREAD_CXX"
+fi
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS" >&5
+$as_echo_n "checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_join ();
+int
+main ()
+{
+return pthread_join ();
+ ;
+ return 0;
+}
_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ax_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
+$as_echo "$ax_pthread_ok" >&6; }
+ if test "x$ax_pthread_ok" = "xno"; then
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+ fi
+ CC="$ax_pthread_save_CC"
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ LIBS="$ax_pthread_save_LIBS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items with a "," contain both
+# C compiler flags (before ",") and linker flags (after ","). Other items
+# starting with a "-" are C compiler flags, and remaining items are
+# library names, except for "none" which indicates that we try without
+# any flags at all, and "pthread-config" which is a program returning
+# the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important. Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+# other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
+# (Note: HP C rejects this with "bad form for `-t' option")
+# -pthreads: Solaris/gcc (Note: HP C also rejects)
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+# doesn't hurt to check since this sometimes defines pthreads and
+# -D_REENTRANT too), HP C (must be checked before -lpthread, which
+# is present but should not be used directly; and before -mthreads,
+# because the compiler interprets this as "-mt" + "-hreads")
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case $target_os in
+
+ freebsd*)
+
+ # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+ # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+
+ ax_pthread_flags="-kthread lthread $ax_pthread_flags"
+ ;;
+
+ hpux*)
+
+ # From the cc(1) man page: "[-mt] Sets various -D flags to enable
+ # multi-threading and also sets -lpthread."
+
+ ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
+ ;;
+
+ openedition*)
+
+ # IBM z/OS requires a feature-test macro to be defined in order to
+ # enable POSIX threads at all, so give the user a hint if this is
+ # not set. (We don't define these ourselves, as they can affect
+ # other portions of the system API in unpredictable ways.)
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
+ AX_PTHREAD_ZOS_MISSING
+# endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "AX_PTHREAD_ZOS_MISSING" >/dev/null 2>&1; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&5
+$as_echo "$as_me: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&2;}
+fi
+rm -f conftest*
+
+ ;;
+
+ solaris*)
+
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (N.B.: The stubs are missing
+ # pthread_cleanup_push, or rather a function called by this macro,
+ # so we could check for that, but who knows whether they'll stub
+ # that too in a future libc.) So we'll check first for the
+ # standard Solaris way of linking pthreads (-mt -lpthread).
+
+ ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags"
+ ;;
+esac
+
+# Are we compiling with Clang?
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC is Clang" >&5
+$as_echo_n "checking whether $CC is Clang... " >&6; }
+if ${ax_cv_PTHREAD_CLANG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ax_cv_PTHREAD_CLANG=no
+ # Note that Autoconf sets GCC=yes for Clang as well as GCC
+ if test "x$GCC" = "xyes"; then
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
+# if defined(__clang__) && defined(__llvm__)
+ AX_PTHREAD_CC_IS_CLANG
+# endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "AX_PTHREAD_CC_IS_CLANG" >/dev/null 2>&1; then :
+ ax_cv_PTHREAD_CLANG=yes
+fi
+rm -f conftest*
+
+ fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG" >&5
+$as_echo "$ax_cv_PTHREAD_CLANG" >&6; }
+ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+
+
+# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
+
+# Note that for GCC and Clang -pthread generally implies -lpthread,
+# except when -nostdlib is passed.
+# This is problematic using libtool to build C++ shared libraries with pthread:
+# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
+# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333
+# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555
+# To solve this, first try -pthread together with -lpthread for GCC
+
+if test "x$GCC" = "xyes"; then :
+ ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"
+fi
+
+# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first
+
+if test "x$ax_pthread_clang" = "xyes"; then :
+ ax_pthread_flags="-pthread,-lpthread -pthread"
+fi
+
+
+# The presence of a feature test macro requesting re-entrant function
+# definitions is, on some systems, a strong hint that pthreads support is
+# correctly enabled
+
+case $target_os in
+ darwin* | hpux* | linux* | osf* | solaris*)
+ ax_pthread_check_macro="_REENTRANT"
+ ;;
+
+ aix*)
+ ax_pthread_check_macro="_THREAD_SAFE"
+ ;;
+
+ *)
+ ax_pthread_check_macro="--"
+ ;;
+esac
+if test "x$ax_pthread_check_macro" = "x--"; then :
+ ax_pthread_check_cond=0
+else
+ ax_pthread_check_cond="!defined($ax_pthread_check_macro)"
+fi
+
+
+if test "x$ax_pthread_ok" = "xno"; then
+for ax_pthread_try_flag in $ax_pthread_flags; do
+
+ case $ax_pthread_try_flag in
+ none)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
+$as_echo_n "checking whether pthreads work without any flags... " >&6; }
+ ;;
+
+ *,*)
+ PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"`
+ PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with \"$PTHREAD_CFLAGS\" and \"$PTHREAD_LIBS\"" >&5
+$as_echo_n "checking whether pthreads work with \"$PTHREAD_CFLAGS\" and \"$PTHREAD_LIBS\"... " >&6; }
+ ;;
+
+ -*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $ax_pthread_try_flag" >&5
+$as_echo_n "checking whether pthreads work with $ax_pthread_try_flag... " >&6; }
+ PTHREAD_CFLAGS="$ax_pthread_try_flag"
+ ;;
+
+ pthread-config)
+ # Extract the first word of "pthread-config", so it can be a program name with args.
+set dummy pthread-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ax_pthread_config+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ax_pthread_config"; then
+ ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ax_pthread_config="yes"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no"
+fi
+fi
+ax_pthread_config=$ac_cv_prog_ax_pthread_config
+if test -n "$ax_pthread_config"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5
+$as_echo "$ax_pthread_config" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$ax_pthread_config" = "xno"; then :
+ continue
+fi
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$ax_pthread_try_flag" >&5
+$as_echo_n "checking for the pthreads library -l$ax_pthread_try_flag... " >&6; }
+ PTHREAD_LIBS="-l$ax_pthread_try_flag"
+ ;;
+ esac
+
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ ax_pthread_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pthread.h>
+# if $ax_pthread_check_cond
+# error "$ax_pthread_check_macro must be defined"
+# endif
+ static void *some_global = NULL;
+ static void routine(void *a)
+ {
+ /* To avoid any unused-parameter or
+ unused-but-set-parameter warning. */
+ some_global = a;
+ }
+ static void *start_routine(void *a) { return a; }
+int
+main ()
+{
+pthread_t th; pthread_attr_t attr;
+ pthread_create(&th, 0, start_routine, 0);
+ pthread_join(th, 0);
+ pthread_attr_init(&attr);
+ pthread_cleanup_push(routine, 0);
+ pthread_cleanup_pop(0) /* ; */
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ax_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ LIBS="$ax_pthread_save_LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
+$as_echo "$ax_pthread_ok" >&6; }
+ if test "x$ax_pthread_ok" = "xyes"; then :
+ break
+fi
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
+
+
+# Clang needs special handling, because older versions handle the -pthread
+# option in a rather... idiosyncratic way
+
+if test "x$ax_pthread_clang" = "xyes"; then
+
+ # Clang takes -pthread; it has never supported any other flag
+
+ # (Note 1: This will need to be revisited if a system that Clang
+ # supports has POSIX threads in a separate library. This tends not
+ # to be the way of modern systems, but it's conceivable.)
+
+ # (Note 2: On some systems, notably Darwin, -pthread is not needed
+ # to get POSIX threads support; the API is always present and
+ # active. We could reasonably leave PTHREAD_CFLAGS empty. But
+ # -pthread does define _REENTRANT, and while the Darwin headers
+ # ignore this macro, third-party headers might not.)
+
+ # However, older versions of Clang make a point of warning the user
+ # that, in an invocation where only linking and no compilation is
+ # taking place, the -pthread option has no effect ("argument unused
+ # during compilation"). They expect -pthread to be passed in only
+ # when source code is being compiled.
+ #
+ # Problem is, this is at odds with the way Automake and most other
+ # C build frameworks function, which is that the same flags used in
+ # compilation (CFLAGS) are also used in linking. Many systems
+ # supported by AX_PTHREAD require exactly this for POSIX threads
+ # support, and in fact it is often not straightforward to specify a
+ # flag that is used only in the compilation phase and not in
+ # linking. Such a scenario is extremely rare in practice.
+ #
+ # Even though use of the -pthread flag in linking would only print
+ # a warning, this can be a nuisance for well-run software projects
+ # that build with -Werror. So if the active version of Clang has
+ # this misfeature, we search for an option to squash it.
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread" >&5
+$as_echo_n "checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread... " >&6; }
+if ${ax_cv_PTHREAD_CLANG_NO_WARN_FLAG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
+ # Create an alternate version of $ac_link that compiles and
+ # links in two steps (.c -> .o, .o -> exe) instead of one
+ # (.c -> exe), because the warning occurs only in the second
+ # step
+ ax_pthread_save_ac_link="$ac_link"
+ ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
+ ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
+ ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
+ if test "x$ax_pthread_try" = "xunknown"; then :
+ break
+fi
+ CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
+ ac_link="$ax_pthread_save_ac_link"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int main(void){return 0;}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_link="$ax_pthread_2step_ac_link"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int main(void){return 0;}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+ ac_link="$ax_pthread_save_ac_link"
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ if test "x$ax_pthread_try" = "x"; then :
+ ax_pthread_try=no
+fi
+ ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&5
+$as_echo "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&6; }
+
+ case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
+ no | unknown) ;;
+ *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
+ esac
+
+fi # $ax_pthread_clang = yes
+
+
+
+# Various other checks:
+if test "x$ax_pthread_ok" = "xyes"; then
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ ax_pthread_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+
+ # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
+$as_echo_n "checking for joinable pthread attribute... " >&6; }
+if ${ax_cv_PTHREAD_JOINABLE_ATTR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ax_cv_PTHREAD_JOINABLE_ATTR=unknown
+ for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+int attr = $ax_pthread_attr; return attr /* ; */
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_JOINABLE_ATTR" >&5
+$as_echo "$ax_cv_PTHREAD_JOINABLE_ATTR" >&6; }
+ if test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
+ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
+ test "x$ax_pthread_joinable_attr_defined" != "xyes"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define PTHREAD_CREATE_JOINABLE $ax_cv_PTHREAD_JOINABLE_ATTR
+_ACEOF
+
+ ax_pthread_joinable_attr_defined=yes
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether more special flags are required for pthreads" >&5
+$as_echo_n "checking whether more special flags are required for pthreads... " >&6; }
+if ${ax_cv_PTHREAD_SPECIAL_FLAGS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ax_cv_PTHREAD_SPECIAL_FLAGS=no
+ case $target_os in
+ solaris*)
+ ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
+ ;;
+ esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_SPECIAL_FLAGS" >&5
+$as_echo "$ax_cv_PTHREAD_SPECIAL_FLAGS" >&6; }
+ if test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
+ test "x$ax_pthread_special_flags_added" != "xyes"; then :
+ PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
+ ax_pthread_special_flags_added=yes
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5
+$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; }
+if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+int i = PTHREAD_PRIO_INHERIT;
+ return i;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ax_cv_PTHREAD_PRIO_INHERIT=yes
+else
+ ax_cv_PTHREAD_PRIO_INHERIT=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5
+$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; }
+ if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
+ test "x$ax_pthread_prio_inherit_defined" != "xyes"; then :
+
+$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h
+
+ ax_pthread_prio_inherit_defined=yes
+
+fi
+
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ LIBS="$ax_pthread_save_LIBS"
+
+ # More AIX lossage: compile with *_r variant
+ if test "x$GCC" != "xyes"; then
+ case $target_os in
+ aix*)
+ case "x/$CC" in #(
+ x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6) :
+ #handle absolute path differently from PATH based program lookup
+ case "x$CC" in #(
+ x/*) :
+
+ if as_fn_executable_p ${CC}_r; then :
+ PTHREAD_CC="${CC}_r"
+fi
+ if test "x${CXX}" != "x"; then :
+ if as_fn_executable_p ${CXX}_r; then :
+ PTHREAD_CXX="${CXX}_r"
+fi
+fi
+ ;; #(
+ *) :
+
+ for ac_prog in ${CC}_r
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PTHREAD_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$PTHREAD_CC"; then
+ ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_PTHREAD_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
+if test -n "$PTHREAD_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
+$as_echo "$PTHREAD_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$PTHREAD_CC" && break
+done
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+
+ if test "x${CXX}" != "x"; then :
+ for ac_prog in ${CXX}_r
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PTHREAD_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$PTHREAD_CXX"; then
+ ac_cv_prog_PTHREAD_CXX="$PTHREAD_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_PTHREAD_CXX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
fi
+fi
+PTHREAD_CXX=$ac_cv_prog_PTHREAD_CXX
+if test -n "$PTHREAD_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CXX" >&5
+$as_echo "$PTHREAD_CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$PTHREAD_CXX" && break
done
+test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX"
+
+fi
+ ;;
+esac
+ ;; #(
+ *) :
+ ;;
+esac
+ ;;
+ esac
+ fi
+fi
+
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX"
+
+
+
+
+
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test "x$ax_pthread_ok" = "xyes"; then
+
+$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
+
+ :
+else
+ ax_pthread_ok=no
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ CC="$PTHREAD_CC"
fi
@@ -14326,7 +15094,7 @@
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by libp11 $as_me 0.4.11, which was
+This file was extended by libp11 $as_me 0.4.12, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -14392,7 +15160,7 @@
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-libp11 config.status 0.4.11
+libp11 config.status 0.4.12
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -14564,7 +15332,6 @@
want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
-lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`'
AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
@@ -14736,6 +15503,7 @@
want_nocaseglob \
sharedlib_from_linklib_cmd \
AR \
+AR_FLAGS \
archiver_list_spec \
STRIP \
RANLIB \
@@ -15598,7 +16366,6 @@
cat <<_LT_EOF >> "$cfgfile"
#! $SHELL
# Generated automatically by $as_me ($PACKAGE) $VERSION
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
# Provide generalized library-building support services.
@@ -15745,11 +16512,8 @@
# The archiver.
AR=$lt_AR
-# Flags to create an archive (by configure).
-lt_ar_flags=$lt_ar_flags
-
# Flags to create an archive.
-AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"}
+AR_FLAGS=$lt_AR_FLAGS
# How to feed a file listing to the archiver.
archiver_list_spec=$lt_archiver_list_spec
diff -Nru libp11-0.4.11/configure.ac libp11-0.4.12/configure.ac
--- libp11-0.4.11/configure.ac 2020-10-11 15:46:53.000000000 +0200
+++ libp11-0.4.12/configure.ac 2022-07-15 21:56:04.000000000 +0200
@@ -5,13 +5,14 @@
# When bumping versions see also the LT version numbers below.
define([PACKAGE_VERSION_MAJOR], [0])
define([PACKAGE_VERSION_MINOR], [4])
-define([PACKAGE_VERSION_FIX], [11])
+define([PACKAGE_VERSION_FIX], [12])
define([PACKAGE_SUFFIX], [])
AC_INIT([libp11],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX])
AC_CONFIG_AUX_DIR([.])
AC_CONFIG_HEADERS([src/config.h])
AC_CONFIG_MACRO_DIR([m4])
+AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([subdir-objects])
LIBP11_VERSION_MAJOR="PACKAGE_VERSION_MAJOR"
@@ -56,8 +57,8 @@
# the openssl version we link to. If the ABI is broken on a later
# release, we should either stick to supporting a single openssl ABI
# or bump the LT_OLDEST version sufficiently to avoid clashes.
-LIBP11_LT_REVISION="3"
-LIBP11_LT_CURRENT="7"
+LIBP11_LT_REVISION="0"
+LIBP11_LT_CURRENT="8"
LIBP11_LT_AGE="$((${LIBP11_LT_CURRENT}-${LIBP11_LT_OLDEST}))"
gl_LD_VERSION_SCRIPT
@@ -75,7 +76,7 @@
case "${host}" in
*-mingw*|*-winnt*)
WIN32="yes"
- CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN"
+ CPPFLAGS="${CPPFLAGS} -D_WIN32_WINNT=0x0600 -DWIN32_LEAN_AND_MEAN"
WIN_LIBPREFIX="lib"
;;
*-cygwin*)
@@ -193,7 +194,10 @@
,
[AC_MSG_ERROR([dlopen required])]
)
- AC_CHECK_FUNCS([__register_atfork],,)
+ AX_PTHREAD
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ CC="$PTHREAD_CC"
fi
PKG_CHECK_MODULES(
diff -Nru libp11-0.4.11/debian/changelog libp11-0.4.12/debian/changelog
--- libp11-0.4.11/debian/changelog 2020-10-18 04:48:01.000000000 +0200
+++ libp11-0.4.12/debian/changelog 2022-12-09 13:58:32.000000000 +0100
@@ -1,3 +1,11 @@
+libp11 (0.4.12-0.1) unstable; urgency=medium
+
+ * Non-maintainer upload
+ * New upstream release (Closes: #1017385, #1017386)
+ * Drop transitional package (Closes: #1011065)
+
+ -- Bastian Germann <bage at debian.org> Fri, 09 Dec 2022 12:58:32 +0000
+
libp11 (0.4.11-1) unstable; urgency=medium
* New upstream release
diff -Nru libp11-0.4.11/debian/control libp11-0.4.12/debian/control
--- libp11-0.4.11/debian/control 2020-10-18 04:48:01.000000000 +0200
+++ libp11-0.4.12/debian/control 2022-12-09 13:58:32.000000000 +0100
@@ -44,10 +44,6 @@
Architecture: any
Multi-Arch: same
Depends: p11-kit, ${misc:Depends}, ${shlibs:Depends}
-Conflicts: libopensc-openssl
-Breaks: libengine-pkcs11-openssl1.1 (<< 0.4.9-2)
-Replaces: libopensc-openssl, libengine-pkcs11-openssl1.1 (<< 0.4.9-2)
-Provides: libopensc-openssl, libengine-pkcs11-openssl1.1
Description: OpenSSL engine for PKCS#11 modules
With this engine for OpenSSL you can use OpenSSL library
and command line tools with any PKCS#11 implementation as
@@ -59,11 +55,3 @@
.
Engine_pkcs11 is a spin off from OpenSC and replaced
libopensc-openssl.
-
-Package: libengine-pkcs11-openssl1.1
-Section: oldlibs
-Architecture: any
-Multi-Arch: same
-Depends: libengine-pkcs11-openssl (= ${binary:Version}), ${misc:Depends}
-Description: dummy package for upgrades from libengine-pkcs11-openssl1.1
- Can be safely removed.
diff -Nru libp11-0.4.11/debian/libp11-3.symbols libp11-0.4.12/debian/libp11-3.symbols
--- libp11-0.4.11/debian/libp11-3.symbols 2020-10-18 04:48:01.000000000 +0200
+++ libp11-0.4.12/debian/libp11-3.symbols 2022-12-09 13:58:32.000000000 +0100
@@ -48,4 +48,5 @@
PKCS11_store_certificate at LIBP11_3 0.4.4
PKCS11_store_private_key at LIBP11_3 0.4.4
PKCS11_store_public_key at LIBP11_3 0.4.4
+ PKCS11_update_slots at LIBP11_3 0.4.12
PKCS11_verify at LIBP11_3 0.4.4
diff -Nru libp11-0.4.11/debian/watch libp11-0.4.12/debian/watch
--- libp11-0.4.11/debian/watch 2020-10-18 04:48:01.000000000 +0200
+++ libp11-0.4.12/debian/watch 2022-12-09 13:55:18.000000000 +0100
@@ -1,4 +1,4 @@
version=4
-opts=pgpsigurlmangle=s/$/.asc/ \
- https://github.com/OpenSC/libp11/releases .*/download/(?:.*/)libp11-([\d\.]*)\.tar\.gz
+opts=searchmode=plain,pgpsigurlmangle=s/$/.asc/ \
+ https://api.github.com/repos/OpenSC/libp11/releases https://github.com/OpenSC/libp11/releases/download/libp11-[\d\.]+/libp11-([\d\.]+)\.tar\.gz
diff -Nru libp11-0.4.11/depcomp libp11-0.4.12/depcomp
--- libp11-0.4.11/depcomp 2018-10-02 20:47:03.000000000 +0200
+++ libp11-0.4.12/depcomp 2022-03-15 18:14:17.000000000 +0100
@@ -3,7 +3,7 @@
scriptversion=2018-03-07.03; # UTC
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
# 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
diff -Nru libp11-0.4.11/doc/Makefile.in libp11-0.4.12/doc/Makefile.in
--- libp11-0.4.11/doc/Makefile.in 2020-10-11 15:46:57.000000000 +0200
+++ libp11-0.4.12/doc/Makefile.in 2022-07-15 21:56:26.000000000 +0200
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.2 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -88,9 +88,11 @@
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+target_triplet = @target@
subdir = doc
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ld-version-script.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \
+ $(top_srcdir)/m4/ld-version-script.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -167,6 +169,8 @@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
@@ -178,6 +182,7 @@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
+ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
@@ -224,6 +229,10 @@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_CXX = @PTHREAD_CXX@
+PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
RC = @RC@
SED = @SED@
@@ -246,6 +255,7 @@
am__tar = @am__tar@
am__untar = @am__untar@
apidocdir = @apidocdir@
+ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -285,7 +295,11 @@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
+target = @target@
target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@@ -381,7 +395,6 @@
cscope cscopelist:
-
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
diff -Nru libp11-0.4.11/examples/auth.c libp11-0.4.12/examples/auth.c
--- libp11-0.4.11/examples/auth.c 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/examples/auth.c 2022-07-05 22:22:51.000000000 +0200
@@ -267,10 +267,10 @@
/* now verify the result */
rc = RSA_verify(NID_sha1, random, RANDOM_SIZE,
-#if OPENSSL_VERSION_NUMBER >= 0x10100003L && !defined(LIBRESSL_VERSION_NUMBER)
- signature, siglen, EVP_PKEY_get0_RSA(pubkey));
+#if OPENSSL_VERSION_NUMBER >= 0x10100003L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL )
+ signature, siglen, (RSA *)EVP_PKEY_get0_RSA(pubkey));
#else
- signature, siglen, pubkey->pkey.rsa);
+ signature, siglen, (RSA *)pubkey->pkey.rsa);
#endif
if (rc != 1) {
fprintf(stderr, "fatal: RSA_verify failed\n");
@@ -302,7 +302,7 @@
if (rc)
printf("authentication failed.\n");
else
- printf("authentication successfull.\n");
+ printf("authentication successful.\n");
return rc;
}
diff -Nru libp11-0.4.11/examples/decrypt.c libp11-0.4.12/examples/decrypt.c
--- libp11-0.4.11/examples/decrypt.c 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/examples/decrypt.c 2022-07-05 22:22:51.000000000 +0200
@@ -168,7 +168,7 @@
}
/* allocate destination buffer */
-#if OPENSSL_VERSION_NUMBER >= 0x10100003L && !defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER >= 0x10100003L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL )
encrypted = OPENSSL_malloc(RSA_size(EVP_PKEY_get0_RSA(pubkey)));
#else
encrypted = OPENSSL_malloc(RSA_size(pubkey->pkey.rsa));
@@ -181,8 +181,8 @@
/* use public key for encryption */
len = RSA_public_encrypt(RANDOM_SIZE, random, encrypted,
-#if OPENSSL_VERSION_NUMBER >= 0x10100003L && !defined(LIBRESSL_VERSION_NUMBER)
- EVP_PKEY_get0_RSA(pubkey),
+#if OPENSSL_VERSION_NUMBER >= 0x10100003L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL )
+ (RSA *)EVP_PKEY_get0_RSA(pubkey),
#else
pubkey->pkey.rsa,
#endif
@@ -248,7 +248,7 @@
}
/* allocate space for decrypted data */
-#if OPENSSL_VERSION_NUMBER >= 0x10100003L && !defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER >= 0x10100003L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL )
decrypted = OPENSSL_malloc(RSA_size(EVP_PKEY_get0_RSA(pubkey)));
#else
decrypted = OPENSSL_malloc(RSA_size(pubkey->pkey.rsa));
@@ -299,7 +299,7 @@
if (rc)
printf("decryption failed.\n");
else
- printf("decryption successfull.\n");
+ printf("decryption successful.\n");
return rc;
}
diff -Nru libp11-0.4.11/examples/Makefile.in libp11-0.4.12/examples/Makefile.in
--- libp11-0.4.11/examples/Makefile.in 2020-10-11 15:46:57.000000000 +0200
+++ libp11-0.4.12/examples/Makefile.in 2022-07-15 21:56:26.000000000 +0200
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.2 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -88,11 +88,13 @@
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+target_triplet = @target@
noinst_PROGRAMS = auth$(EXEEXT) decrypt$(EXEEXT) getrandom$(EXEEXT) \
listkeys$(EXEEXT)
subdir = examples
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ld-version-script.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \
+ $(top_srcdir)/m4/ld-version-script.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -185,8 +187,6 @@
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
@@ -203,6 +203,8 @@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
@@ -214,6 +216,7 @@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
+ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
@@ -260,6 +263,10 @@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_CXX = @PTHREAD_CXX@
+PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
RC = @RC@
SED = @SED@
@@ -282,6 +289,7 @@
am__tar = @am__tar@
am__untar = @am__untar@
apidocdir = @apidocdir@
+ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -321,7 +329,11 @@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
+target = @target@
target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@@ -488,7 +500,6 @@
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
diff -Nru libp11-0.4.11/INSTALL.md libp11-0.4.12/INSTALL.md
--- libp11-0.4.11/INSTALL.md 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/INSTALL.md 2022-07-05 22:22:51.000000000 +0200
@@ -100,12 +100,12 @@
### MinGW cross-compile on a Unix host
-We assume that OpenSSL is installed in /opt/openssl-mingw64.
-Update the paths to match your environment.
+Example configuration for a 64-bit OpenSSL installed in /opt/openssl-mingw64:
+ PKG_CONFIG_PATH=/opt/openssl-mingw64/lib64/pkgconfig ./configure --host=x86_64-w64-mingw32 --prefix=/opt/libp11-mingw64
- export PKG_CONFIG_PATH=/opt/openssl-mingw64/lib/pkgconfig
-
- ./configure --host=x86_64-w64-mingw32 --prefix=/opt/libp11-mingw64
+Example configuration for a 32-bit OpenSSL installed in /opt/openssl-mingw:
+ PKG_CONFIG_PATH=/opt/openssl-mingw/lib/pkgconfig ./configure --host=i686-w64-mingw32 --prefix=/opt/libp11-mingw
+Building and installing:
make && sudo make install
diff -Nru libp11-0.4.11/install-sh libp11-0.4.12/install-sh
--- libp11-0.4.11/install-sh 2018-10-02 20:47:03.000000000 +0200
+++ libp11-0.4.12/install-sh 2022-03-15 18:14:17.000000000 +0100
@@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
-scriptversion=2018-03-11.20; # UTC
+scriptversion=2020-11-14.01; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@@ -69,6 +69,11 @@
# Desired mode of installed file.
mode=0755
+# Create dirs (including intermediate dirs) using mode 755.
+# This is like GNU 'install' as of coreutils 8.32 (2020).
+mkdir_umask=22
+
+backupsuffix=
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
@@ -99,18 +104,28 @@
--version display version info and exit.
-c (ignored)
- -C install only if different (preserve the last data modification time)
+ -C install only if different (preserve data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
+ -p pass -p to $cpprog.
-s $stripprog installed files.
+ -S SUFFIX attempt to back up existing files, with suffix SUFFIX.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
+
+By default, rm is invoked with -f; when overridden with RMPROG,
+it's up to you to specify -f if you want it.
+
+If -S is not specified, no backups are attempted.
+
+Email bug reports to bug-automake at gnu.org.
+Automake home page: https://www.gnu.org/software/automake/
"
while test $# -ne 0; do
@@ -137,8 +152,13 @@
-o) chowncmd="$chownprog $2"
shift;;
+ -p) cpprog="$cpprog -p";;
+
-s) stripcmd=$stripprog;;
+ -S) backupsuffix="$2"
+ shift;;
+
-t)
is_target_a_directory=always
dst_arg=$2
@@ -255,6 +275,10 @@
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
+ # Don't chown directories that already exist.
+ if test $dstdir_status = 0; then
+ chowncmd=""
+ fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
@@ -301,22 +325,6 @@
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
- # Create intermediate dirs using mode 755 as modified by the umask.
- # This is like FreeBSD 'install' as of 1997-10-28.
- umask=`umask`
- case $stripcmd.$umask in
- # Optimize common cases.
- *[2367][2367]) mkdir_umask=$umask;;
- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
- *[0-7])
- mkdir_umask=`expr $umask + 22 \
- - $umask % 100 % 40 + $umask % 20 \
- - $umask % 10 % 4 + $umask % 2
- `;;
- *) mkdir_umask=$umask,go-w;;
- esac
-
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
@@ -326,52 +334,49 @@
fi
posix_mkdir=false
- case $umask in
- *[123567][0-7][0-7])
- # POSIX mkdir -p sets u+wx bits regardless of umask, which
- # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
- ;;
- *)
- # Note that $RANDOM variable is not portable (e.g. dash); Use it
- # here however when possible just to lower collision chance.
- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
-
- trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
-
- # Because "mkdir -p" follows existing symlinks and we likely work
- # directly in world-writeable /tmp, make sure that the '$tmpdir'
- # directory is successfully created first before we actually test
- # 'mkdir -p' feature.
- if (umask $mkdir_umask &&
- $mkdirprog $mkdir_mode "$tmpdir" &&
- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
- then
- if test -z "$dir_arg" || {
- # Check for POSIX incompatibilities with -m.
- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
- # other-writable bit of parent directory when it shouldn't.
- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
- test_tmpdir="$tmpdir/a"
- ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
- case $ls_ld_tmpdir in
- d????-?r-*) different_mode=700;;
- d????-?--*) different_mode=755;;
- *) false;;
- esac &&
- $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
- ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
- }
- }
- then posix_mkdir=:
- fi
- rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
- else
- # Remove any dirs left behind by ancient mkdir implementations.
- rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
- fi
- trap '' 0;;
- esac;;
+ # The $RANDOM variable is not portable (e.g., dash). Use it
+ # here however when possible just to lower collision chance.
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+
+ trap '
+ ret=$?
+ rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
+ exit $ret
+ ' 0
+
+ # Because "mkdir -p" follows existing symlinks and we likely work
+ # directly in world-writeable /tmp, make sure that the '$tmpdir'
+ # directory is successfully created first before we actually test
+ # 'mkdir -p'.
+ if (umask $mkdir_umask &&
+ $mkdirprog $mkdir_mode "$tmpdir" &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ test_tmpdir="$tmpdir/a"
+ ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
+ fi
+ trap '' 0;;
esac
if
@@ -382,7 +387,7 @@
then :
else
- # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
@@ -411,7 +416,7 @@
prefixes=
else
if $posix_mkdir; then
- (umask=$mkdir_umask &&
+ (umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
@@ -451,7 +456,18 @@
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
- (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+ (umask $cp_umask &&
+ { test -z "$stripcmd" || {
+ # Create $dsttmp read-write so that cp doesn't create it read-only,
+ # which would cause strip to fail.
+ if test -z "$doit"; then
+ : >"$dsttmp" # No need to fork-exec 'touch'.
+ else
+ $doit touch "$dsttmp"
+ fi
+ }
+ } &&
+ $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
@@ -477,6 +493,13 @@
then
rm -f "$dsttmp"
else
+ # If $backupsuffix is set, and the file being installed
+ # already exists, attempt a backup. Don't worry if it fails,
+ # e.g., if mv doesn't support -f.
+ if test -n "$backupsuffix" && test -f "$dst"; then
+ $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
+ fi
+
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
@@ -491,9 +514,9 @@
# file should still install successfully.
{
test ! -f "$dst" ||
- $doit $rmcmd -f "$dst" 2>/dev/null ||
+ $doit $rmcmd "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
- { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
diff -Nru libp11-0.4.11/ltmain.sh libp11-0.4.12/ltmain.sh
--- libp11-0.4.11/ltmain.sh 2018-10-02 20:46:56.000000000 +0200
+++ libp11-0.4.12/ltmain.sh 2022-03-15 18:14:13.000000000 +0100
@@ -1,12 +1,12 @@
#! /bin/sh
## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
-## by inline-source v2018-07-24.06
+## by inline-source v2014-01-03.01
-# libtool (GNU libtool) 2.4.6.42-b88ce
+# libtool (GNU libtool) 2.4.6
# Provide generalized library-building support services.
# Written by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2015 Free Software Foundation, Inc.
# This is free software; see the source for copying conditions. There is NO
# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@@ -31,8 +31,8 @@
PROGRAM=libtool
PACKAGE=libtool
-VERSION=2.4.6.42-b88ce
-package_revision=2.4.6.42
+VERSION="2.4.6 Debian-2.4.6-15"
+package_revision=2.4.6
## ------ ##
@@ -64,25 +64,34 @@
# libraries, which are installed to $pkgauxdir.
# Set a version string for this script.
-scriptversion=2018-07-24.06; # UTC
+scriptversion=2015-01-20.17; # UTC
# General shell script boiler plate, and helper functions.
# Written by Gary V. Vaughan, 2004
-# This is free software. There is NO warranty; not even for
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#
-# Copyright (C) 2004-2018 Bootstrap Authors
-#
-# This file is dual licensed under the terms of the MIT license
-# <https://opensource.org/license/MIT>, and GPL version 3 or later
-# <http://www.gnu.org/licenses/gpl-2.0.html>. You must apply one of
-# these licenses when using or redistributing this software or any of
-# the files within it. See the URLs above, or the file `LICENSE`
-# included in the Bootstrap distribution for the full license texts.
+# Copyright (C) 2004-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# 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.
+
+# As a special exception to the GNU General Public License, if you distribute
+# this file as part of a program or library that is built using GNU Libtool,
+# you may include this file under the same distribution terms that you use
+# for the rest of that program.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNES 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 <http://www.gnu.org/licenses/>.
-# Please report bugs or propose patches to:
-# <https://github.com/gnulib-modules/bootstrap/issues>
+# Please report bugs or propose patches to gary at gnu.org.
## ------ ##
@@ -131,6 +140,9 @@
fi"
done
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
# Make sure IFS has a sensible default
sp=' '
nl='
@@ -147,26 +159,6 @@
fi
-# func_unset VAR
-# --------------
-# Portably unset VAR.
-# In some shells, an 'unset VAR' statement leaves a non-zero return
-# status if VAR is already unset, which might be problematic if the
-# statement is used at the end of a function (thus poisoning its return
-# value) or when 'set -e' is active (causing even a spurious abort of
-# the script in this case).
-func_unset ()
-{
- { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; }
-}
-
-
-# Make sure CDPATH doesn't cause `cd` commands to output the target dir.
-func_unset CDPATH
-
-# Make sure ${,E,F}GREP behave sanely.
-func_unset GREP_OPTIONS
-
## ------------------------- ##
## Locate command utilities. ##
@@ -267,7 +259,7 @@
rm -f conftest.in conftest.tmp conftest.nl conftest.out
}
- func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin"
+ func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
rm -f conftest.sed
SED=$func_path_progs_result
}
@@ -303,7 +295,7 @@
rm -f conftest.in conftest.tmp conftest.nl conftest.out
}
- func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin"
+ func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
GREP=$func_path_progs_result
}
@@ -395,7 +387,7 @@
# putting '$debug_cmd' at the start of all your functions, you can get
# bash to show function call trace with:
#
-# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+# debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
debug_cmd=${debug_cmd-":"}
exit_cmd=:
@@ -588,16 +580,16 @@
{
$debug_cmd
- func_quote_arg pretty "$2"
- eval "$1+=\\ \$func_quote_arg_result"
+ func_quote_for_eval "$2"
+ eval "$1+=\\ \$func_quote_for_eval_result"
}'
else
func_append_quoted ()
{
$debug_cmd
- func_quote_arg pretty "$2"
- eval "$1=\$$1\\ \$func_quote_arg_result"
+ func_quote_for_eval "$2"
+ eval "$1=\$$1\\ \$func_quote_for_eval_result"
}
fi
@@ -1099,199 +1091,85 @@
}
-# func_quote_portable EVAL ARG
-# ----------------------------
-# Internal function to portably implement func_quote_arg. Note that we still
-# keep attention to performance here so we as much as possible try to avoid
-# calling sed binary (so far O(N) complexity as long as func_append is O(1)).
-func_quote_portable ()
+# func_quote_for_eval ARG...
+# --------------------------
+# Aesthetically quote ARGs to be evaled later.
+# This function returns two values:
+# i) func_quote_for_eval_result
+# double-quoted, suitable for a subsequent eval
+# ii) func_quote_for_eval_unquoted_result
+# has all characters that are still active within double
+# quotes backslashified.
+func_quote_for_eval ()
{
$debug_cmd
- func_quote_portable_result=$2
-
- # one-time-loop (easy break)
- while true
- do
- if $1; then
- func_quote_portable_result=`$ECHO "$2" | $SED \
- -e "$sed_double_quote_subst" -e "$sed_double_backslash"`
- break
- fi
-
- # Quote for eval.
- case $func_quote_portable_result in
+ func_quote_for_eval_unquoted_result=
+ func_quote_for_eval_result=
+ while test 0 -lt $#; do
+ case $1 in
*[\\\`\"\$]*)
- case $func_quote_portable_result in
- *[\[\*\?]*)
- func_quote_portable_result=`$ECHO "$func_quote_portable_result" \
- | $SED "$sed_quote_subst"`
- break
- ;;
- esac
+ _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
+ *)
+ _G_unquoted_arg=$1 ;;
+ esac
+ if test -n "$func_quote_for_eval_unquoted_result"; then
+ func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
+ else
+ func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
+ fi
- func_quote_portable_old_IFS=$IFS
- for _G_char in '\' '`' '"' '$'
- do
- # STATE($1) PREV($2) SEPARATOR($3)
- set start "" ""
- func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy
- IFS=$_G_char
- for _G_part in $func_quote_portable_result
- do
- case $1 in
- quote)
- func_append func_quote_portable_result "$3$2"
- set quote "$_G_part" "\\$_G_char"
- ;;
- start)
- set first "" ""
- func_quote_portable_result=
- ;;
- first)
- set quote "$_G_part" ""
- ;;
- esac
- done
- done
- IFS=$func_quote_portable_old_IFS
+ case $_G_unquoted_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and variable expansion
+ # for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ _G_quoted_arg=\"$_G_unquoted_arg\"
;;
- *) ;;
+ *)
+ _G_quoted_arg=$_G_unquoted_arg
+ ;;
esac
- break
- done
- func_quote_portable_unquoted_result=$func_quote_portable_result
- case $func_quote_portable_result in
- # double-quote args containing shell metacharacters to delay
- # word splitting, command substitution and variable expansion
- # for a subsequent eval.
- # many bourne shells cannot handle close brackets correctly
- # in scan sets, so we specify it separately.
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- func_quote_portable_result=\"$func_quote_portable_result\"
- ;;
- esac
+ if test -n "$func_quote_for_eval_result"; then
+ func_append func_quote_for_eval_result " $_G_quoted_arg"
+ else
+ func_append func_quote_for_eval_result "$_G_quoted_arg"
+ fi
+ shift
+ done
}
-# func_quotefast_eval ARG
-# -----------------------
-# Quote one ARG (internal). This is equivalent to 'func_quote_arg eval ARG',
-# but optimized for speed. Result is stored in $func_quotefast_eval.
-if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then
- printf -v _GL_test_printf_tilde %q '~'
- if test '\~' = "$_GL_test_printf_tilde"; then
- func_quotefast_eval ()
- {
- printf -v func_quotefast_eval_result %q "$1"
- }
- else
- # Broken older Bash implementations. Make those faster too if possible.
- func_quotefast_eval ()
- {
- case $1 in
- '~'*)
- func_quote_portable false "$1"
- func_quotefast_eval_result=$func_quote_portable_result
- ;;
- *)
- printf -v func_quotefast_eval_result %q "$1"
- ;;
- esac
- }
- fi
-else
- func_quotefast_eval ()
- {
- func_quote_portable false "$1"
- func_quotefast_eval_result=$func_quote_portable_result
- }
-fi
-
+# func_quote_for_expand ARG
+# -------------------------
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ $debug_cmd
-# func_quote_arg MODEs ARG
-# ------------------------
-# Quote one ARG to be evaled later. MODEs argument may contain zero or more
-# specifiers listed below separated by ',' character. This function returns two
-# values:
-# i) func_quote_arg_result
-# double-quoted (when needed), suitable for a subsequent eval
-# ii) func_quote_arg_unquoted_result
-# has all characters that are still active within double
-# quotes backslashified. Available only if 'unquoted' is specified.
-#
-# Available modes:
-# ----------------
-# 'eval' (default)
-# - escape shell special characters
-# 'expand'
-# - the same as 'eval'; but do not quote variable references
-# 'pretty'
-# - request aesthetic output, i.e. '"a b"' instead of 'a\ b'. This might
-# be used later in func_quote to get output like: 'echo "a b"' instead
-# of 'echo a\ b'. This is slower than default on some shells.
-# 'unquoted'
-# - produce also $func_quote_arg_unquoted_result which does not contain
-# wrapping double-quotes.
-#
-# Examples for 'func_quote_arg pretty,unquoted string':
-#
-# string | *_result | *_unquoted_result
-# ------------+-----------------------+-------------------
-# " | \" | \"
-# a b | "a b" | a b
-# "a b" | "\"a b\"" | \"a b\"
-# * | "*" | *
-# z="${x-$y}" | "z=\"\${x-\$y}\"" | z=\"\${x-\$y}\"
-#
-# Examples for 'func_quote_arg pretty,unquoted,expand string':
-#
-# string | *_result | *_unquoted_result
-# --------------+---------------------+--------------------
-# z="${x-$y}" | "z=\"${x-$y}\"" | z=\"${x-$y}\"
-func_quote_arg ()
-{
- _G_quote_expand=false
- case ,$1, in
- *,expand,*)
- _G_quote_expand=:
- ;;
+ case $1 in
+ *[\\\`\"]*)
+ _G_arg=`$ECHO "$1" | $SED \
+ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ _G_arg=$1 ;;
esac
- case ,$1, in
- *,pretty,*|*,expand,*|*,unquoted,*)
- func_quote_portable $_G_quote_expand "$2"
- func_quote_arg_result=$func_quote_portable_result
- func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result
- ;;
- *)
- # Faster quote-for-eval for some shells.
- func_quotefast_eval "$2"
- func_quote_arg_result=$func_quotefast_eval_result
+ case $_G_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ _G_arg=\"$_G_arg\"
;;
esac
-}
-
-# func_quote MODEs ARGs...
-# ------------------------
-# Quote all ARGs to be evaled later and join them into single command. See
-# func_quote_arg's description for more info.
-func_quote ()
-{
- $debug_cmd
- _G_func_quote_mode=$1 ; shift
- func_quote_result=
- while test 0 -lt $#; do
- func_quote_arg "$_G_func_quote_mode" "$1"
- if test -n "$func_quote_result"; then
- func_append func_quote_result " $func_quote_arg_result"
- else
- func_append func_quote_result "$func_quote_arg_result"
- fi
- shift
- done
+ func_quote_for_expand_result=$_G_arg
}
@@ -1337,8 +1215,8 @@
_G_cmd=$1
_G_fail_exp=${2-':'}
- func_quote_arg pretty,expand "$_G_cmd"
- eval "func_notquiet $func_quote_arg_result"
+ func_quote_for_expand "$_G_cmd"
+ eval "func_notquiet $func_quote_for_expand_result"
$opt_dry_run || {
eval "$_G_cmd"
@@ -1363,8 +1241,8 @@
_G_fail_exp=${2-':'}
$opt_quiet || {
- func_quote_arg expand,pretty "$_G_cmd"
- eval "func_echo $func_quote_arg_result"
+ func_quote_for_expand "$_G_cmd"
+ eval "func_echo $func_quote_for_expand_result"
}
$opt_dry_run || {
@@ -1491,26 +1369,30 @@
# End:
#! /bin/sh
+# Set a version string for this script.
+scriptversion=2015-10-07.11; # UTC
+
# A portable, pluggable option parser for Bourne shell.
# Written by Gary V. Vaughan, 2010
-# This is free software. There is NO warranty; not even for
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#
-# Copyright (C) 2010-2018 Bootstrap Authors
-#
-# This file is dual licensed under the terms of the MIT license
-# <https://opensource.org/license/MIT>, and GPL version 3 or later
-# <http://www.gnu.org/licenses/gpl-2.0.html>. You must apply one of
-# these licenses when using or redistributing this software or any of
-# the files within it. See the URLs above, or the file `LICENSE`
-# included in the Bootstrap distribution for the full license texts.
+# Copyright (C) 2010-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# 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.
-# Please report bugs or propose patches to:
-# <https://github.com/gnulib-modules/bootstrap/issues>
+# 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.
-# Set a version string for this script.
-scriptversion=2018-07-24.06; # UTC
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary at gnu.org.
## ------ ##
@@ -1533,7 +1415,7 @@
#
# In order for the '--version' option to work, you will need to have a
# suitably formatted comment like the one at the top of this file
-# starting with '# Written by ' and ending with '# Copyright'.
+# starting with '# Written by ' and ending with '# warranty; '.
#
# For '-h' and '--help' to work, you will also need a one line
# description of your script's purpose in a comment directly above the
@@ -1545,7 +1427,7 @@
# to display verbose messages only when your user has specified
# '--verbose'.
#
-# After sourcing this file, you can plug in processing for additional
+# After sourcing this file, you can plug processing for additional
# options by amending the variables from the 'Configuration' section
# below, and following the instructions in the 'Option parsing'
# section further down.
@@ -1594,8 +1476,8 @@
## ------------------------- ##
# This section contains functions for adding, removing, and running hooks
-# in the main code. A hook is just a list of function names that can be
-# run in order later on.
+# to the main code. A hook is just a named list of of function, that can
+# be run in order later on.
# func_hookable FUNC_NAME
# -----------------------
@@ -1628,8 +1510,7 @@
# func_remove_hook FUNC_NAME HOOK_FUNC
# ------------------------------------
-# Remove HOOK_FUNC from the list of hook functions to be called by
-# FUNC_NAME.
+# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
func_remove_hook ()
{
$debug_cmd
@@ -1638,28 +1519,10 @@
}
-# func_propagate_result FUNC_NAME_A FUNC_NAME_B
-# ---------------------------------------------
-# If the *_result variable of FUNC_NAME_A _is set_, assign its value to
-# *_result variable of FUNC_NAME_B.
-func_propagate_result ()
-{
- $debug_cmd
-
- func_propagate_result_result=:
- if eval "test \"\${${1}_result+set}\" = set"
- then
- eval "${2}_result=\$${1}_result"
- else
- func_propagate_result_result=false
- fi
-}
-
-
# func_run_hooks FUNC_NAME [ARG]...
# ---------------------------------
# Run all hook functions registered to FUNC_NAME.
-# It's assumed that the list of hook functions contains nothing more
+# It is assumed that the list of hook functions contains nothing more
# than a whitespace-delimited list of legal shell function names, and
# no effort is wasted trying to catch shell meta-characters or preserve
# whitespace.
@@ -1667,21 +1530,26 @@
{
$debug_cmd
+ _G_rc_run_hooks=false
+
case " $hookable_fns " in
*" $1 "*) ;;
- *) func_fatal_error "'$1' does not support hook functions." ;;
+ *) func_fatal_error "'$1' does not support hook funcions.n" ;;
esac
eval _G_hook_fns=\$$1_hooks; shift
for _G_hook in $_G_hook_fns; do
- func_unset "${_G_hook}_result"
- eval $_G_hook '${1+"$@"}'
- func_propagate_result $_G_hook func_run_hooks
- if $func_propagate_result_result; then
- eval set dummy "$func_run_hooks_result"; shift
+ if eval $_G_hook '"$@"'; then
+ # store returned options list back into positional
+ # parameters for next 'cmd' execution.
+ eval _G_hook_result=\$${_G_hook}_result
+ eval set dummy "$_G_hook_result"; shift
+ _G_rc_run_hooks=:
fi
done
+
+ $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result
}
@@ -1691,16 +1559,14 @@
## --------------- ##
# In order to add your own option parsing hooks, you must accept the
-# full positional parameter list from your hook function. You may remove
-# or edit any options that you action, and then pass back the remaining
-# unprocessed options in '<hooked_function_name>_result', escaped
-# suitably for 'eval'.
-#
-# The '<hooked_function_name>_result' variable is automatically unset
-# before your hook gets called; for best performance, only set the
-# *_result variable when necessary (i.e. don't call the 'func_quote'
-# function unnecessarily because it can be an expensive operation on some
-# machines).
+# full positional parameter list in your hook function, you may remove/edit
+# any options that you action, and then pass back the remaining unprocessed
+# options in '<hooked_function_name>_result', escaped suitably for
+# 'eval'. In this case you also must return $EXIT_SUCCESS to let the
+# hook's caller know that it should pay attention to
+# '<hooked_function_name>_result'. Returning $EXIT_FAILURE signalizes that
+# arguments are left untouched by the hook and therefore caller will ignore the
+# result variable.
#
# Like this:
#
@@ -1712,8 +1578,11 @@
# usage_message=$usage_message'
# -s, --silent don'\''t print informational messages
# '
-# # No change in '$@' (ignored completely by this hook). Leave
-# # my_options_prep_result variable intact.
+# # No change in '$@' (ignored completely by this hook). There is
+# # no need to do the equivalent (but slower) action:
+# # func_quote_for_eval ${1+"$@"}
+# # my_options_prep_result=$func_quote_for_eval_result
+# false
# }
# func_add_hook func_options_prep my_options_prep
#
@@ -1724,7 +1593,7 @@
#
# args_changed=false
#
-# # Note that, for efficiency, we parse as many options as we can
+# # Note that for efficiency, we parse as many options as we can
# # recognise in a loop before passing the remainder back to the
# # caller on the first unrecognised argument we encounter.
# while test $# -gt 0; do
@@ -1741,17 +1610,18 @@
# args_changed=:
# ;;
# *) # Make sure the first unrecognised option "$_G_opt"
-# # is added back to "$@" in case we need it later,
-# # if $args_changed was set to 'true'.
+# # is added back to "$@", we could need that later
+# # if $args_changed is true.
# set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
# esac
# done
#
-# # Only call 'func_quote' here if we processed at least one argument.
# if $args_changed; then
-# func_quote eval ${1+"$@"}
-# my_silent_option_result=$func_quote_result
+# func_quote_for_eval ${1+"$@"}
+# my_silent_option_result=$func_quote_for_eval_result
# fi
+#
+# $args_changed
# }
# func_add_hook func_parse_options my_silent_option
#
@@ -1762,6 +1632,8 @@
#
# $opt_silent && $opt_verbose && func_fatal_help "\
# '--silent' and '--verbose' options are mutually exclusive."
+#
+# false
# }
# func_add_hook func_validate_options my_option_validation
#
@@ -1777,8 +1649,13 @@
{
$debug_cmd
- func_run_hooks func_options ${1+"$@"}
- func_propagate_result func_run_hooks func_options_finish
+ _G_func_options_finish_exit=false
+ if func_run_hooks func_options ${1+"$@"}; then
+ func_options_finish_result=$func_run_hooks_result
+ _G_func_options_finish_exit=:
+ fi
+
+ $_G_func_options_finish_exit
}
@@ -1791,27 +1668,28 @@
{
$debug_cmd
- _G_options_quoted=false
+ _G_rc_options=false
for my_func in options_prep parse_options validate_options options_finish
do
- func_unset func_${my_func}_result
- func_unset func_run_hooks_result
- eval func_$my_func '${1+"$@"}'
- func_propagate_result func_$my_func func_options
- if $func_propagate_result_result; then
- eval set dummy "$func_options_result"; shift
- _G_options_quoted=:
+ if eval func_$my_func '${1+"$@"}'; then
+ eval _G_res_var='$'"func_${my_func}_result"
+ eval set dummy "$_G_res_var" ; shift
+ _G_rc_options=:
fi
done
- $_G_options_quoted || {
- # As we (func_options) are top-level options-parser function and
- # nobody quoted "$@" for us yet, we need to do it explicitly for
- # caller.
- func_quote eval ${1+"$@"}
- func_options_result=$func_quote_result
- }
+ # Save modified positional parameters for caller. As a top-level
+ # options-parser function we always need to set the 'func_options_result'
+ # variable (regardless the $_G_rc_options value).
+ if $_G_rc_options; then
+ func_options_result=$_G_res_var
+ else
+ func_quote_for_eval ${1+"$@"}
+ func_options_result=$func_quote_for_eval_result
+ fi
+
+ $_G_rc_options
}
@@ -1821,7 +1699,8 @@
# Note that when calling hook functions, we pass through the list of
# positional parameters. If a hook function modifies that list, and
# needs to propagate that back to rest of this script, then the complete
-# modified list must be put in 'func_run_hooks_result' before returning.
+# modified list must be put in 'func_run_hooks_result' before
+# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned).
func_hookable func_options_prep
func_options_prep ()
{
@@ -1831,8 +1710,14 @@
opt_verbose=false
opt_warning_types=
- func_run_hooks func_options_prep ${1+"$@"}
- func_propagate_result func_run_hooks func_options_prep
+ _G_rc_options_prep=false
+ if func_run_hooks func_options_prep ${1+"$@"}; then
+ _G_rc_options_prep=:
+ # save modified positional parameters for caller
+ func_options_prep_result=$func_run_hooks_result
+ fi
+
+ $_G_rc_options_prep
}
@@ -1844,32 +1729,27 @@
{
$debug_cmd
- _G_parse_options_requote=false
+ func_parse_options_result=
+
+ _G_rc_parse_options=false
# this just eases exit handling
while test $# -gt 0; do
# Defer to hook functions for initial option parsing, so they
# get priority in the event of reusing an option name.
- func_run_hooks func_parse_options ${1+"$@"}
- func_propagate_result func_run_hooks func_parse_options
- if $func_propagate_result_result; then
- eval set dummy "$func_parse_options_result"; shift
- # Even though we may have changed "$@", we passed the "$@" array
- # down into the hook and it quoted it for us (because we are in
- # this if-branch). No need to quote it again.
- _G_parse_options_requote=false
+ if func_run_hooks func_parse_options ${1+"$@"}; then
+ eval set dummy "$func_run_hooks_result"; shift
+ _G_rc_parse_options=:
fi
# Break out of the loop if we already parsed every option.
test $# -gt 0 || break
- # We expect that one of the options parsed in this function matches
- # and thus we remove _G_opt from "$@" and need to re-quote.
_G_match_parse_options=:
_G_opt=$1
shift
case $_G_opt in
--debug|-x) debug_cmd='set -x'
- func_echo "enabling shell trace mode" >&2
+ func_echo "enabling shell trace mode"
$debug_cmd
;;
@@ -1880,7 +1760,7 @@
--warnings|--warning|-W)
if test $# = 0 && func_missing_arg $_G_opt; then
- _G_parse_options_requote=:
+ _G_rc_parse_options=:
break
fi
case " $warning_categories $1" in
@@ -1935,7 +1815,7 @@
shift
;;
- --) _G_parse_options_requote=: ; break ;;
+ --) _G_rc_parse_options=: ; break ;;
-*) func_fatal_help "unrecognised option: '$_G_opt'" ;;
*) set dummy "$_G_opt" ${1+"$@"}; shift
_G_match_parse_options=false
@@ -1943,16 +1823,17 @@
;;
esac
- if $_G_match_parse_options; then
- _G_parse_options_requote=:
- fi
+ $_G_match_parse_options && _G_rc_parse_options=:
done
- if $_G_parse_options_requote; then
+
+ if $_G_rc_parse_options; then
# save modified positional parameters for caller
- func_quote eval ${1+"$@"}
- func_parse_options_result=$func_quote_result
+ func_quote_for_eval ${1+"$@"}
+ func_parse_options_result=$func_quote_for_eval_result
fi
+
+ $_G_rc_parse_options
}
@@ -1965,14 +1846,21 @@
{
$debug_cmd
+ _G_rc_validate_options=false
+
# Display all warnings if -W was not given.
test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
- func_run_hooks func_validate_options ${1+"$@"}
- func_propagate_result func_run_hooks func_validate_options
+ if func_run_hooks func_validate_options ${1+"$@"}; then
+ # save modified positional parameters for caller
+ func_validate_options_result=$func_run_hooks_result
+ _G_rc_validate_options=:
+ fi
# Bail if the options were screwed!
$exit_cmd $EXIT_FAILURE
+
+ $_G_rc_validate_options
}
@@ -2028,8 +1916,8 @@
# func_split_equals STRING
# ------------------------
-# Set func_split_equals_lhs and func_split_equals_rhs shell variables
-# after splitting STRING at the '=' sign.
+# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
+# splitting STRING at the '=' sign.
test -z "$_G_HAVE_XSI_OPS" \
&& (eval 'x=a/b/c;
test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
@@ -2044,9 +1932,8 @@
func_split_equals_lhs=${1%%=*}
func_split_equals_rhs=${1#*=}
- if test "x$func_split_equals_lhs" = "x$1"; then
- func_split_equals_rhs=
- fi
+ test "x$func_split_equals_lhs" = "x$1" \
+ && func_split_equals_rhs=
}'
else
# ...otherwise fall back to using expr, which is often a shell builtin.
@@ -2124,44 +2011,31 @@
# func_version
# ------------
# Echo version message to standard output and exit.
-# The version message is extracted from the calling file's header
-# comments, with leading '# ' stripped:
-# 1. First display the progname and version
-# 2. Followed by the header comment line matching /^# Written by /
-# 3. Then a blank line followed by the first following line matching
-# /^# Copyright /
-# 4. Immediately followed by any lines between the previous matches,
-# except lines preceding the intervening completely blank line.
-# For example, see the header comments of this file.
func_version ()
{
$debug_cmd
printf '%s\n' "$progname $scriptversion"
$SED -n '
- /^# Written by /!b
- s|^# ||; p; n
-
- :fwd2blnk
- /./ {
- n
- b fwd2blnk
+ /(C)/!b go
+ :more
+ /\./!{
+ N
+ s|\n# | |
+ b more
}
- p; n
-
- :holdwrnt
- s|^# ||
- s|^# *$||
- /^Copyright /!{
- /./H
- n
- b holdwrnt
+ :go
+ /^# Written by /,/# warranty; / {
+ s|^# ||
+ s|^# *$||
+ s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
+ p
}
-
- s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
- G
- s|\(\n\)\n*|\1|g
- p; q' < "$progpath"
+ /^# Written by / {
+ s|^# ||
+ p
+ }
+ /^warranty; /q' < "$progpath"
exit $?
}
@@ -2171,12 +2045,12 @@
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
# time-stamp-time-zone: "UTC"
# End:
# Set a version string.
-scriptversion='(GNU libtool) 2.4.6.42-b88ce'
+scriptversion='(GNU libtool) 2.4.6'
# func_echo ARG...
@@ -2267,7 +2141,7 @@
compiler: $LTCC
compiler flags: $LTCFLAGS
linker: $LD (gnu? $with_gnu_ld)
- version: $progname (GNU libtool) 2.4.6.42-b88ce
+ version: $progname $scriptversion Debian-2.4.6-15
automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q`
@@ -2323,7 +2197,7 @@
# a configuration failure hint, and exit.
func_fatal_configuration ()
{
- func_fatal_error ${1+"$@"} \
+ func__fatal_error ${1+"$@"} \
"See the $PACKAGE documentation for more information." \
"Fatal configuration error."
}
@@ -2501,9 +2375,11 @@
if $_G_rc_lt_options_prep; then
# Pass back the list of options.
- func_quote eval ${1+"$@"}
- libtool_options_prep_result=$func_quote_result
+ func_quote_for_eval ${1+"$@"}
+ libtool_options_prep_result=$func_quote_for_eval_result
fi
+
+ $_G_rc_lt_options_prep
}
func_add_hook func_options_prep libtool_options_prep
@@ -2606,9 +2482,11 @@
if $_G_rc_lt_parse_options; then
# save modified positional parameters for caller
- func_quote eval ${1+"$@"}
- libtool_parse_options_result=$func_quote_result
+ func_quote_for_eval ${1+"$@"}
+ libtool_parse_options_result=$func_quote_for_eval_result
fi
+
+ $_G_rc_lt_parse_options
}
func_add_hook func_parse_options libtool_parse_options
@@ -2665,8 +2543,8 @@
}
# Pass back the unparsed argument list
- func_quote eval ${1+"$@"}
- libtool_validate_options_result=$func_quote_result
+ func_quote_for_eval ${1+"$@"}
+ libtool_validate_options_result=$func_quote_for_eval_result
}
func_add_hook func_validate_options libtool_validate_options
@@ -3632,8 +3510,8 @@
esac
done
- func_quote_arg pretty "$libobj"
- test "X$libobj" != "X$func_quote_arg_result" \
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
&& $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
&& func_warning "libobj name '$libobj' may not contain shell special characters."
func_dirname_and_basename "$obj" "/" ""
@@ -3706,8 +3584,8 @@
func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
srcfile=$func_to_tool_file_result
- func_quote_arg pretty "$srcfile"
- qsrcfile=$func_quote_arg_result
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
# Only build a PIC object if we are building libtool libraries.
if test yes = "$build_libtool_libs"; then
@@ -4310,8 +4188,8 @@
case $nonopt in *shtool*) :;; *) false;; esac
then
# Aesthetically quote it.
- func_quote_arg pretty "$nonopt"
- install_prog="$func_quote_arg_result "
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
arg=$1
shift
else
@@ -4321,8 +4199,8 @@
# The real first argument should be the name of the installation program.
# Aesthetically quote it.
- func_quote_arg pretty "$arg"
- func_append install_prog "$func_quote_arg_result"
+ func_quote_for_eval "$arg"
+ func_append install_prog "$func_quote_for_eval_result"
install_shared_prog=$install_prog
case " $install_prog " in
*[\\\ /]cp\ *) install_cp=: ;;
@@ -4379,12 +4257,12 @@
esac
# Aesthetically quote the argument.
- func_quote_arg pretty "$arg"
- func_append install_prog " $func_quote_arg_result"
+ func_quote_for_eval "$arg"
+ func_append install_prog " $func_quote_for_eval_result"
if test -n "$arg2"; then
- func_quote_arg pretty "$arg2"
+ func_quote_for_eval "$arg2"
fi
- func_append install_shared_prog " $func_quote_arg_result"
+ func_append install_shared_prog " $func_quote_for_eval_result"
done
test -z "$install_prog" && \
@@ -4395,8 +4273,8 @@
if test -n "$install_override_mode" && $no_mode; then
if $install_cp; then :; else
- func_quote_arg pretty "$install_override_mode"
- func_append install_shared_prog " -m $func_quote_arg_result"
+ func_quote_for_eval "$install_override_mode"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
fi
fi
@@ -4692,8 +4570,8 @@
relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
$opt_quiet || {
- func_quote_arg expand,pretty "$relink_command"
- eval "func_echo $func_quote_arg_result"
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
}
if eval "$relink_command"; then :
else
@@ -5472,8 +5350,7 @@
if test \"\$libtool_execute_magic\" != \"$magic\"; then
file=\"\$0\""
- func_quote_arg pretty "$ECHO"
- qECHO=$func_quote_arg_result
+ qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
$ECHO "\
# A function that is used when there is no print builtin or printf.
@@ -5483,7 +5360,7 @@
\$1
_LTECHO_EOF'
}
- ECHO=$qECHO
+ ECHO=\"$qECHO\"
fi
# Very basic option parsing. These options are (a) specific to
@@ -6826,9 +6703,9 @@
while test "$#" -gt 0; do
arg=$1
shift
- func_quote_arg pretty,unquoted "$arg"
- qarg=$func_quote_arg_unquoted_result
- func_append libtool_args " $func_quote_arg_result"
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
# If the previous option needs an argument, assign it.
if test -n "$prev"; then
@@ -7426,9 +7303,9 @@
save_ifs=$IFS; IFS=,
for flag in $args; do
IFS=$save_ifs
- func_quote_arg pretty "$flag"
- func_append arg " $func_quote_arg_result"
- func_append compiler_flags " $func_quote_arg_result"
+ func_quote_for_eval "$flag"
+ func_append arg " $func_quote_for_eval_result"
+ func_append compiler_flags " $func_quote_for_eval_result"
done
IFS=$save_ifs
func_stripname ' ' '' "$arg"
@@ -7442,10 +7319,10 @@
save_ifs=$IFS; IFS=,
for flag in $args; do
IFS=$save_ifs
- func_quote_arg pretty "$flag"
- func_append arg " $wl$func_quote_arg_result"
- func_append compiler_flags " $wl$func_quote_arg_result"
- func_append linker_flags " $func_quote_arg_result"
+ func_quote_for_eval "$flag"
+ func_append arg " $wl$func_quote_for_eval_result"
+ func_append compiler_flags " $wl$func_quote_for_eval_result"
+ func_append linker_flags " $func_quote_for_eval_result"
done
IFS=$save_ifs
func_stripname ' ' '' "$arg"
@@ -7469,8 +7346,8 @@
# -msg_* for osf cc
-msg_*)
- func_quote_arg pretty "$arg"
- arg=$func_quote_arg_result
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
;;
# Flags to be passed through unchanged, with rationale:
@@ -7491,12 +7368,14 @@
# -stdlib=* select c++ std lib with clang
# -fsanitize=* Clang/GCC memory and address sanitizer
# -fuse-ld=* Linker select flags for GCC
+ # -static-* direct GCC to link specific libraries statically
+ # -fcilkplus Cilk Plus language extension features for C/C++
-64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
-t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
-O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
- -specs=*|-fsanitize=*|-fuse-ld=*)
- func_quote_arg pretty "$arg"
- arg=$func_quote_arg_result
+ -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
func_append compile_command " $arg"
func_append finalize_command " $arg"
func_append compiler_flags " $arg"
@@ -7517,15 +7396,15 @@
continue
else
# Otherwise treat like 'Some other compiler flag' below
- func_quote_arg pretty "$arg"
- arg=$func_quote_arg_result
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
fi
;;
# Some other compiler flag.
-* | +*)
- func_quote_arg pretty "$arg"
- arg=$func_quote_arg_result
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
;;
*.$objext)
@@ -7645,8 +7524,8 @@
*)
# Unknown arguments in both finalize_command and compile_command need
# to be aesthetically quoted because they are evaled later.
- func_quote_arg pretty "$arg"
- arg=$func_quote_arg_result
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
;;
esac # arg
@@ -7787,7 +7666,10 @@
case $pass in
dlopen) libs=$dlfiles ;;
dlpreopen) libs=$dlprefiles ;;
- link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ link)
+ libs="$deplibs %DEPLIBS%"
+ test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+ ;;
esac
fi
if test lib,dlpreopen = "$linkmode,$pass"; then
@@ -8106,19 +7988,19 @@
# It is a libtool convenience library, so add in its objects.
func_append convenience " $ladir/$objdir/$old_library"
func_append old_convenience " $ladir/$objdir/$old_library"
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
elif test prog != "$linkmode" && test lib != "$linkmode"; then
func_fatal_error "'$lib' is not a convenience library"
fi
- tmp_libs=
- for deplib in $dependency_libs; do
- deplibs="$deplib $deplibs"
- if $opt_preserve_dup_deps; then
- case "$tmp_libs " in
- *" $deplib "*) func_append specialdeplibs " $deplib" ;;
- esac
- fi
- func_append tmp_libs " $deplib"
- done
continue
fi # $pass = conv
@@ -9042,6 +8924,9 @@
revision=$number_minor
lt_irix_increment=no
;;
+ *)
+ func_fatal_configuration "$modename: unknown library version type '$version_type'"
+ ;;
esac
;;
no)
@@ -10152,8 +10037,8 @@
for cmd in $concat_cmds; do
IFS=$save_ifs
$opt_quiet || {
- func_quote_arg expand,pretty "$cmd"
- eval "func_echo $func_quote_arg_result"
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
}
$opt_dry_run || eval "$cmd" || {
lt_exit=$?
@@ -10246,8 +10131,8 @@
eval cmd=\"$cmd\"
IFS=$save_ifs
$opt_quiet || {
- func_quote_arg expand,pretty "$cmd"
- eval "func_echo $func_quote_arg_result"
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
}
$opt_dry_run || eval "$cmd" || {
lt_exit=$?
@@ -10721,13 +10606,12 @@
elif eval var_value=\$$var; test -z "$var_value"; then
relink_command="$var=; export $var; $relink_command"
else
- func_quote_arg pretty "$var_value"
- relink_command="$var=$func_quote_arg_result; export $var; $relink_command"
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
fi
done
- func_quote eval cd "`pwd`"
- func_quote_arg pretty,unquoted "($func_quote_result; $relink_command)"
- relink_command=$func_quote_arg_unquoted_result
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
fi
# Only actually do things if not in dry run mode.
@@ -10967,15 +10851,13 @@
elif eval var_value=\$$var; test -z "$var_value"; then
relink_command="$var=; export $var; $relink_command"
else
- func_quote_arg pretty,unquoted "$var_value"
- relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command"
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
fi
done
# Quote the link command for shipping.
- func_quote eval cd "`pwd`"
- relink_command="($func_quote_result; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
- func_quote_arg pretty,unquoted "$relink_command"
- relink_command=$func_quote_arg_unquoted_result
+ relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
if test yes = "$hardcode_automatic"; then
relink_command=
fi
diff -Nru libp11-0.4.11/m4/ax_pthread.m4 libp11-0.4.12/m4/ax_pthread.m4
--- libp11-0.4.11/m4/ax_pthread.m4 1970-01-01 01:00:00.000000000 +0100
+++ libp11-0.4.12/m4/ax_pthread.m4 2021-10-30 14:20:08.000000000 +0200
@@ -0,0 +1,522 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+# This macro figures out how to build C programs using POSIX threads. It
+# sets the PTHREAD_LIBS output variable to the threads library and linker
+# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+# flags that are needed. (The user can also force certain compiler
+# flags/libs to be tested by setting these environment variables.)
+#
+# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is
+# needed for multi-threaded programs (defaults to the value of CC
+# respectively CXX otherwise). (This is necessary on e.g. AIX to use the
+# special cc_r/CC_r compiler alias.)
+#
+# NOTE: You are assumed to not only compile your program with these flags,
+# but also to link with them as well. For example, you might link with
+# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+# If you are only building threaded programs, you may wish to use these
+# variables in your default LIBS, CFLAGS, and CC:
+#
+# LIBS="$PTHREAD_LIBS $LIBS"
+# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
+# CC="$PTHREAD_CC"
+# CXX="$PTHREAD_CXX"
+#
+# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
+# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+# PTHREAD_CFLAGS.
+#
+# ACTION-IF-FOUND is a list of shell commands to run if a threads library
+# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+# is not found. If ACTION-IF-FOUND is not specified, the default action
+# will define HAVE_PTHREAD.
+#
+# Please let the authors know if this macro fails on any platform, or if
+# you have any other suggestions or comments. This macro was based on work
+# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+# Alejandro Forero Cuervo to the autoconf macro repository. We are also
+# grateful for the helpful feedback of numerous users.
+#
+# Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Steven G. Johnson <stevenj at alum.mit.edu>
+# Copyright (c) 2011 Daniel Richard G. <skunk at iSKUNK.ORG>
+# Copyright (c) 2019 Marc Stevens <marc.stevens at cwi.nl>
+#
+# 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/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 30
+
+AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
+AC_DEFUN([AX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_TARGET])
+AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AC_PROG_SED])
+AC_LANG_PUSH([C])
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on Tru64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
+ ax_pthread_save_CC="$CC"
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ ax_pthread_save_LIBS="$LIBS"
+ AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
+ AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"])
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
+ AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
+ AC_MSG_RESULT([$ax_pthread_ok])
+ if test "x$ax_pthread_ok" = "xno"; then
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+ fi
+ CC="$ax_pthread_save_CC"
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ LIBS="$ax_pthread_save_LIBS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items with a "," contain both
+# C compiler flags (before ",") and linker flags (after ","). Other items
+# starting with a "-" are C compiler flags, and remaining items are
+# library names, except for "none" which indicates that we try without
+# any flags at all, and "pthread-config" which is a program returning
+# the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important. Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+# other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
+# (Note: HP C rejects this with "bad form for `-t' option")
+# -pthreads: Solaris/gcc (Note: HP C also rejects)
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+# doesn't hurt to check since this sometimes defines pthreads and
+# -D_REENTRANT too), HP C (must be checked before -lpthread, which
+# is present but should not be used directly; and before -mthreads,
+# because the compiler interprets this as "-mt" + "-hreads")
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case $target_os in
+
+ freebsd*)
+
+ # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+ # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+
+ ax_pthread_flags="-kthread lthread $ax_pthread_flags"
+ ;;
+
+ hpux*)
+
+ # From the cc(1) man page: "[-mt] Sets various -D flags to enable
+ # multi-threading and also sets -lpthread."
+
+ ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
+ ;;
+
+ openedition*)
+
+ # IBM z/OS requires a feature-test macro to be defined in order to
+ # enable POSIX threads at all, so give the user a hint if this is
+ # not set. (We don't define these ourselves, as they can affect
+ # other portions of the system API in unpredictable ways.)
+
+ AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
+ [
+# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
+ AX_PTHREAD_ZOS_MISSING
+# endif
+ ],
+ [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
+ ;;
+
+ solaris*)
+
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (N.B.: The stubs are missing
+ # pthread_cleanup_push, or rather a function called by this macro,
+ # so we could check for that, but who knows whether they'll stub
+ # that too in a future libc.) So we'll check first for the
+ # standard Solaris way of linking pthreads (-mt -lpthread).
+
+ ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags"
+ ;;
+esac
+
+# Are we compiling with Clang?
+
+AC_CACHE_CHECK([whether $CC is Clang],
+ [ax_cv_PTHREAD_CLANG],
+ [ax_cv_PTHREAD_CLANG=no
+ # Note that Autoconf sets GCC=yes for Clang as well as GCC
+ if test "x$GCC" = "xyes"; then
+ AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
+ [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
+# if defined(__clang__) && defined(__llvm__)
+ AX_PTHREAD_CC_IS_CLANG
+# endif
+ ],
+ [ax_cv_PTHREAD_CLANG=yes])
+ fi
+ ])
+ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+
+
+# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
+
+# Note that for GCC and Clang -pthread generally implies -lpthread,
+# except when -nostdlib is passed.
+# This is problematic using libtool to build C++ shared libraries with pthread:
+# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
+# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333
+# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555
+# To solve this, first try -pthread together with -lpthread for GCC
+
+AS_IF([test "x$GCC" = "xyes"],
+ [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"])
+
+# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first
+
+AS_IF([test "x$ax_pthread_clang" = "xyes"],
+ [ax_pthread_flags="-pthread,-lpthread -pthread"])
+
+
+# The presence of a feature test macro requesting re-entrant function
+# definitions is, on some systems, a strong hint that pthreads support is
+# correctly enabled
+
+case $target_os in
+ darwin* | hpux* | linux* | osf* | solaris*)
+ ax_pthread_check_macro="_REENTRANT"
+ ;;
+
+ aix*)
+ ax_pthread_check_macro="_THREAD_SAFE"
+ ;;
+
+ *)
+ ax_pthread_check_macro="--"
+ ;;
+esac
+AS_IF([test "x$ax_pthread_check_macro" = "x--"],
+ [ax_pthread_check_cond=0],
+ [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
+
+
+if test "x$ax_pthread_ok" = "xno"; then
+for ax_pthread_try_flag in $ax_pthread_flags; do
+
+ case $ax_pthread_try_flag in
+ none)
+ AC_MSG_CHECKING([whether pthreads work without any flags])
+ ;;
+
+ *,*)
+ PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"`
+ PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"`
+ AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"])
+ ;;
+
+ -*)
+ AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
+ PTHREAD_CFLAGS="$ax_pthread_try_flag"
+ ;;
+
+ pthread-config)
+ AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
+ AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
+ PTHREAD_LIBS="-l$ax_pthread_try_flag"
+ ;;
+ esac
+
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ ax_pthread_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+# if $ax_pthread_check_cond
+# error "$ax_pthread_check_macro must be defined"
+# endif
+ static void *some_global = NULL;
+ static void routine(void *a)
+ {
+ /* To avoid any unused-parameter or
+ unused-but-set-parameter warning. */
+ some_global = a;
+ }
+ static void *start_routine(void *a) { return a; }],
+ [pthread_t th; pthread_attr_t attr;
+ pthread_create(&th, 0, start_routine, 0);
+ pthread_join(th, 0);
+ pthread_attr_init(&attr);
+ pthread_cleanup_push(routine, 0);
+ pthread_cleanup_pop(0) /* ; */])],
+ [ax_pthread_ok=yes],
+ [])
+
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ LIBS="$ax_pthread_save_LIBS"
+
+ AC_MSG_RESULT([$ax_pthread_ok])
+ AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
+
+
+# Clang needs special handling, because older versions handle the -pthread
+# option in a rather... idiosyncratic way
+
+if test "x$ax_pthread_clang" = "xyes"; then
+
+ # Clang takes -pthread; it has never supported any other flag
+
+ # (Note 1: This will need to be revisited if a system that Clang
+ # supports has POSIX threads in a separate library. This tends not
+ # to be the way of modern systems, but it's conceivable.)
+
+ # (Note 2: On some systems, notably Darwin, -pthread is not needed
+ # to get POSIX threads support; the API is always present and
+ # active. We could reasonably leave PTHREAD_CFLAGS empty. But
+ # -pthread does define _REENTRANT, and while the Darwin headers
+ # ignore this macro, third-party headers might not.)
+
+ # However, older versions of Clang make a point of warning the user
+ # that, in an invocation where only linking and no compilation is
+ # taking place, the -pthread option has no effect ("argument unused
+ # during compilation"). They expect -pthread to be passed in only
+ # when source code is being compiled.
+ #
+ # Problem is, this is at odds with the way Automake and most other
+ # C build frameworks function, which is that the same flags used in
+ # compilation (CFLAGS) are also used in linking. Many systems
+ # supported by AX_PTHREAD require exactly this for POSIX threads
+ # support, and in fact it is often not straightforward to specify a
+ # flag that is used only in the compilation phase and not in
+ # linking. Such a scenario is extremely rare in practice.
+ #
+ # Even though use of the -pthread flag in linking would only print
+ # a warning, this can be a nuisance for well-run software projects
+ # that build with -Werror. So if the active version of Clang has
+ # this misfeature, we search for an option to squash it.
+
+ AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
+ [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
+ [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
+ # Create an alternate version of $ac_link that compiles and
+ # links in two steps (.c -> .o, .o -> exe) instead of one
+ # (.c -> exe), because the warning occurs only in the second
+ # step
+ ax_pthread_save_ac_link="$ac_link"
+ ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
+ ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"`
+ ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
+ AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
+ CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
+ ac_link="$ax_pthread_save_ac_link"
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
+ [ac_link="$ax_pthread_2step_ac_link"
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
+ [break])
+ ])
+ done
+ ac_link="$ax_pthread_save_ac_link"
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
+ ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
+ ])
+
+ case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
+ no | unknown) ;;
+ *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
+ esac
+
+fi # $ax_pthread_clang = yes
+
+
+
+# Various other checks:
+if test "x$ax_pthread_ok" = "xyes"; then
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ ax_pthread_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+
+ # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+ AC_CACHE_CHECK([for joinable pthread attribute],
+ [ax_cv_PTHREAD_JOINABLE_ATTR],
+ [ax_cv_PTHREAD_JOINABLE_ATTR=unknown
+ for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+ [int attr = $ax_pthread_attr; return attr /* ; */])],
+ [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
+ [])
+ done
+ ])
+ AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
+ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
+ test "x$ax_pthread_joinable_attr_defined" != "xyes"],
+ [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
+ [$ax_cv_PTHREAD_JOINABLE_ATTR],
+ [Define to necessary symbol if this constant
+ uses a non-standard name on your system.])
+ ax_pthread_joinable_attr_defined=yes
+ ])
+
+ AC_CACHE_CHECK([whether more special flags are required for pthreads],
+ [ax_cv_PTHREAD_SPECIAL_FLAGS],
+ [ax_cv_PTHREAD_SPECIAL_FLAGS=no
+ case $target_os in
+ solaris*)
+ ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
+ ;;
+ esac
+ ])
+ AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
+ test "x$ax_pthread_special_flags_added" != "xyes"],
+ [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
+ ax_pthread_special_flags_added=yes])
+
+ AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+ [ax_cv_PTHREAD_PRIO_INHERIT],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
+ [[int i = PTHREAD_PRIO_INHERIT;
+ return i;]])],
+ [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+ [ax_cv_PTHREAD_PRIO_INHERIT=no])
+ ])
+ AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
+ test "x$ax_pthread_prio_inherit_defined" != "xyes"],
+ [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
+ ax_pthread_prio_inherit_defined=yes
+ ])
+
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ LIBS="$ax_pthread_save_LIBS"
+
+ # More AIX lossage: compile with *_r variant
+ if test "x$GCC" != "xyes"; then
+ case $target_os in
+ aix*)
+ AS_CASE(["x/$CC"],
+ [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
+ [#handle absolute path differently from PATH based program lookup
+ AS_CASE(["x$CC"],
+ [x/*],
+ [
+ AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])
+ AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])])
+ ],
+ [
+ AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])
+ AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])])
+ ]
+ )
+ ])
+ ;;
+ esac
+ fi
+fi
+
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX"
+
+AC_SUBST([PTHREAD_LIBS])
+AC_SUBST([PTHREAD_CFLAGS])
+AC_SUBST([PTHREAD_CC])
+AC_SUBST([PTHREAD_CXX])
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test "x$ax_pthread_ok" = "xyes"; then
+ ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
+ :
+else
+ ax_pthread_ok=no
+ $2
+fi
+AC_LANG_POP
+])dnl AX_PTHREAD
diff -Nru libp11-0.4.11/m4/libtool.m4 libp11-0.4.12/m4/libtool.m4
--- libp11-0.4.11/m4/libtool.m4 2018-10-02 20:46:57.000000000 +0200
+++ libp11-0.4.12/m4/libtool.m4 2022-03-15 18:14:13.000000000 +0100
@@ -1,6 +1,6 @@
# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
#
-# Copyright (C) 1996-2001, 2003-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
# Written by Gordon Matzigkeit, 1996
#
# This file is free software; the Free Software Foundation gives
@@ -219,8 +219,8 @@
ofile=libtool
can_build_shared=yes
-# All known linkers require a '.a' archive for static linking (except MSVC and
-# ICC, which need '.lib').
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
libext=a
with_gnu_ld=$lt_cv_prog_gnu_ld
@@ -728,7 +728,6 @@
cat <<_LT_EOF >> "$cfgfile"
#! $SHELL
# Generated automatically by $as_me ($PACKAGE) $VERSION
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
# Provide generalized library-building support services.
@@ -1042,8 +1041,8 @@
_LT_EOF
echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
$LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
- echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
- $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+ echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+ $AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
$RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
cat > conftest.c << _LT_EOF
@@ -1072,11 +1071,11 @@
# to the OS version, if on x86, and 10.4, the deployment
# target defaults to 10.4. Don't you love it?
case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
- 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ 10.0,*86*-darwin8*|10.0,*-darwin[[912]]*)
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
10.[[012]][[,.]]*)
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
- 10.*)
+ 10.*|11.*)
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
esac
;;
@@ -1493,22 +1492,9 @@
m4_defun([_LT_PROG_AR],
[AC_CHECK_TOOLS(AR, [ar], false)
: ${AR=ar}
+: ${AR_FLAGS=cr}
_LT_DECL([], [AR], [1], [The archiver])
-
-# Use ARFLAGS variable as AR's operation code to sync the variable naming with
-# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
-# higher priority because thats what people were doing historically (setting
-# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS
-# variable obsoleted/removed.
-
-test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
-lt_ar_flags=$AR_FLAGS
-_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)])
-
-# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override
-# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
-_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}],
- [Flags to create an archive])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
[lt_cv_ar_at_file=no
@@ -2220,35 +2206,26 @@
striplib=
old_striplib=
AC_MSG_CHECKING([whether stripping libraries is possible])
-if test -z "$STRIP"; then
- AC_MSG_RESULT([no])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
else
- if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
- old_striplib="$STRIP --strip-debug"
- striplib="$STRIP --strip-unneeded"
- AC_MSG_RESULT([yes])
- else
- case $host_os in
- darwin*)
- # FIXME - insert some real tests, host_os isn't really good enough
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
striplib="$STRIP -x"
old_striplib="$STRIP -S"
AC_MSG_RESULT([yes])
- ;;
- freebsd*)
- if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
- old_striplib="$STRIP --strip-debug"
- striplib="$STRIP --strip-unneeded"
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- fi
- ;;
- *)
+ else
AC_MSG_RESULT([no])
- ;;
- esac
- fi
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
fi
_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
_LT_DECL([], [striplib], [1])
@@ -2587,8 +2564,8 @@
dynamic_linker='Win32 ld.exe'
;;
- *,cl* | *,icl*)
- # Native MSVC or ICC
+ *,cl*)
+ # Native MSVC
libname_spec='$name'
soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
library_names_spec='$libname.dll.lib'
@@ -2644,7 +2621,7 @@
;;
*)
- # Assume MSVC and ICC wrapper
+ # Assume MSVC wrapper
library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
dynamic_linker='Win32 ld.exe'
;;
@@ -2909,6 +2886,18 @@
dynamic_linker='GNU/Linux ld.so'
;;
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
netbsd*)
version_type=sunos
need_lib_prefix=no
@@ -3568,7 +3557,7 @@
lt_cv_deplibs_check_method=pass_all
;;
-netbsd*)
+netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
else
@@ -4032,7 +4021,7 @@
if test "$lt_cv_nm_interface" = "MS dumpbin"; then
# Fake it for dumpbin and say T for any non-static function,
# D for any global variable and I for any imported variable.
- # Also find C++ and __fastcall symbols from MSVC++ or ICC,
+ # Also find C++ and __fastcall symbols from MSVC++,
# which start with @ or ?.
lt_cv_sys_global_symbol_pipe="$AWK ['"\
" {last_section=section; section=\$ 3};"\
@@ -4074,7 +4063,8 @@
if AC_TRY_EVAL(ac_compile); then
# Now try to grab the symbols.
nlist=conftest.nm
- if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+ $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD
+ if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then
# Try sorting and uniquifying the output.
if sort "$nlist" | uniq > "$nlist"T; then
mv -f "$nlist"T "$nlist"
@@ -4446,7 +4436,7 @@
;;
esac
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu)
;;
*qnx* | *nto*)
# QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -4714,6 +4704,12 @@
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
+ # flang / f18. f95 an alias for gfortran or flang on Debian
+ flang* | f18* | f95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
# icc used to be incompatible with GCC.
# ICC 10 doesn't accept -KPIC any more.
icc* | ifort*)
@@ -4941,7 +4937,7 @@
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
_LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
else
- _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
fi
;;
pw32*)
@@ -4949,7 +4945,7 @@
;;
cygwin* | mingw* | cegcc*)
case $cc_basename in
- cl* | icl*)
+ cl*)
_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
;;
*)
@@ -4958,6 +4954,9 @@
;;
esac
;;
+ linux* | k*bsd*-gnu | gnu*)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
*)
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
;;
@@ -5006,20 +5005,23 @@
case $host_os in
cygwin* | mingw* | pw32* | cegcc*)
- # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
- # Microsoft Visual C++ or Intel C++ Compiler.
+ # Microsoft Visual C++.
if test yes != "$GCC"; then
with_gnu_ld=no
fi
;;
interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
with_gnu_ld=yes
;;
openbsd* | bitrig*)
with_gnu_ld=no
;;
+ linux* | k*bsd*-gnu | gnu*)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
esac
_LT_TAGVAR(ld_shlibs, $1)=yes
@@ -5178,7 +5180,6 @@
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
- _LT_TAGVAR(file_list_spec, $1)='@'
;;
interix[[3-9]]*)
@@ -5275,7 +5276,7 @@
fi
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
@@ -5396,7 +5397,7 @@
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
_LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
else
- _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
fi
aix_use_runtimelinking=no
@@ -5579,12 +5580,12 @@
cygwin* | mingw* | pw32* | cegcc*)
# When not using gcc, we currently assume that we are using
- # Microsoft Visual C++ or Intel C++ Compiler.
+ # Microsoft Visual C++.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
case $cc_basename in
- cl* | icl*)
- # Native MSVC or ICC
+ cl*)
+ # Native MSVC
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
_LT_TAGVAR(always_export_symbols, $1)=yes
@@ -5625,7 +5626,7 @@
fi'
;;
*)
- # Assume MSVC and ICC wrapper
+ # Assume MSVC wrapper
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
# Tell ltmain to make .lib files, not .a files.
@@ -5796,6 +5797,7 @@
if test yes = "$lt_cv_irix_exported_symbol"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
fi
+ _LT_TAGVAR(link_all_deplibs, $1)=no
else
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -5817,7 +5819,7 @@
esac
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
@@ -5884,7 +5886,6 @@
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
- _LT_TAGVAR(file_list_spec, $1)='@'
;;
osf3*)
@@ -6444,7 +6445,7 @@
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
else
GXX=no
@@ -6655,8 +6656,8 @@
cygwin* | mingw* | pw32* | cegcc*)
case $GXX,$cc_basename in
- ,cl* | no,cl* | ,icl* | no,icl*)
- # Native MSVC or ICC
+ ,cl* | no,cl*)
+ # Native MSVC
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
@@ -6754,7 +6755,6 @@
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
- _LT_TAGVAR(file_list_spec, $1)='@'
;;
dgux*)
@@ -6820,7 +6820,7 @@
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test yes = "$GXX"; then
@@ -6885,7 +6885,7 @@
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test yes = "$GXX"; then
@@ -7224,7 +7224,7 @@
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
else
# FIXME: insert proper C++ library support
@@ -7308,7 +7308,7 @@
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
else
# g++ 2.7 appears to require '-G' NOT '-shared' on this
# platform.
@@ -7319,7 +7319,7 @@
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
fi
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
diff -Nru libp11-0.4.11/m4/lt~obsolete.m4 libp11-0.4.12/m4/lt~obsolete.m4
--- libp11-0.4.11/m4/lt~obsolete.m4 2018-10-02 20:46:57.000000000 +0200
+++ libp11-0.4.12/m4/lt~obsolete.m4 2022-03-15 18:14:13.000000000 +0100
@@ -1,6 +1,6 @@
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
-# Copyright (C) 2004-2005, 2007, 2009, 2011-2018 Free Software
+# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
# Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
diff -Nru libp11-0.4.11/m4/ltoptions.m4 libp11-0.4.12/m4/ltoptions.m4
--- libp11-0.4.11/m4/ltoptions.m4 2018-10-02 20:46:57.000000000 +0200
+++ libp11-0.4.12/m4/ltoptions.m4 2022-03-15 18:14:13.000000000 +0100
@@ -1,6 +1,6 @@
# Helper functions for option handling. -*- Autoconf -*-
#
-# Copyright (C) 2004-2005, 2007-2009, 2011-2018 Free Software
+# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
diff -Nru libp11-0.4.11/m4/ltsugar.m4 libp11-0.4.12/m4/ltsugar.m4
--- libp11-0.4.11/m4/ltsugar.m4 2018-10-02 20:46:57.000000000 +0200
+++ libp11-0.4.12/m4/ltsugar.m4 2022-03-15 18:14:13.000000000 +0100
@@ -1,6 +1,6 @@
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
-# Copyright (C) 2004-2005, 2007-2008, 2011-2018 Free Software
+# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
diff -Nru libp11-0.4.11/m4/ltversion.m4 libp11-0.4.12/m4/ltversion.m4
--- libp11-0.4.11/m4/ltversion.m4 2018-10-02 20:46:57.000000000 +0200
+++ libp11-0.4.12/m4/ltversion.m4 2022-03-15 18:14:13.000000000 +0100
@@ -1,6 +1,6 @@
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
-# Copyright (C) 2004, 2011-2018 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
@@ -9,15 +9,15 @@
# @configure_input@
-# serial 4221 ltversion.m4
+# serial 4179 ltversion.m4
# This file is part of GNU Libtool
-m4_define([LT_PACKAGE_VERSION], [2.4.6.42-b88ce])
-m4_define([LT_PACKAGE_REVISION], [2.4.6.42])
+m4_define([LT_PACKAGE_VERSION], [2.4.6])
+m4_define([LT_PACKAGE_REVISION], [2.4.6])
AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.4.6.42-b88ce'
-macro_revision='2.4.6.42'
+[macro_version='2.4.6'
+macro_revision='2.4.6'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])
diff -Nru libp11-0.4.11/Makefile.in libp11-0.4.12/Makefile.in
--- libp11-0.4.11/Makefile.in 2020-10-11 15:46:57.000000000 +0200
+++ libp11-0.4.12/Makefile.in 2022-07-15 21:56:26.000000000 +0200
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.2 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -88,9 +88,11 @@
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+target_triplet = @target@
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ld-version-script.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \
+ $(top_srcdir)/m4/ld-version-script.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -186,12 +188,10 @@
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
-CSCOPE = cscope
DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in COPYING NEWS compile \
- config.guess config.sub depcomp install-sh ltmain.sh missing
+am__DIST_COMMON = $(srcdir)/Makefile.in COPYING INSTALL.md NEWS \
+ README.md compile config.guess config.sub depcomp install-sh \
+ ltmain.sh missing
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@@ -230,6 +230,8 @@
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
DIST_TARGETS = dist-gzip
+# Exists only to be overridden by the user if desired.
+AM_DISTCHECK_DVI_TARGET = dvi
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
@@ -248,6 +250,8 @@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
@@ -259,6 +263,7 @@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
+ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
@@ -305,6 +310,10 @@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_CXX = @PTHREAD_CXX@
+PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
RC = @RC@
SED = @SED@
@@ -327,6 +336,7 @@
am__tar = @am__tar@
am__untar = @am__untar@
apidocdir = @apidocdir@
+ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -366,7 +376,11 @@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
+target = @target@
target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@@ -561,7 +575,6 @@
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
-
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -711,7 +724,7 @@
$(DISTCHECK_CONFIGURE_FLAGS) \
--srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
diff -Nru libp11-0.4.11/make.rules.mak libp11-0.4.12/make.rules.mak
--- libp11-0.4.11/make.rules.mak 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/make.rules.mak 2021-10-30 14:20:08.000000000 +0200
@@ -43,6 +43,6 @@
LIBS = "$(OPENSSL_LIB)" ws2_32.lib user32.lib advapi32.lib crypt32.lib gdi32.lib
-CFLAGS = /nologo /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MT$(DEBUG_SUFFIX) $(OPENSSL_INC) /D_WIN32_WINNT=0x0502 /DWIN32_LEAN_AND_MEAN $(DEBUG_COMPILE)
+CFLAGS = /nologo /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MT$(DEBUG_SUFFIX) $(OPENSSL_INC) /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN $(DEBUG_COMPILE)
LINKFLAGS = /NOLOGO /INCREMENTAL:NO $(MACHINE) /MANIFEST:NO /NXCOMPAT /DYNAMICBASE $(DEBUG_LINK)
diff -Nru libp11-0.4.11/missing libp11-0.4.12/missing
--- libp11-0.4.11/missing 2018-10-02 20:47:03.000000000 +0200
+++ libp11-0.4.12/missing 2022-03-15 18:14:17.000000000 +0100
@@ -3,7 +3,7 @@
scriptversion=2018-03-07.03; # UTC
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
diff -Nru libp11-0.4.11/NEWS libp11-0.4.12/NEWS
--- libp11-0.4.11/NEWS 2020-10-11 16:48:43.000000000 +0200
+++ libp11-0.4.12/NEWS 2022-07-15 23:36:16.000000000 +0200
@@ -1,5 +1,24 @@
NEWS for Libp11 -- History of user visible changes
+New in 0.4.12; 2022-07-15; Michał Trojnara
+* Fixed using an explicitly provided PIN regardless of the secure login
+ flag (Alon Bar-Lev)
+* Fixed RSA_PKCS1_PADDING handling (Michał Trojnara)
+* Fixed a crash on LLP64, including 64-bit Windows (Małgorzata Olszówka)
+* Fixed searching objects when both ID and label are specified (minfrin)
+* Fixed the OAEP "source" parameter (S-P Chan)
+* Fixed object searching by label (Michał Trojnara)
+* Fixed thread safety in slot enumeration (Michał Trojnara)
+* Fixed storing certificates on tokens (Mateusz Kwiatkowski)
+* Fixed several memory leaks (Michał Trojnara, Jakub Jelen, Timo Teräs)
+* Fixed OpenSSL 3.0 compatibility (Jakub Jelen)
+* Fixed LibreSSL compatibility (orbea, patchMonkey156)
+* Major concurrency improvements and refactoring (Timo Teräs)
+* Added re-numeration of slots as an engine control command (Markus Koetter)
+* Added the PKCS11_update_slots() API function (Timo Teräs)
+* Added support for the SHA3 hash function (alegon01)
+* Added a self-test for engine RSA operations (Uri Blumenthal)
+
New in 0.4.11; 2020-10-11; Michał Trojnara
* Fixed "EVP_PKEY_derive:buffer too small" EC errors (Luka Logar)
* Fixed various memory leaks (Mateusz Kwiatkowski)
@@ -176,7 +195,7 @@
New in 0.2.6; 2009-07-22; Andreas Jellinghaus
* Fix new version: add new symbol to export file
-* fix building on MSVC plattform
+* fix building on MSVC platform
New in 0.2.5; 2009-06-15; Andreas Jellinghaus
* Add function to export the slot id (Douglas E. Engert).
diff -Nru libp11-0.4.11/README.md libp11-0.4.12/README.md
--- libp11-0.4.11/README.md 2018-12-24 22:39:59.000000000 +0100
+++ libp11-0.4.12/README.md 2021-10-30 14:20:08.000000000 +0200
@@ -168,6 +168,7 @@
* **SET_USER_INTERFACE**: Set the global user interface
* **SET_CALLBACK_DATA**: Set the global user interface extra data
* **FORCE_LOGIN**: Force login to the PKCS#11 module
+* **RE_ENUMERATE**: re-enumerate the slots/tokens, required when adding/removing tokens/slots
An example code snippet setting specific module is shown below.
@@ -184,11 +185,14 @@
## Thread safety in libp11
-Thread-safety requires dynamic callbacks to be registered by the calling
-application with the following OpenSSL functions:
-* CRYPTO_set_dynlock_create_callback
-* CRYPTO_set_dynlock_destroy_callback
-* CRYPTO_set_dynlock_lock_callback
+libp11 internally uses OS locking, and configures the PKCS#11 module to do
+the same.
+
+Access to the the PKCS#11 tokens and objects is via a pool of PKCS#11 sessions.
+This allows concurrent usage of crypto operations in thread safe manner.
+
+However, many of the main PKCS11_* API functions are currently not fully thread
+safe. Work to fix this is pending.
## Submitting pull requests
diff -Nru libp11-0.4.11/src/config.h.in libp11-0.4.12/src/config.h.in
--- libp11-0.4.11/src/config.h.in 2020-10-11 15:47:02.000000000 +0200
+++ libp11-0.4.12/src/config.h.in 2022-07-15 21:56:31.000000000 +0200
@@ -30,6 +30,12 @@
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Have PTHREAD_PRIO_INHERIT. */
+#undef HAVE_PTHREAD_PRIO_INHERIT
+
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
@@ -60,9 +66,6 @@
/* Define to 1 if you have the <utmp.h> header file. */
#undef HAVE_UTMP_H
-/* Define to 1 if you have the `__register_atfork' function. */
-#undef HAVE___REGISTER_ATFORK
-
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
@@ -87,6 +90,10 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
diff -Nru libp11-0.4.11/src/eng_back.c libp11-0.4.12/src/eng_back.c
--- libp11-0.4.11/src/eng_back.c 2020-10-11 15:35:09.000000000 +0200
+++ libp11-0.4.12/src/eng_back.c 2022-07-05 22:22:51.000000000 +0200
@@ -27,6 +27,7 @@
*/
#include "engine.h"
+#include "p11_pthread.h"
#include <stdio.h>
#include <string.h>
@@ -48,19 +49,14 @@
*/
char *pin;
size_t pin_length;
+ int forced_pin;
int verbose;
char *module;
char *init_args;
UI_METHOD *ui_method;
void *callback_data;
int force_login;
-
- /* Engine initialization mutex */
-#if OPENSSL_VERSION_NUMBER >= 0x10100004L && !defined(LIBRESSL_VERSION_NUMBER)
- CRYPTO_RWLOCK *rwlock;
-#else
- int rwlock;
-#endif
+ pthread_mutex_t lock;
/* Current operations */
PKCS11_CTX *pkcs11_ctx;
@@ -68,6 +64,8 @@
unsigned int slot_count;
};
+static int ctx_ctrl_set_pin(ENGINE_CTX *ctx, const char *pin);
+
/******************************************************************************/
/* Utility functions */
/******************************************************************************/
@@ -92,6 +90,38 @@
ctx_log(ctx, level, "%02x", val[n]);
}
+static void dump_expiry(ENGINE_CTX *ctx, int level,
+ const PKCS11_CERT *cert)
+{
+ BIO *bio;
+ const ASN1_TIME *exp;
+
+ char *data = NULL;
+ int len = 0;
+
+ if (level > ctx->verbose) {
+ return;
+ }
+
+ if (!cert || !cert->x509 || !(exp = X509_get0_notAfter(cert->x509))) {
+ ctx_log(ctx, level, "none");
+ }
+
+ if ((bio = BIO_new(BIO_s_mem())) == NULL) {
+ return;
+ }
+
+ ASN1_TIME_print(bio, exp);
+
+ len = BIO_get_mem_data(bio, &data);
+
+ ctx_log(ctx, level, "%.*s", len, data);
+
+ BIO_free(bio);
+
+ return;
+}
+
/******************************************************************************/
/* PIN handling */
/******************************************************************************/
@@ -104,6 +134,7 @@
OPENSSL_free(ctx->pin);
ctx->pin = NULL;
ctx->pin_length = 0;
+ ctx->forced_pin = 0;
}
}
@@ -182,7 +213,7 @@
/* If the token has a secure login (i.e., an external keypad),
* then use a NULL PIN. Otherwise, obtain a new PIN if needed. */
- if (tok->secureLogin) {
+ if (tok->secureLogin && !ctx->forced_pin) {
/* Free the PIN if it has already been
* assigned (i.e, cached by ctx_get_pin) */
ctx_destroy_pin(ctx);
@@ -224,6 +255,7 @@
if (!ctx)
return NULL;
memset(ctx, 0, sizeof(ENGINE_CTX));
+ pthread_mutex_init(&ctx->lock, 0);
mod = getenv("PKCS11_MODULE_PATH");
if (mod) {
@@ -236,13 +268,6 @@
#endif
}
-#if OPENSSL_VERSION_NUMBER >= 0x10100004L && !defined(LIBRESSL_VERSION_NUMBER)
- ctx->rwlock = CRYPTO_THREAD_lock_new();
-#else
- ctx->rwlock = CRYPTO_get_dynlock_create_callback() ?
- CRYPTO_get_new_dynlockid() : 0;
-#endif
-
return ctx;
}
@@ -253,69 +278,57 @@
ctx_destroy_pin(ctx);
OPENSSL_free(ctx->module);
OPENSSL_free(ctx->init_args);
-#if OPENSSL_VERSION_NUMBER >= 0x10100004L && !defined(LIBRESSL_VERSION_NUMBER)
- CRYPTO_THREAD_lock_free(ctx->rwlock);
-#else
- if (ctx->rwlock)
- CRYPTO_destroy_dynlockid(ctx->rwlock);
-#endif
+ pthread_mutex_destroy(&ctx->lock);
OPENSSL_free(ctx);
}
return 1;
}
+static int ctx_enumerate_slots_unlocked(ENGINE_CTX *ctx, PKCS11_CTX *pkcs11_ctx)
+{
+ /* PKCS11_update_slots() uses C_GetSlotList() via libp11 */
+ if (PKCS11_update_slots(pkcs11_ctx, &ctx->slot_list, &ctx->slot_count) < 0) {
+ ctx_log(ctx, 0, "Failed to enumerate slots\n");
+ return 0;
+ }
+ ctx_log(ctx, 1, "Found %u slot%s\n", ctx->slot_count,
+ ctx->slot_count <= 1 ? "" : "s");
+ return 1;
+}
+
+static int ctx_enumerate_slots(ENGINE_CTX *ctx, PKCS11_CTX *pkcs11_ctx)
+{
+ int rv;
+
+ pthread_mutex_lock(&ctx->lock);
+ rv = ctx_enumerate_slots_unlocked(ctx, pkcs11_ctx);
+ pthread_mutex_unlock(&ctx->lock);
+ return rv;
+}
+
/* Initialize libp11 data: ctx->pkcs11_ctx and ctx->slot_list */
-static void ctx_init_libp11_unlocked(ENGINE_CTX *ctx)
+static int ctx_init_libp11_unlocked(ENGINE_CTX *ctx)
{
PKCS11_CTX *pkcs11_ctx;
- PKCS11_SLOT *slot_list = NULL;
- unsigned int slot_count = 0;
- ctx_log(ctx, 1, "PKCS#11: Initializing the engine\n");
+ if (ctx->pkcs11_ctx && ctx->slot_list)
+ return 0;
+
+ ctx_log(ctx, 1, "PKCS#11: Initializing the engine: %s\n", ctx->module);
pkcs11_ctx = PKCS11_CTX_new();
PKCS11_CTX_init_args(pkcs11_ctx, ctx->init_args);
PKCS11_set_ui_method(pkcs11_ctx, ctx->ui_method, ctx->callback_data);
-
- /* PKCS11_CTX_load() uses C_GetSlotList() via p11-kit */
if (PKCS11_CTX_load(pkcs11_ctx, ctx->module) < 0) {
ctx_log(ctx, 0, "Unable to load module %s\n", ctx->module);
PKCS11_CTX_free(pkcs11_ctx);
- return;
- }
-
- /* PKCS11_enumerate_slots() uses C_GetSlotList() via libp11 */
- if (PKCS11_enumerate_slots(pkcs11_ctx, &slot_list, &slot_count) < 0) {
- ctx_log(ctx, 0, "Failed to enumerate slots\n");
- PKCS11_CTX_unload(pkcs11_ctx);
- PKCS11_CTX_free(pkcs11_ctx);
- return;
+ return -1;
}
-
- ctx_log(ctx, 1, "Found %u slot%s\n", slot_count,
- slot_count <= 1 ? "" : "s");
-
ctx->pkcs11_ctx = pkcs11_ctx;
- ctx->slot_list = slot_list;
- ctx->slot_count = slot_count;
-}
-static int ctx_init_libp11(ENGINE_CTX *ctx)
-{
-#if OPENSSL_VERSION_NUMBER >= 0x10100004L && !defined(LIBRESSL_VERSION_NUMBER)
- CRYPTO_THREAD_write_lock(ctx->rwlock);
-#else
- if (ctx->rwlock)
- CRYPTO_w_lock(ctx->rwlock);
-#endif
- if (!ctx->pkcs11_ctx|| !ctx->slot_list)
- ctx_init_libp11_unlocked(ctx);
-#if OPENSSL_VERSION_NUMBER >= 0x10100004L && !defined(LIBRESSL_VERSION_NUMBER)
- CRYPTO_THREAD_unlock(ctx->rwlock);
-#else
- if (ctx->rwlock)
- CRYPTO_w_unlock(ctx->rwlock);
-#endif
+ if (ctx_enumerate_slots_unlocked(ctx, pkcs11_ctx) != 1)
+ return -1;
+
return ctx->pkcs11_ctx && ctx->slot_list ? 0 : -1;
}
@@ -327,21 +340,7 @@
* Double-locking a non-recursive rwlock causes the application to
* crash or hang, depending on the locking library implementation. */
- /* Only attempt initialization when dynamic locks are unavailable.
- * This likely also indicates a single-threaded application,
- * so temporarily unlocking CRYPTO_LOCK_ENGINE should be safe. */
-#if OPENSSL_VERSION_NUMBER < 0x10100004L && !defined(LIBRESSL_VERSION_NUMBER)
- if (CRYPTO_get_dynlock_create_callback() == NULL ||
- CRYPTO_get_dynlock_lock_callback() == NULL ||
- CRYPTO_get_dynlock_destroy_callback() == NULL) {
- CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
- ctx_init_libp11_unlocked(ctx);
- CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
- return ctx->pkcs11_ctx && ctx->slot_list ? 1 : 0;
- }
-#else
(void)ctx; /* squash the unused parameter warning */
-#endif
return 1;
}
@@ -365,77 +364,74 @@
}
/******************************************************************************/
-/* Certificate handling */
+/* Utilities common to public, private key and certificate handling */
/******************************************************************************/
-/* prototype for OpenSSL ENGINE_load_cert */
-/* used by load_cert_ctrl via ENGINE_ctrl for now */
-
-static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id,
- const int login)
+static void *ctx_try_load_object(ENGINE_CTX *ctx,
+ const char *object_typestr,
+ void *(*match_func)(ENGINE_CTX *, PKCS11_TOKEN *,
+ const unsigned char *, size_t, const char *),
+ const char *object_uri, const int login,
+ UI_METHOD *ui_method, void *callback_data)
{
PKCS11_SLOT *slot;
PKCS11_SLOT *found_slot = NULL, **matched_slots = NULL;
PKCS11_TOKEN *tok, *match_tok = NULL;
- PKCS11_CERT *certs, *selected_cert = NULL;
- X509 *x509 = NULL;
- unsigned int cert_count, n, m;
- unsigned char cert_id[MAX_VALUE_LEN / 2];
- size_t cert_id_len = sizeof(cert_id);
- char *cert_label = NULL;
+ unsigned int n, m;
+ unsigned char obj_id[MAX_VALUE_LEN / 2];
+ size_t obj_id_len = sizeof(obj_id);
+ char *obj_label = NULL;
char tmp_pin[MAX_PIN_LENGTH+1];
size_t tmp_pin_len = MAX_PIN_LENGTH;
int slot_nr = -1;
char flags[64];
size_t matched_count = 0;
+ void *object = NULL;
- if (ctx_init_libp11(ctx)) /* Delayed libp11 initialization */
- return NULL;
-
- if (s_slot_cert_id && *s_slot_cert_id) {
- if (!strncasecmp(s_slot_cert_id, "pkcs11:", 7)) {
- n = parse_pkcs11_uri(ctx, s_slot_cert_id, &match_tok,
- cert_id, &cert_id_len,
- tmp_pin, &tmp_pin_len, &cert_label);
+ if (object_uri && *object_uri) {
+ if (!strncasecmp(object_uri, "pkcs11:", 7)) {
+ n = parse_pkcs11_uri(ctx, object_uri, &match_tok,
+ obj_id, &obj_id_len, tmp_pin, &tmp_pin_len, &obj_label);
if (!n) {
ctx_log(ctx, 0,
- "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);
+ "The %s ID is not a valid PKCS#11 URI\n"
+ "The PKCS#11 URI format is defined by RFC7512\n",
+ object_typestr);
+ ENGerr(ENG_F_CTX_LOAD_OBJECT, ENG_R_INVALID_ID);
goto error;
}
if (tmp_pin_len > 0 && tmp_pin[0] != 0) {
- ctx_destroy_pin(ctx);
- ctx->pin = OPENSSL_malloc(MAX_PIN_LENGTH+1);
- if (ctx->pin) {
- memset(ctx->pin, 0, MAX_PIN_LENGTH+1);
- memcpy(ctx->pin, tmp_pin, tmp_pin_len);
- ctx->pin_length = tmp_pin_len;
+ tmp_pin[tmp_pin_len] = 0;
+ if (!ctx_ctrl_set_pin(ctx, tmp_pin)) {
+ goto error;
}
}
+ ctx_log(ctx, 1, "Looking in slots for %s %s login: ",
+ object_typestr, login ? "with" : "without");
} else {
- n = parse_slot_id_string(ctx, s_slot_cert_id, &slot_nr,
- cert_id, &cert_id_len, &cert_label);
+ n = parse_slot_id_string(ctx, object_uri, &slot_nr,
+ obj_id, &obj_id_len, &obj_label);
if (!n) {
ctx_log(ctx, 0,
- "The certificate ID is not a valid PKCS#11 URI\n"
+ "The %s ID is not a valid PKCS#11 URI\n"
"The PKCS#11 URI format is defined by RFC7512\n"
"The legacy ENGINE_pkcs11 ID format is also "
- "still accepted for now\n");
- ENGerr(ENG_F_CTX_LOAD_CERT, ENG_R_INVALID_ID);
+ "still accepted for now\n",
+ object_typestr);
+ ENGerr(ENG_F_CTX_LOAD_OBJECT, ENG_R_INVALID_ID);
goto error;
}
+ ctx_log(ctx, 1, "Looking in slot %d for %s %s login: ",
+ slot_nr, object_typestr, login ? "with" : "without");
}
- ctx_log(ctx, 1, "Looking in slot %d for certificate: ",
- slot_nr);
- if (cert_id_len != 0) {
+ if (obj_id_len != 0) {
ctx_log(ctx, 1, "id=");
- dump_hex(ctx, 1, cert_id, cert_id_len);
+ dump_hex(ctx, 1, obj_id, obj_id_len);
}
- if (cert_id_len != 0 && cert_label)
+ if (obj_id_len != 0 && obj_label)
ctx_log(ctx, 1, " ");
- if (cert_label)
- ctx_log(ctx, 1, "label=%s", cert_label);
+ if (obj_label)
+ ctx_log(ctx, 1, "label=%s", obj_label);
ctx_log(ctx, 1, "\n");
}
@@ -481,7 +477,7 @@
!strcmp(match_tok->model, slot->token->model))) {
found_slot = slot;
}
- ctx_log(ctx, 1, "[%lu] %-25.25s %-16s",
+ ctx_log(ctx, 1, "- [%lu] %-25.25s %-36s",
PKCS11_get_slotid_from_slot(slot),
slot->description, flags);
if (slot->token) {
@@ -491,9 +487,6 @@
}
ctx_log(ctx, 1, "\n");
- 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;
@@ -504,13 +497,20 @@
if (matched_count == 0) {
if (match_tok) {
- ctx_log(ctx, 0, "Specified object not found\n");
+ if (found_slot) {
+ ctx_log(ctx, 0, "The %s was not found on token %s\n",
+ object_typestr, found_slot->token->label[0] ?
+ found_slot->token->label : "no label");
+ } else {
+ ctx_log(ctx, 0, "No matching initialized token was found for %s\n",
+ object_typestr);
+ }
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);
+ ctx_log(ctx, 0, "The %s was not found on slot %d\n", object_typestr, slot_nr);
goto error;
} else {
found_slot = PKCS11_find_token(ctx->pkcs11_ctx,
@@ -531,7 +531,7 @@
slot = matched_slots[n];
tok = slot->token;
if (!tok) {
- ctx_log(ctx, 0, "Empty token found\n");
+ ctx_log(ctx, 0, "Empty slot found\n");
break;
}
@@ -546,7 +546,7 @@
* the PIN against all matching slots */
if (matched_count == 1) {
if (!ctx_login(ctx, slot, tok,
- ctx->ui_method, ctx->callback_data)) {
+ ui_method, callback_data)) {
ctx_log(ctx, 0, "Login to token failed, returning NULL...\n");
goto error;
}
@@ -555,7 +555,7 @@
" 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,
+ ctx_log(ctx, 0, "- [%u] %s: %s\n", m + 1,
slot->description? slot->description:
"(no description)",
(slot->token && slot->token->label)?
@@ -566,48 +566,11 @@
}
}
- if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) {
- ctx_log(ctx, 0, "Unable to enumerate certificates\n");
- continue;
- }
-
- 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)) {
- for (m = 0; m < cert_count; m++) {
- PKCS11_CERT *k = certs + m;
-
- if (cert_label && k->label && 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) {
+ object = match_func(ctx, tok, obj_id, obj_id_len, obj_label);
+ if (object)
break;
- }
}
- if (selected_cert) {
- x509 = X509_dup(selected_cert->x509);
- } else {
- if (login) /* Only print the error on the second attempt */
- ctx_log(ctx, 0, "Certificate not found.\n");
- x509 = NULL;
- }
error:
/* Free the searched token data */
if (match_tok) {
@@ -618,363 +581,313 @@
OPENSSL_free(match_tok);
}
- if (cert_label)
- OPENSSL_free(cert_label);
+ if (obj_label)
+ OPENSSL_free(obj_label);
if (matched_slots)
free(matched_slots);
- return x509;
+ return object;
}
-static int ctx_ctrl_load_cert(ENGINE_CTX *ctx, void *p)
+static void *ctx_load_object(ENGINE_CTX *ctx,
+ const char *object_typestr,
+ void *(*match_func)(ENGINE_CTX *, PKCS11_TOKEN *,
+ const unsigned char *, size_t, const char *),
+ const char *object_uri, UI_METHOD *ui_method, void *callback_data)
{
- struct {
- const char *s_slot_cert_id;
- X509 *cert;
- } *parms = p;
+ void *obj = NULL;
- if (!parms) {
- ENGerr(ENG_F_CTX_CTRL_LOAD_CERT, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
- }
- if (parms->cert) {
- ENGerr(ENG_F_CTX_CTRL_LOAD_CERT, ENG_R_INVALID_PARAMETER);
- return 0;
+ pthread_mutex_lock(&ctx->lock);
+
+ /* Delayed libp11 initialization */
+ if (ctx_init_libp11_unlocked(ctx)) {
+ ENGerr(ENG_F_CTX_LOAD_OBJECT, ENG_R_INVALID_PARAMETER);
+ pthread_mutex_unlock(&ctx->lock);
+ return NULL;
}
- ERR_clear_error();
- if (!ctx->force_login)
- parms->cert = ctx_load_cert(ctx, parms->s_slot_cert_id, 0);
- if (!parms->cert) { /* Try again with login */
+
+ if (!ctx->force_login) {
ERR_clear_error();
- parms->cert = ctx_load_cert(ctx, parms->s_slot_cert_id, 1);
+ obj = ctx_try_load_object(ctx, object_typestr, match_func,
+ object_uri, 0, ui_method, callback_data);
}
- if (!parms->cert) {
- if (!ERR_peek_last_error())
- ENGerr(ENG_F_CTX_CTRL_LOAD_CERT, ENG_R_OBJECT_NOT_FOUND);
- return 0;
+
+ if (!obj) {
+ /* Try again with login */
+ ERR_clear_error();
+ obj = ctx_try_load_object(ctx, object_typestr, match_func,
+ object_uri, 1, ui_method, callback_data);
+ if (!obj) {
+ ctx_log(ctx, 0, "The %s was not found at: %s\n",
+ object_typestr, object_uri);
+ }
}
- return 1;
+
+ pthread_mutex_unlock(&ctx->lock);
+ return obj;
}
/******************************************************************************/
-/* Private and public key handling */
+/* Certificate handling */
/******************************************************************************/
-static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id,
- UI_METHOD *ui_method, void *callback_data,
- const int isPrivate, const int login)
+static PKCS11_CERT *cert_cmp(PKCS11_CERT *a, PKCS11_CERT *b, time_t *ptime)
{
- PKCS11_SLOT *slot;
- PKCS11_SLOT *found_slot = NULL, **matched_slots = NULL;
- PKCS11_TOKEN *tok, *match_tok = NULL;
- PKCS11_KEY *keys, *selected_key = NULL;
- EVP_PKEY *pk = NULL;
- unsigned int key_count, n, m;
- unsigned char key_id[MAX_VALUE_LEN / 2];
- size_t key_id_len = sizeof(key_id);
- char *key_label = NULL;
- int slot_nr = -1;
- char tmp_pin[MAX_PIN_LENGTH+1];
- size_t tmp_pin_len = MAX_PIN_LENGTH;
- char flags[64];
- size_t matched_count = 0;
+ const ASN1_TIME *a_time, *b_time;
+ int pday, psec;
- if (ctx_init_libp11(ctx)) /* Delayed libp11 initialization */
- goto error;
+ /* the best certificate exists */
+ if (!a || !a->x509) {
+ return b;
+ }
+ if (!b || !b->x509) {
+ return a;
+ }
- ctx_log(ctx, 1, "Loading %s key \"%s\"\n",
- (char *)(isPrivate ? "private" : "public"),
- s_slot_key_id);
- if (s_slot_key_id && *s_slot_key_id) {
- if (!strncasecmp(s_slot_key_id, "pkcs11:", 7)) {
- n = parse_pkcs11_uri(ctx, s_slot_key_id, &match_tok,
- key_id, &key_id_len,
- tmp_pin, &tmp_pin_len, &key_label);
- if (!n) {
- ctx_log(ctx, 0,
- "The key ID is not a valid PKCS#11 URI\n"
- "The PKCS#11 URI format is defined by RFC7512\n");
- ENGerr(ENG_F_CTX_LOAD_KEY, ENG_R_INVALID_ID);
- goto error;
- }
- if (tmp_pin_len > 0 && tmp_pin[0] != 0) {
- /* 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);
- if (ctx->pin) {
- memset(ctx->pin, 0, MAX_PIN_LENGTH+1);
- memcpy(ctx->pin, tmp_pin, tmp_pin_len);
- ctx->pin_length = tmp_pin_len;
- }
- }
- } else {
- n = parse_slot_id_string(ctx, s_slot_key_id, &slot_nr,
- key_id, &key_id_len, &key_label);
- if (!n) {
- ctx_log(ctx, 0,
- "The key ID is not a valid PKCS#11 URI\n"
- "The PKCS#11 URI format is defined by RFC7512\n"
- "The legacy ENGINE_pkcs11 ID format is also "
- "still accepted for now\n");
- ENGerr(ENG_F_CTX_LOAD_KEY, ENG_R_INVALID_ID);
- goto error;
- }
- }
- ctx_log(ctx, 1, "Looking in slot %d for key: ",
- slot_nr);
- if (key_id_len != 0) {
- ctx_log(ctx, 1, "id=");
- dump_hex(ctx, 1, key_id, key_id_len);
+ a_time = X509_get0_notAfter(a->x509);
+ b_time = X509_get0_notAfter(b->x509);
+
+ /* the best certificate expires last */
+ if (ASN1_TIME_diff(&pday, &psec, a_time, b_time)) {
+ if (pday < 0 || psec < 0) {
+ return a;
+ } else if (pday > 0 || psec > 0) {
+ return b;
}
- if (key_id_len != 0 && key_label)
- ctx_log(ctx, 1, " ");
- if (key_label)
- ctx_log(ctx, 1, "label=%s", key_label);
- ctx_log(ctx, 1, "\n");
}
- matched_slots = (PKCS11_SLOT **)calloc(ctx->slot_count,
- sizeof(PKCS11_SLOT *));
- if (!matched_slots) {
- ctx_log(ctx, 0, "Could not allocate memory for matched slots\n");
- goto error;
+ /* deterministic tie break */
+ if (X509_cmp(a->x509, b->x509) < 1) {
+ return b;
+ } else {
+ return a;
}
+}
- for (n = 0; n < ctx->slot_count; n++) {
- slot = ctx->slot_list + n;
- flags[0] = '\0';
- if (slot->token) {
- if (!slot->token->initialized)
- strcat(flags, "uninitialized, ");
- else if (!slot->token->userPinSet)
- strcat(flags, "no pin, ");
- if (slot->token->loginRequired)
- strcat(flags, "login, ");
- if (slot->token->readOnly)
- strcat(flags, "ro, ");
- } else {
- strcpy(flags, "no token");
- }
- if ((m = strlen(flags)) != 0) {
- flags[m - 2] = '\0';
- }
+static void *match_cert(ENGINE_CTX *ctx, PKCS11_TOKEN *tok,
+ const unsigned char *obj_id, size_t obj_id_len, const char *obj_label)
+{
+ PKCS11_CERT *certs, *selected_cert = NULL;
+ unsigned int m, cert_count;
+ const char *which;
- if (slot_nr != -1 &&
- slot_nr == (int)PKCS11_get_slotid_from_slot(slot)) {
- found_slot = slot;
- }
+ if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) {
+ ctx_log(ctx, 0, "Unable to enumerate certificates\n");
+ return NULL;
+ }
+ if (cert_count == 0)
+ return NULL;
- if (match_tok && slot->token &&
- (!match_tok->label ||
- !strcmp(match_tok->label, slot->token->label)) &&
- (!match_tok->manufacturer ||
- !strcmp(match_tok->manufacturer, slot->token->manufacturer)) &&
- (!match_tok->serialnr ||
- !strcmp(match_tok->serialnr, slot->token->serialnr)) &&
- (!match_tok->model ||
- !strcmp(match_tok->model, slot->token->model))) {
- found_slot = slot;
+ ctx_log(ctx, 1, "Found %u certificate%s:\n", cert_count, cert_count == 1 ? "" : "s");
+ if (obj_id_len != 0 || obj_label) {
+ which = "longest expiry matching";
+ for (m = 0; m < cert_count; m++) {
+ PKCS11_CERT *k = certs + m;
+
+ ctx_log(ctx, 1, " %2u id=", m + 1);
+ dump_hex(ctx, 1, k->id, k->id_len);
+ ctx_log(ctx, 1, " label=%s expiry=", k->label ? k->label : "(null)");
+ dump_expiry(ctx, 1, k);
+ ctx_log(ctx, 1, "\n");
+
+ if (obj_label && obj_id_len != 0) {
+ if (k->label && strcmp(k->label, obj_label) == 0 &&
+ k->id_len == obj_id_len &&
+ memcmp(k->id, obj_id, obj_id_len) == 0) {
+ selected_cert = cert_cmp(selected_cert, k, NULL);
+ }
+ } else if (obj_label && !obj_id_len) {
+ if (k->label && strcmp(k->label, obj_label) == 0) {
+ selected_cert = cert_cmp(selected_cert, k, NULL);
+ }
+ } else if (obj_id_len && !obj_label) {
+ if (k->id_len == obj_id_len &&
+ memcmp(k->id, obj_id, obj_id_len) == 0) {
+ selected_cert = cert_cmp(selected_cert, k, NULL);
+ }
+ }
}
- ctx_log(ctx, 1, "[%lu] %-25.25s %-16s",
- PKCS11_get_slotid_from_slot(slot),
- slot->description, flags);
- if (slot->token) {
- ctx_log(ctx, 1, " (%s)",
- slot->token->label[0] ?
- slot->token->label : "no label");
+ } else {
+ which = "first (with id present)";
+ for (m = 0; m < cert_count; m++) {
+ PKCS11_CERT *k = certs + m;
+
+ ctx_log(ctx, 1, " %2u id=", m + 1);
+ dump_hex(ctx, 1, k->id, k->id_len);
+ ctx_log(ctx, 1, " label=%s expiry=", k->label ? k->label : "(null)");
+ dump_expiry(ctx, 1, k);
+ ctx_log(ctx, 1, "\n");
+
+ if (!selected_cert && k->id && *k->id) {
+ selected_cert = k; /* Use the first certificate with nonempty id */
+ }
+ }
+ if (!selected_cert) {
+ which = "first";
+ selected_cert = certs; /* Use the first certificate */
}
+ }
+
+ if (selected_cert) {
+ ctx_log(ctx, 1, "Returning %s certificate: id=", which);
+ dump_hex(ctx, 1, selected_cert->id, selected_cert->id_len);
+ ctx_log(ctx, 1, " label=%s expiry=", selected_cert->label ? selected_cert->label : "(null)");
+ dump_expiry(ctx, 1, selected_cert);
ctx_log(ctx, 1, "\n");
+ } else {
+ ctx_log(ctx, 1, "No matching certificate returned.\n");
+ }
- if (found_slot && found_slot->token && !found_slot->token->initialized)
- ctx_log(ctx, 0, "Found uninitialized token\n");
+ return selected_cert;
+}
- /* 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;
- }
+static int ctx_ctrl_load_cert(ENGINE_CTX *ctx, void *p)
+{
+ struct {
+ const char *s_slot_cert_id;
+ X509 *cert;
+ } *parms = p;
+ PKCS11_CERT *cert;
- if (matched_count == 0) {
- if (match_tok) {
- ctx_log(ctx, 0, "Specified object not found\n");
- goto error;
- }
+ if (!parms) {
+ ENGerr(ENG_F_CTX_CTRL_LOAD_CERT, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ if (parms->cert) {
+ ENGerr(ENG_F_CTX_CTRL_LOAD_CERT, ENG_R_INVALID_PARAMETER);
+ return 0;
+ }
- /* 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;
- }
- }
+ cert = ctx_load_object(ctx, "certificate", match_cert, parms->s_slot_cert_id,
+ ctx->ui_method, ctx->callback_data);
+ if (!cert) {
+ if (!ERR_peek_last_error())
+ ENGerr(ENG_F_CTX_CTRL_LOAD_CERT, ENG_R_OBJECT_NOT_FOUND);
+ return 0;
}
+ parms->cert = X509_dup(cert->x509);
+ return 1;
+}
- for (n = 0; n < matched_count; n++) {
- slot = matched_slots[n];
- tok = slot->token;
- if (!tok) {
- ctx_log(ctx, 0, "Found empty token\n");
- break;
- }
+/******************************************************************************/
+/* Private and public key handling */
+/******************************************************************************/
- ctx_log(ctx, 1, "Found slot: %s\n", slot->description);
- ctx_log(ctx, 1, "Found token: %s\n", slot->token->label);
+static void *match_key(ENGINE_CTX *ctx, const char *key_type,
+ PKCS11_KEY *keys, unsigned int key_count,
+ const unsigned char *obj_id, size_t obj_id_len, const char *obj_label)
+{
+ PKCS11_KEY *selected_key = NULL;
+ unsigned int m;
+ const char *which;
- /* 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 (key_count == 0)
+ return NULL;
- 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;
- }
- }
- 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;
- }
- 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)) {
- 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 ? k->label : "(null)");
- if (key_label && k->label && strcmp(k->label, key_label) == 0)
+ ctx_log(ctx, 1, "Found %u %s key%s:\n", key_count, key_type,
+ key_count == 1 ? "" : "s");
+
+ if (obj_id_len != 0 || obj_label) {
+ which = "last matching";
+ 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 ? k->label : "(null)");
+
+ if (obj_label && obj_id_len != 0) {
+ if (k->label && strcmp(k->label, obj_label) == 0 &&
+ k->id_len == obj_id_len &&
+ memcmp(k->id, obj_id, obj_id_len) == 0) {
selected_key = k;
- if (key_id_len != 0 && k->id_len == key_id_len
- && memcmp(k->id, key_id, key_id_len) == 0)
+ }
+ } else if (obj_label && !obj_id_len) {
+ if (k->label && strcmp(k->label, obj_label) == 0) {
+ selected_key = k;
+ }
+ } else if (obj_id_len && !obj_label) {
+ if (k->id_len == obj_id_len &&
+ memcmp(k->id, obj_id, obj_id_len) == 0) {
selected_key = k;
+ }
}
- } else {
- selected_key = keys; /* Use the first key */
- }
-
- if (selected_key) {
- break;
}
+ } else {
+ which = "first";
+ selected_key = keys; /* Use the first key */
}
if (selected_key) {
- pk = isPrivate ?
- PKCS11_get_private_key(selected_key) :
- PKCS11_get_public_key(selected_key);
+ ctx_log(ctx, 1, "Returning %s %s key: id=", which, key_type);
+ dump_hex(ctx, 1, selected_key->id, selected_key->id_len);
+ ctx_log(ctx, 1, " label=%s\n", selected_key->label ? selected_key->label : "(null)");
} else {
- if (login) /* Only print the error on the second attempt */
- ctx_log(ctx, 0, "Key not found.\n");
- pk = NULL;
+ ctx_log(ctx, 1, "No matching %s key returned.\n", key_type);
}
-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);
+ return selected_key;
+}
+
+static void *match_public_key(ENGINE_CTX *ctx, PKCS11_TOKEN *tok,
+ const unsigned char *obj_id, size_t obj_id_len, const char *obj_label)
+{
+ PKCS11_KEY *keys;
+ unsigned int key_count;
+
+ /* 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");
+ return 0;
}
- if (key_label)
- OPENSSL_free(key_label);
- if (matched_slots)
- free(matched_slots);
- return pk;
+ return match_key(ctx, "public", keys, key_count, obj_id, obj_id_len, obj_label);
+}
+
+static void *match_private_key(ENGINE_CTX *ctx, PKCS11_TOKEN *tok,
+ const unsigned char *obj_id, size_t obj_id_len, const char *obj_label)
+{
+ PKCS11_KEY *keys;
+ unsigned int key_count;
+
+ /* 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");
+ return 0;
+ }
+ return match_key(ctx, "private", keys, key_count, obj_id, obj_id_len, obj_label);
}
EVP_PKEY *ctx_load_pubkey(ENGINE_CTX *ctx, const char *s_key_id,
UI_METHOD *ui_method, void *callback_data)
{
- EVP_PKEY *pk = NULL;
+ PKCS11_KEY *key;
- ERR_clear_error();
- if (!ctx->force_login)
- pk = ctx_load_key(ctx, s_key_id, ui_method, callback_data, 0, 0);
- if (!pk) { /* Try again with login */
- ERR_clear_error();
- pk = ctx_load_key(ctx, s_key_id, ui_method, callback_data, 0, 1);
- }
- if (!pk) {
+ key = ctx_load_object(ctx, "public key", match_public_key, s_key_id,
+ ui_method, callback_data);
+ if (!key) {
ctx_log(ctx, 0, "PKCS11_load_public_key returned NULL\n");
if (!ERR_peek_last_error())
ENGerr(ENG_F_CTX_LOAD_PUBKEY, ENG_R_OBJECT_NOT_FOUND);
return NULL;
}
- return pk;
+ return PKCS11_get_public_key(key);
}
EVP_PKEY *ctx_load_privkey(ENGINE_CTX *ctx, const char *s_key_id,
UI_METHOD *ui_method, void *callback_data)
{
- EVP_PKEY *pk = NULL;
+ PKCS11_KEY *key;
- ERR_clear_error();
- if (!ctx->force_login)
- pk = ctx_load_key(ctx, s_key_id, ui_method, callback_data, 1, 0);
- if (!pk) { /* Try again with login */
- ERR_clear_error();
- pk = ctx_load_key(ctx, s_key_id, ui_method, callback_data, 1, 1);
- }
- if (!pk) {
+ key = ctx_load_object(ctx, "private key", match_private_key, s_key_id,
+ ui_method, callback_data);
+ if (!key) {
ctx_log(ctx, 0, "PKCS11_get_private_key returned NULL\n");
if (!ERR_peek_last_error())
ENGerr(ENG_F_CTX_LOAD_PRIVKEY, ENG_R_OBJECT_NOT_FOUND);
return NULL;
}
- return pk;
+ return PKCS11_get_private_key(key);
}
/******************************************************************************/
@@ -1020,6 +933,7 @@
return 0;
}
ctx->pin_length = strlen(ctx->pin);
+ ctx->forced_pin = 1;
return 1;
}
@@ -1092,6 +1006,8 @@
return ctx_ctrl_set_callback_data(ctx, p);
case CMD_FORCE_LOGIN:
return ctx_ctrl_force_login(ctx);
+ case CMD_RE_ENUMERATE:
+ return ctx_enumerate_slots(ctx, ctx->pkcs11_ctx);
default:
ENGerr(ENG_F_CTX_ENGINE_CTRL, ENG_R_UNKNOWN_COMMAND);
break;
diff -Nru libp11-0.4.11/src/eng_err.h libp11-0.4.12/src/eng_err.h
--- libp11-0.4.11/src/eng_err.h 2018-02-20 08:52:07.000000000 +0100
+++ libp11-0.4.12/src/eng_err.h 2021-10-30 14:20:08.000000000 +0200
@@ -31,6 +31,7 @@
# define ENG_F_CTX_CTRL_LOAD_CERT 102
# define ENG_F_CTX_CTRL_SET_PIN 106
# define ENG_F_CTX_ENGINE_CTRL 105
+# define ENG_F_CTX_LOAD_OBJECT 107
# define ENG_F_CTX_LOAD_CERT 100
# define ENG_F_CTX_LOAD_KEY 101
# define ENG_F_CTX_LOAD_PRIVKEY 103
diff -Nru libp11-0.4.11/src/eng_front.c libp11-0.4.12/src/eng_front.c
--- libp11-0.4.11/src/eng_front.c 2020-10-11 15:34:40.000000000 +0200
+++ libp11-0.4.12/src/eng_front.c 2021-10-30 14:20:08.000000000 +0200
@@ -75,6 +75,10 @@
"FORCE_LOGIN",
"Force login to the PKCS#11 module",
ENGINE_CMD_FLAG_NO_INPUT},
+ {CMD_RE_ENUMERATE,
+ "RE_ENUMERATE",
+ "re enumerate slots",
+ ENGINE_CMD_FLAG_NO_INPUT},
{0, NULL, NULL, 0}
};
diff -Nru libp11-0.4.11/src/engine.h libp11-0.4.12/src/engine.h
--- libp11-0.4.11/src/engine.h 2018-08-03 07:57:27.000000000 +0200
+++ libp11-0.4.12/src/engine.h 2021-10-30 14:20:08.000000000 +0200
@@ -51,6 +51,7 @@
#define CMD_SET_USER_INTERFACE (ENGINE_CMD_BASE + 7)
#define CMD_SET_CALLBACK_DATA (ENGINE_CMD_BASE + 8)
#define CMD_FORCE_LOGIN (ENGINE_CMD_BASE+9)
+#define CMD_RE_ENUMERATE (ENGINE_CMD_BASE+10)
typedef struct st_engine_ctx ENGINE_CTX; /* opaque */
diff -Nru libp11-0.4.11/src/libp11.exports libp11-0.4.12/src/libp11.exports
--- libp11-0.4.11/src/libp11.exports 2018-08-05 13:11:37.000000000 +0200
+++ libp11-0.4.12/src/libp11.exports 2022-05-04 18:45:56.000000000 +0200
@@ -5,6 +5,7 @@
PKCS11_CTX_free
PKCS11_open_session
PKCS11_enumerate_slots
+PKCS11_update_slots
PKCS11_release_all_slots
PKCS11_find_token
PKCS11_find_next_token
diff -Nru libp11-0.4.11/src/libp11.h libp11-0.4.12/src/libp11.h
--- libp11-0.4.11/src/libp11.h 2018-08-09 07:17:07.000000000 +0200
+++ libp11-0.4.12/src/libp11.h 2022-05-04 18:45:56.000000000 +0200
@@ -60,7 +60,6 @@
size_t id_len;
unsigned char isPrivate; /**< private key present? */
unsigned char needLogin; /**< login to read private key? */
- EVP_PKEY *evp_key; /**< initially NULL, need to call PKCS11_load_key */
void *_private;
} PKCS11_KEY;
@@ -93,7 +92,7 @@
unsigned char soPinFinalTry;
unsigned char soPinLocked;
unsigned char soPinToBeChanged;
- void *_private;
+ struct PKCS11_slot_st *slot;
} PKCS11_TOKEN;
/** PKCS11 slot: card reader */
@@ -138,15 +137,6 @@
extern int PKCS11_CTX_load(PKCS11_CTX * ctx, const char * ident);
/**
- * Reinitialize a PKCS#11 module (after a fork)
- *
- * @param ctx context allocated by PKCS11_CTX_new()
- * @retval 0 success
- * @retval -1 error
- */
-extern int PKCS11_CTX_reload(PKCS11_CTX * ctx);
-
-/**
* Unload a PKCS#11 module
*
* @param ctx context allocated by PKCS11_CTX_new()
@@ -182,6 +172,23 @@
PKCS11_SLOT **slotsp, unsigned int *nslotsp);
/**
+ * Get or update a list of all slots
+ *
+ * The difference to PKCS11_enumerate_slots() is that this will
+ * expect as input previous slot list (or zero initialized count
+ * and null pointer) for the list. This function always reuses the
+ * slots found from the previous list to avoid unexpected slot
+ * and key object destructon.
+ * @param ctx context allocated by PKCS11_CTX_new()
+ * @param slotsp pointer on a list of slots
+ * @param nslotsp pointer to size of the allocated list
+ * @retval 0 success
+ * @retval -1 error
+ */
+extern int PKCS11_update_slots(PKCS11_CTX * ctx,
+ PKCS11_SLOT **slotsp, unsigned int *nslotsp);
+
+/**
* Get the slot_id from a slot as it is stored in private
*
* @param slotp pointer on a slot
@@ -520,13 +527,14 @@
# define CKR_F_PKCS11_PRIVATE_DECRYPT 121
# define CKR_F_PKCS11_PRIVATE_ENCRYPT 122
# define CKR_F_PKCS11_RELOAD_KEY 123
-# define CKR_F_PKCS11_REOPEN_SESSION 124
# define CKR_F_PKCS11_SEED_RANDOM 125
# define CKR_F_PKCS11_STORE_CERTIFICATE 126
# define CKR_F_PKCS11_STORE_KEY 127
# define CKR_F_PKCS11_REMOVE_KEY 128
# define CKR_F_PKCS11_REMOVE_CERTIFICATE 129
# define CKR_F_PKCS11_GENERATE_KEY 130
+# define CKR_F_PKCS11_RELOAD_CERTIFICATE 131
+# define CKR_F_PKCS11_GET_SESSION 132
/* Backward compatibility of error function codes */
#define PKCS11_F_PKCS11_CHANGE_PIN CKR_F_PKCS11_CHANGE_PIN
@@ -553,7 +561,6 @@
#define PKCS11_F_PKCS11_PRIVATE_DECRYPT CKR_F_PKCS11_PRIVATE_DECRYPT
#define PKCS11_F_PKCS11_PRIVATE_ENCRYPT CKR_F_PKCS11_PRIVATE_ENCRYPT
#define PKCS11_F_PKCS11_RELOAD_KEY CKR_F_PKCS11_RELOAD_KEY
-#define PKCS11_F_PKCS11_REOPEN_SESSION CKR_F_PKCS11_REOPEN_SESSION
#define PKCS11_F_PKCS11_SEED_RANDOM CKR_F_PKCS11_SEED_RANDOM
#define PKCS11_F_PKCS11_STORE_CERTIFICATE CKR_F_PKCS11_STORE_CERTIFICATE
#define PKCS11_F_PKCS11_STORE_KEY CKR_F_PKCS11_STORE_KEY
diff -Nru libp11-0.4.11/src/libp11-int.h libp11-0.4.12/src/libp11-int.h
--- libp11-0.4.11/src/libp11-int.h 2018-11-24 09:53:48.000000000 +0100
+++ libp11-0.4.12/src/libp11-int.h 2022-07-05 22:22:51.000000000 +0200
@@ -29,93 +29,81 @@
#define CRYPTOKI_EXPORTS
#include "pkcs11.h"
-#if OPENSSL_VERSION_NUMBER < 0x10100004L || defined(LIBRESSL_VERSION_NUMBER)
-typedef int PKCS11_RWLOCK;
-#else
-typedef CRYPTO_RWLOCK *PKCS11_RWLOCK;
-#endif
+#include "p11_pthread.h"
+
+/* forward and type declarations */
+typedef struct pkcs11_ctx_private PKCS11_CTX_private;
+typedef struct pkcs11_slot_private PKCS11_SLOT_private;
+typedef struct pkcs11_object_private PKCS11_OBJECT_private;
+typedef struct pkcs11_object_ops PKCS11_OBJECT_ops;
/* get private implementations of PKCS11 structures */
/*
* PKCS11_CTX: context for a PKCS11 implementation
*/
-typedef struct pkcs11_ctx_private {
+struct pkcs11_ctx_private {
CK_FUNCTION_LIST_PTR method;
void *handle;
char *init_args;
UI_METHOD *ui_method; /* UI_METHOD for CKU_CONTEXT_SPECIFIC PINs */
void *ui_user_data;
unsigned int forkid;
- PKCS11_RWLOCK rwlock;
- int sign_initialized;
- int decrypt_initialized;
-} PKCS11_CTX_private;
-#define PRIVCTX(ctx) ((PKCS11_CTX_private *) ((ctx)->_private))
-
-typedef struct pkcs11_slot_private {
- PKCS11_CTX *parent;
- unsigned char haveSession, loggedIn;
- CK_SLOT_ID id;
- CK_SESSION_HANDLE session;
- unsigned int forkid;
- int prev_rw; /* the rw status the session was open */
-
- /* options used in last PKCS11_login */
- char *prev_pin;
- int prev_so;
-} PKCS11_SLOT_private;
-#define PRIVSLOT(slot) ((PKCS11_SLOT_private *) ((slot)->_private))
-#define SLOT2CTX(slot) (PRIVSLOT(slot)->parent)
+ pthread_mutex_t fork_lock;
+};
+#define PRIVCTX(_ctx) ((PKCS11_CTX_private *) ((_ctx)->_private))
typedef struct pkcs11_keys {
int num;
PKCS11_KEY *keys;
} PKCS11_keys;
-typedef struct pkcs11_token_private {
- PKCS11_SLOT *parent;
+struct pkcs11_slot_private {
+ int refcnt;
+ PKCS11_CTX_private *ctx;
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+ int8_t rw_mode, logged_in;
+ CK_SLOT_ID id;
+ CK_SESSION_HANDLE *session_pool;
+ unsigned int session_head, session_tail, session_poolsize;
+ unsigned int num_sessions, max_sessions;
+ unsigned int forkid;
+
+ /* options used in last PKCS11_login */
+ char *prev_pin;
+
+ /* members concerning the token */
+ CK_BBOOL secure_login;
PKCS11_keys prv, pub;
int ncerts;
PKCS11_CERT *certs;
-} PKCS11_TOKEN_private;
-#define PRIVTOKEN(token) ((PKCS11_TOKEN_private *) ((token)->_private))
-#define TOKEN2SLOT(token) (PRIVTOKEN(token)->parent)
-#define TOKEN2CTX(token) SLOT2CTX(TOKEN2SLOT(token))
-
-typedef struct pkcs11_key_ops {
- int type; /* EVP_PKEY_xxx */
- EVP_PKEY *(*get_evp_key) (PKCS11_KEY *);
- void (*update_ex_data) (PKCS11_KEY *);
-} PKCS11_KEY_ops;
+};
+#define PRIVSLOT(_slot) ((PKCS11_SLOT_private *) ((_slot)->_private))
-typedef struct pkcs11_key_private {
- PKCS11_TOKEN *parent;
+struct pkcs11_object_private {
+ PKCS11_SLOT_private *slot;
+ CK_OBJECT_CLASS object_class;
CK_OBJECT_HANDLE object;
CK_BBOOL always_authenticate;
unsigned char id[255];
size_t id_len;
- PKCS11_KEY_ops *ops;
+ char *label;
+ PKCS11_OBJECT_ops *ops;
+ EVP_PKEY *evp_key;
+ X509 *x509;
unsigned int forkid;
-} PKCS11_KEY_private;
-#define PRIVKEY(key) ((PKCS11_KEY_private *) (key)->_private)
-#define KEY2SLOT(key) TOKEN2SLOT(KEY2TOKEN(key))
-#define KEY2TOKEN(key) (PRIVKEY(key)->parent)
-#define KEY2CTX(key) TOKEN2CTX(KEY2TOKEN(key))
+};
+#define PRIVKEY(_key) ((PKCS11_OBJECT_private *) (_key)->_private)
+#define PRIVCERT(_cert) ((PKCS11_OBJECT_private *) (_cert)->_private)
+
+struct pkcs11_object_ops {
+ int pkey_type; /* EVP_PKEY_xxx */
+ EVP_PKEY *(*get_evp_key) (PKCS11_OBJECT_private *);
+};
-typedef struct pkcs11_cert_private {
- PKCS11_TOKEN *parent;
- CK_OBJECT_HANDLE object;
- unsigned char id[255];
- size_t id_len;
-} PKCS11_CERT_private;
-#define PRIVCERT(cert) ((PKCS11_CERT_private *) (cert)->_private)
-#define CERT2SLOT(cert) TOKEN2SLOT(CERT2TOKEN(cert))
-#define CERT2TOKEN(cert) (PRIVCERT(cert)->parent)
-#define CERT2CTX(cert) TOKEN2CTX(CERT2TOKEN(cert))
-
-extern PKCS11_KEY_ops pkcs11_rsa_ops;
-extern PKCS11_KEY_ops *pkcs11_ec_ops;
+extern PKCS11_OBJECT_ops pkcs11_rsa_ops;
+extern PKCS11_OBJECT_ops pkcs11_ec_ops;
/*
* Internal functions
@@ -129,7 +117,7 @@
ERR_clear_error(); \
} while (0)
#define CRYPTOKI_call(ctx, func_and_args) \
- PRIVCTX(ctx)->method->func_and_args
+ ctx->method->func_and_args
extern int ERR_load_CKR_strings(void);
/* Memory allocation */
@@ -137,239 +125,229 @@
pkcs11_strdup((char *) s, sizeof(s))
extern char *pkcs11_strdup(char *, size_t);
-/* Emulate the OpenSSL 1.1 locking API for older OpenSSL versions */
-#if OPENSSL_VERSION_NUMBER < 0x10100004L || defined(LIBRESSL_VERSION_NUMBER)
-int CRYPTO_THREAD_lock_new();
-void CRYPTO_THREAD_lock_free(int);
-#define CRYPTO_THREAD_write_lock(type) \
- if(type) CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
-#define CRYPTO_THREAD_unlock(type) \
- if(type) CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
-#define CRYPTO_THREAD_read_lock(type) \
- if(type) CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__)
-#define CRYPTO_THREAD_read_unlock(type) \
- if(type) CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__)
-#endif
-
/* Emulate the OpenSSL 1.1 getters */
-#if OPENSSL_VERSION_NUMBER < 0x10100003L || defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER < 0x10100003L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3000000L )
#define EVP_PKEY_get0_RSA(key) ((key)->pkey.rsa)
#define EVP_PKEY_get0_EC_KEY(key) ((key)->pkey.ec)
#endif
-/* Reinitializing the module afer fork (if detected) */
+/* Reinitializing the module after fork (if detected) */
extern unsigned int get_forkid();
-extern int check_fork(PKCS11_CTX *ctx);
-extern int check_slot_fork(PKCS11_SLOT *slot);
-extern int check_token_fork(PKCS11_TOKEN *token);
-extern int check_key_fork(PKCS11_KEY *key);
-extern int check_cert_fork(PKCS11_CERT *cert);
+extern int check_fork(PKCS11_CTX_private *ctx);
+extern int check_slot_fork(PKCS11_SLOT_private *slot);
+extern int check_object_fork(PKCS11_OBJECT_private *key);
/* Other internal functions */
extern void *C_LoadModule(const char *name, CK_FUNCTION_LIST_PTR_PTR);
extern CK_RV C_UnloadModule(void *module);
-extern void pkcs11_destroy_keys(PKCS11_TOKEN *, unsigned int);
-extern void pkcs11_destroy_certs(PKCS11_TOKEN *);
-extern int pkcs11_reload_key(PKCS11_KEY *);
-extern int pkcs11_reopen_session(PKCS11_SLOT * slot);
-extern int pkcs11_relogin(PKCS11_SLOT * slot);
+extern void pkcs11_destroy_keys(PKCS11_SLOT_private *, unsigned int);
+extern void pkcs11_destroy_certs(PKCS11_SLOT_private *);
+extern int pkcs11_reload_object(PKCS11_OBJECT_private *);
+extern int pkcs11_reload_slot(PKCS11_SLOT_private *);
/* Managing object attributes */
-extern int pkcs11_getattr_var(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
- unsigned int, CK_BYTE *, size_t *);
-extern int pkcs11_getattr_val(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
- unsigned int, void *, size_t);
-extern int pkcs11_getattr_alloc(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
- unsigned int, CK_BYTE **, size_t *);
+extern int pkcs11_getattr_var(PKCS11_CTX_private *, CK_SESSION_HANDLE, CK_OBJECT_HANDLE,
+ CK_ATTRIBUTE_TYPE, CK_BYTE *, size_t *);
+extern int pkcs11_getattr_val(PKCS11_CTX_private *, CK_SESSION_HANDLE, CK_OBJECT_HANDLE,
+ CK_ATTRIBUTE_TYPE, void *, size_t);
+extern int pkcs11_getattr_alloc(PKCS11_CTX_private *, CK_SESSION_HANDLE, CK_OBJECT_HANDLE,
+ CK_ATTRIBUTE_TYPE, CK_BYTE **, size_t *);
/*
* Caution: the BIGNUM ** shall reference either a NULL pointer or a
* pointer to a valid BIGNUM.
*/
-extern int pkcs11_getattr_bn(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
- unsigned int, BIGNUM **);
-
-#define key_getattr_var(key, t, p, s) \
- pkcs11_getattr_var(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (p), (s))
+extern int pkcs11_getattr_bn(PKCS11_CTX_private *, CK_SESSION_HANDLE, CK_OBJECT_HANDLE,
+ CK_ATTRIBUTE_TYPE, BIGNUM **);
-#define key_getattr_val(key, t, p, s) \
- pkcs11_getattr_val(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (p), (s))
-
-#define key_getattr_alloc(key, t, p, s) \
- pkcs11_getattr_alloc(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (p), (s))
-
-/*
- * Caution: bn shall reference either a NULL pointer or a pointer to
- * a valid BIGNUM.
- */
-#define key_getattr_bn(key, t, bn) \
- pkcs11_getattr_bn(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (bn))
+typedef struct pkcs11_template_st {
+ unsigned long allocated;
+ unsigned int nattr;
+ CK_ATTRIBUTE attrs[32];
+} PKCS11_TEMPLATE;
typedef int (*pkcs11_i2d_fn) (void *, unsigned char **);
-extern void pkcs11_addattr(CK_ATTRIBUTE_PTR, int, const void *, size_t);
-extern void pkcs11_addattr_int(CK_ATTRIBUTE_PTR, int, unsigned long);
-extern void pkcs11_addattr_bool(CK_ATTRIBUTE_PTR, int, int);
-extern void pkcs11_addattr_s(CK_ATTRIBUTE_PTR, int, const char *);
-extern void pkcs11_addattr_bn(CK_ATTRIBUTE_PTR, int, const BIGNUM *);
-extern void pkcs11_addattr_obj(CK_ATTRIBUTE_PTR, int, pkcs11_i2d_fn, void *);
-extern void pkcs11_zap_attrs(CK_ATTRIBUTE_PTR, unsigned int);
+extern unsigned int pkcs11_addattr(PKCS11_TEMPLATE *, int, void *, size_t);
+#define pkcs11_addattr_var(_tmpl, _type, _var) pkcs11_addattr(_tmpl, _type, &(_var), sizeof(_var))
+extern void pkcs11_addattr_bool(PKCS11_TEMPLATE *, int, int);
+extern void pkcs11_addattr_s(PKCS11_TEMPLATE *, int, const char *);
+extern void pkcs11_addattr_bn(PKCS11_TEMPLATE *, int, const BIGNUM *);
+extern void pkcs11_addattr_obj(PKCS11_TEMPLATE *, int, pkcs11_i2d_fn, void *);
+extern void pkcs11_zap_attrs(PKCS11_TEMPLATE *);
/* Internal implementation of current features */
+/* Atomic reference counting */
+extern int pkcs11_atomic_add(int *, int, pthread_mutex_t *);
+
/* Allocate the context */
extern PKCS11_CTX *pkcs11_CTX_new(void);
/* Specify any private PKCS#11 module initialization args, if necessary */
-extern void pkcs11_CTX_init_args(PKCS11_CTX * ctx, const char * init_args);
+extern void pkcs11_CTX_init_args(PKCS11_CTX *ctx, const char *init_args);
/* Load a PKCS#11 module */
-extern int pkcs11_CTX_load(PKCS11_CTX * ctx, const char * ident);
+extern int pkcs11_CTX_load(PKCS11_CTX *ctx, const char *ident);
/* Reinitialize a PKCS#11 module (after a fork) */
-extern int pkcs11_CTX_reload(PKCS11_CTX * ctx);
+extern int pkcs11_CTX_reload(PKCS11_CTX_private *ctx);
/* Unload a PKCS#11 module */
-extern void pkcs11_CTX_unload(PKCS11_CTX * ctx);
+extern void pkcs11_CTX_unload(PKCS11_CTX *ctx);
/* Free a libp11 context */
-extern void pkcs11_CTX_free(PKCS11_CTX * ctx);
+extern void pkcs11_CTX_free(PKCS11_CTX *ctx);
/* Open a session in RO or RW mode */
-extern int pkcs11_open_session(PKCS11_SLOT * slot, int rw, int relogin);
+extern int pkcs11_open_session(PKCS11_SLOT_private *, int rw);
+
+/* Acquire a session from the slot specific session pool */
+extern int pkcs11_get_session(PKCS11_SLOT_private *, int rw, CK_SESSION_HANDLE *sessionp);
+
+/* Return a session the the slot specific session pool */
+extern void pkcs11_put_session(PKCS11_SLOT_private *, CK_SESSION_HANDLE session);
/* Get a list of all slots */
-extern int pkcs11_enumerate_slots(PKCS11_CTX * ctx,
+extern int pkcs11_enumerate_slots(PKCS11_CTX_private * ctx,
PKCS11_SLOT **slotsp, unsigned int *nslotsp);
/* Get the slot_id from a slot as it is stored in private */
-extern unsigned long pkcs11_get_slotid_from_slot(PKCS11_SLOT *slot);
+extern unsigned long pkcs11_get_slotid_from_slot(PKCS11_SLOT_private *);
+
+/* Increment slot reference count */
+extern PKCS11_SLOT_private *pkcs11_slot_ref(PKCS11_SLOT_private *slot);
+
+/* Decrement slot reference count, free if it becomes zero */
+extern void pkcs11_slot_unref(PKCS11_SLOT_private *slot);
/* Free the list of slots allocated by PKCS11_enumerate_slots() */
-extern void pkcs11_release_all_slots(PKCS11_CTX * ctx,
- PKCS11_SLOT *slots, unsigned int nslots);
+extern void pkcs11_release_all_slots(PKCS11_SLOT *slots, unsigned int nslots);
-/* Find the first slot with a token */
-extern PKCS11_SLOT *pkcs11_find_token(PKCS11_CTX * ctx,
- PKCS11_SLOT *slots, unsigned int nslots);
-
-/* Find the next slot with a token */
-extern PKCS11_SLOT *pkcs11_find_next_token(PKCS11_CTX * ctx,
- PKCS11_SLOT *slots, unsigned int nslots,
- PKCS11_SLOT *current);
+/* Refresh the slot's token status */
+extern int pkcs11_refresh_token(PKCS11_SLOT *slot);
/* Check if user is already authenticated to a card */
-extern int pkcs11_is_logged_in(PKCS11_SLOT * slot, int so, int * res);
+extern int pkcs11_is_logged_in(PKCS11_SLOT_private *, int so, int *res);
/* Authenticate to the card */
-extern int pkcs11_login(PKCS11_SLOT * slot, int so, const char *pin, int relogin);
+extern int pkcs11_login(PKCS11_SLOT_private *, int so, const char *pin);
/* De-authenticate from the card */
-extern int pkcs11_logout(PKCS11_SLOT * slot);
+extern int pkcs11_logout(PKCS11_SLOT_private *);
/* Authenticate a private the key operation if needed */
-int pkcs11_authenticate(PKCS11_KEY *key);
+int pkcs11_authenticate(PKCS11_OBJECT_private *key, CK_SESSION_HANDLE session);
/* Get a list of keys associated with this token */
-extern int pkcs11_enumerate_keys(PKCS11_TOKEN *token, unsigned int type,
+extern int pkcs11_enumerate_keys(PKCS11_SLOT_private *, unsigned int type,
PKCS11_KEY **keys, unsigned int *nkeys);
-/* Remove a key from the token */
-extern int pkcs11_remove_key(PKCS11_KEY *key);
+/* Create an object from a handle */
+extern PKCS11_OBJECT_private *pkcs11_object_from_handle(PKCS11_SLOT_private *slot,
+ CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object);
+
+/* Get an object based on template */
+extern PKCS11_OBJECT_private *pkcs11_object_from_template(PKCS11_SLOT_private *slot,
+ CK_SESSION_HANDLE session, PKCS11_TEMPLATE *tmpl);
+
+/* Get the corresponding object (same ID, given different object type) */
+extern PKCS11_OBJECT_private *pkcs11_object_from_object(PKCS11_OBJECT_private *obj,
+ CK_SESSION_HANDLE session, CK_OBJECT_CLASS object_class);
+
+/* Free an object */
+extern void pkcs11_object_free(PKCS11_OBJECT_private *obj);
/* Get the key type (as EVP_PKEY_XXX) */
-extern int pkcs11_get_key_type(PKCS11_KEY *key);
+extern int pkcs11_get_key_type(PKCS11_OBJECT_private *key);
-/* Returns a EVP_PKEY object with the private or public key */
-extern EVP_PKEY *pkcs11_get_key(PKCS11_KEY *key, int isPrivate);
+/* Returns a EVP_PKEY object with the given key type */
+extern EVP_PKEY *pkcs11_get_key(PKCS11_OBJECT_private *key, CK_OBJECT_CLASS obj_class);
/* Find the corresponding certificate (if any) */
-extern PKCS11_CERT *pkcs11_find_certificate(PKCS11_KEY *key);
+extern PKCS11_CERT *pkcs11_find_certificate(PKCS11_OBJECT_private *key);
/* Find the corresponding key (if any) */
-extern PKCS11_KEY *pkcs11_find_key(PKCS11_CERT *cert);
-
-/* Find the corresponding key (if any) pub <-> priv base on ID */
-extern PKCS11_KEY *pkcs11_find_key_from_key(PKCS11_KEY *key);
+extern PKCS11_KEY *pkcs11_find_key(PKCS11_OBJECT_private *cert);
/* Get a list of all certificates associated with this token */
-extern int pkcs11_enumerate_certs(PKCS11_TOKEN *token,
+extern int pkcs11_enumerate_certs(PKCS11_SLOT_private *,
PKCS11_CERT **certs, unsigned int *ncerts);
-/* Remove a certificate from the token */
-extern int pkcs11_remove_certificate(PKCS11_CERT *key);
+/* Remove an object from the token */
+extern int pkcs11_remove_object(PKCS11_OBJECT_private *object);
/* Set UI method to allow retrieving CKU_CONTEXT_SPECIFIC PINs interactively */
-extern int pkcs11_set_ui_method(PKCS11_CTX *ctx,
+extern int pkcs11_set_ui_method(PKCS11_CTX_private *ctx,
UI_METHOD *ui_method, void *ui_user_data);
/* Initialize a token */
-extern int pkcs11_init_token(PKCS11_TOKEN * token, const char *pin,
+extern int pkcs11_init_token(PKCS11_SLOT_private *, const char *pin,
const char *label);
/* Initialize the user PIN on a token */
-extern int pkcs11_init_pin(PKCS11_TOKEN * token, const char *pin);
+extern int pkcs11_init_pin(PKCS11_SLOT_private *, const char *pin);
/* Change the user PIN on a token */
-extern int pkcs11_change_pin(PKCS11_SLOT * slot,
+extern int pkcs11_change_pin(PKCS11_SLOT_private *,
const char *old_pin, const char *new_pin);
/* Store private key on a token */
-extern int pkcs11_store_private_key(PKCS11_TOKEN * token,
- EVP_PKEY * pk, char *label, unsigned char *id, size_t id_len);
+extern int pkcs11_store_private_key(PKCS11_SLOT_private *,
+ EVP_PKEY *pk, char *label, unsigned char *id, size_t id_len);
/* Store public key on a token */
-extern int pkcs11_store_public_key(PKCS11_TOKEN * token,
- EVP_PKEY * pk, char *label, unsigned char *id, size_t id_len);
+extern int pkcs11_store_public_key(PKCS11_SLOT_private *,
+ EVP_PKEY *pk, char *label, unsigned char *id, size_t id_len);
/* Store certificate on a token */
-extern int pkcs11_store_certificate(PKCS11_TOKEN * token, X509 * x509,
+extern int pkcs11_store_certificate(PKCS11_SLOT_private *, X509 * x509,
char *label, unsigned char *id, size_t id_len,
PKCS11_CERT **ret_cert);
/* Access the random number generator */
-extern int pkcs11_seed_random(PKCS11_SLOT *, const unsigned char *s, unsigned int s_len);
-extern int pkcs11_generate_random(PKCS11_SLOT *, unsigned char *r, unsigned int r_len);
+extern int pkcs11_seed_random(PKCS11_SLOT_private *, const unsigned char *s, unsigned int s_len);
+extern int pkcs11_generate_random(PKCS11_SLOT_private *, unsigned char *r, unsigned int r_len);
/* Internal implementation of deprecated features */
/* Generate and store a private key on the token */
-extern int pkcs11_generate_key(PKCS11_TOKEN * token,
+extern int pkcs11_generate_key(PKCS11_SLOT_private *tpriv,
int algorithm, unsigned int bits,
char *label, unsigned char* id, size_t id_len);
/* Get the RSA key modulus size (in bytes) */
-extern int pkcs11_get_key_size(PKCS11_KEY *);
+extern int pkcs11_get_key_size(PKCS11_OBJECT_private *);
/* Get the RSA key modules as BIGNUM */
-extern int pkcs11_get_key_modulus(PKCS11_KEY *, BIGNUM **);
+extern int pkcs11_get_key_modulus(PKCS11_OBJECT_private *, BIGNUM **);
/* Get the RSA key public exponent as BIGNUM */
-extern int pkcs11_get_key_exponent(PKCS11_KEY *, BIGNUM **);
+extern int pkcs11_get_key_exponent(PKCS11_OBJECT_private *, BIGNUM **);
/* Sign with the RSA private key */
extern int pkcs11_sign(int type,
const unsigned char *m, unsigned int m_len,
- unsigned char *sigret, unsigned int *siglen, PKCS11_KEY * key);
+ unsigned char *sigret, unsigned int *siglen, PKCS11_OBJECT_private *key);
/* This function has never been implemented */
extern int pkcs11_verify(int type,
const unsigned char *m, unsigned int m_len,
- unsigned char *signature, unsigned int siglen, PKCS11_KEY * key);
+ unsigned char *signature, unsigned int siglen, PKCS11_OBJECT_private *key);
/* Encrypts data using the private key */
extern int pkcs11_private_encrypt(
int flen, const unsigned char *from,
- unsigned char *to, PKCS11_KEY * rsa, int padding);
+ unsigned char *to, PKCS11_OBJECT_private *rsa, int padding);
/* Decrypts data using the private key */
extern int pkcs11_private_decrypt(
int flen, const unsigned char *from,
- unsigned char *to, PKCS11_KEY * key, int padding);
+ unsigned char *to, PKCS11_OBJECT_private *key, int padding);
/* Retrieve PKCS11_KEY from an RSA key */
-extern PKCS11_KEY *pkcs11_get_ex_data_rsa(const RSA *rsa);
+extern PKCS11_OBJECT_private *pkcs11_get_ex_data_rsa(const RSA *rsa);
/* Retrieve PKCS11_KEY from an EC_KEY */
-extern PKCS11_KEY *pkcs11_get_ex_data_ec(const EC_KEY *ec);
+extern PKCS11_OBJECT_private *pkcs11_get_ex_data_ec(const EC_KEY *ec);
#endif
diff -Nru libp11-0.4.11/src/libp11.rc libp11-0.4.12/src/libp11.rc
--- libp11-0.4.11/src/libp11.rc 2020-10-11 17:18:12.000000000 +0200
+++ libp11-0.4.12/src/libp11.rc 2022-07-15 21:56:30.000000000 +0200
@@ -1,8 +1,8 @@
#include <winresrc.h>
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 7,4,3,0
- PRODUCTVERSION 0,4,11,0
+ FILEVERSION 8,5,0,0
+ PRODUCTVERSION 0,4,12,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x21L
@@ -20,14 +20,14 @@
VALUE "Comments", "Provided under the terms of the GNU General Public License (LGPLv2.1+).\0"
VALUE "CompanyName", "OpenSC Project\0"
VALUE "FileDescription", "PKCS#11 access library\0"
- VALUE "FileVersion", "7.4.3.0\0"
+ VALUE "FileVersion", "8.5.0.0\0"
VALUE "InternalName", "libp11\0"
VALUE "LegalCopyright", "OpenSC Project\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "libp11-3.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "libp11\0"
- VALUE "ProductVersion", "0.4.11.0\0"
+ VALUE "ProductVersion", "0.4.12.0\0"
VALUE "SpecialBuild", "\0"
END
END
diff -Nru libp11-0.4.11/src/Makefile.am libp11-0.4.12/src/Makefile.am
--- libp11-0.4.11/src/Makefile.am 2018-08-29 23:42:21.000000000 +0200
+++ libp11-0.4.12/src/Makefile.am 2022-03-15 18:13:43.000000000 +0100
@@ -4,7 +4,7 @@
CLEANFILES = libp11.pc
EXTRA_DIST = Makefile.mak libp11.rc.in pkcs11.rc.in
-noinst_HEADERS= libp11-int.h pkcs11.h
+noinst_HEADERS= libp11-int.h pkcs11.h p11_pthread.h
include_HEADERS= libp11.h p11_err.h
lib_LTLIBRARIES = libp11.la
enginesexec_LTLIBRARIES = pkcs11.la
diff -Nru libp11-0.4.11/src/Makefile.in libp11-0.4.12/src/Makefile.in
--- libp11-0.4.11/src/Makefile.in 2020-10-11 15:46:57.000000000 +0200
+++ libp11-0.4.12/src/Makefile.in 2022-07-15 21:56:27.000000000 +0200
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.2 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -90,6 +90,7 @@
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+target_triplet = @target@
@WIN32_TRUE at am__append_1 = libp11.rc
@HAVE_LD_VERSION_SCRIPT_TRUE at am__append_2 = -Wl,--version-script=libp11.map
@HAVE_LD_VERSION_SCRIPT_TRUE@@WIN32_TRUE at am__append_3 = -export-symbols "$(srcdir)/libp11.exports"
@@ -97,7 +98,8 @@
@WIN32_TRUE at am__append_5 = pkcs11.rc
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ld-version-script.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \
+ $(top_srcdir)/m4/ld-version-script.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -253,8 +255,6 @@
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(srcdir)/libp11.pc.in $(srcdir)/libp11.rc.in \
$(srcdir)/pkcs11.rc.in $(top_srcdir)/depcomp
@@ -273,6 +273,8 @@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
@@ -284,6 +286,7 @@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
+ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
@@ -330,6 +333,10 @@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_CXX = @PTHREAD_CXX@
+PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
RC = @RC@
SED = @SED@
@@ -352,6 +359,7 @@
am__tar = @am__tar@
am__untar = @am__untar@
apidocdir = @apidocdir@
+ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -391,7 +399,11 @@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
+target = @target@
target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@@ -399,7 +411,7 @@
DISTCLEANFILES = libp11.map
CLEANFILES = libp11.pc
EXTRA_DIST = Makefile.mak libp11.rc.in pkcs11.rc.in
-noinst_HEADERS = libp11-int.h pkcs11.h
+noinst_HEADERS = libp11-int.h pkcs11.h p11_pthread.h
include_HEADERS = libp11.h p11_err.h
lib_LTLIBRARIES = libp11.la
enginesexec_LTLIBRARIES = pkcs11.la
@@ -865,7 +877,6 @@
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
diff -Nru libp11-0.4.11/src/p11_atfork.c libp11-0.4.12/src/p11_atfork.c
--- libp11-0.4.11/src/p11_atfork.c 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/src/p11_atfork.c 2022-05-04 18:45:56.000000000 +0200
@@ -23,81 +23,67 @@
#include "libp11-int.h"
#ifndef _WIN32
-#include <unistd.h>
-
-#ifndef __STDC_VERSION__
-/* older than C90 */
-#define inline
-#endif /* __STDC_VERSION__ */
-
-#ifdef HAVE___REGISTER_ATFORK
-
-#ifdef __sun
-#pragma fini(lib_deinit)
-#pragma init(lib_init)
-#define _CONSTRUCTOR
-#define _DESTRUCTOR
-#else /* __sun */
-#define _CONSTRUCTOR __attribute__((constructor))
-#define _DESTRUCTOR __attribute__((destructor))
-#endif /* __sun */
static unsigned int P11_forkid = 0;
-inline static unsigned int _P11_get_forkid(void)
-{
- return P11_forkid;
-}
+#ifdef HAVE_PTHREAD
-inline static int _P11_detect_fork(unsigned int forkid)
-{
- if (forkid == P11_forkid)
- return 0;
- return 1;
-}
+#include <pthread.h>
-static void fork_handler(void)
+static void _P11_atfork_child(void)
{
P11_forkid++;
}
-extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
-extern void *__dso_handle;
-
-_CONSTRUCTOR
+__attribute__((constructor))
int _P11_register_fork_handler(void)
{
- if (__register_atfork(0, 0, fork_handler, __dso_handle) != 0)
+ if (pthread_atfork(0, 0, _P11_atfork_child) != 0)
return -1;
return 0;
}
-#else /* HAVE___REGISTER_ATFORK */
-
-inline static unsigned int _P11_get_forkid(void)
+static unsigned int _P11_update_forkid(void)
{
- return getpid();
+ return P11_forkid;
}
-inline static int _P11_detect_fork(unsigned int forkid)
+#else /* HAVE_PTHREAD */
+
+#include <unistd.h>
+
+static unsigned int _P11_update_forkid(void)
{
- if (getpid() == forkid)
- return 0;
- return 1;
+ P11_forkid = (unsigned int)getpid();
+ return P11_forkid;
}
-#endif /* HAVE___REGISTER_ATFORK */
+#endif /* HAVE_PTHREAD */
+
+#define CHECK_FORKID(ctx, forkid, function_call) \
+ do { \
+ int rv = 0; \
+ _P11_update_forkid(); \
+ if (forkid != P11_forkid) { \
+ pthread_mutex_lock(&ctx->fork_lock); \
+ function_call; \
+ pthread_mutex_unlock(&ctx->fork_lock); \
+ } \
+ return rv; \
+ } while (0)
#else /* !_WIN32 */
-#define _P11_get_forkid() 0
-#define _P11_detect_fork(x) 0
+#define P11_forkid 0
+#define _P11_update_forkid() 0
+#define CHECK_FORKID(ctx, forkid, function_call) return 0
#endif /* !_WIN32 */
unsigned int get_forkid()
{
- return _P11_get_forkid();
+ _P11_update_forkid();
+ return P11_forkid;
}
/*
@@ -105,14 +91,12 @@
* It wipes out the internal state of the PKCS#11 library
* Any libp11 references to this state are no longer valid
*/
-static int check_fork_int(PKCS11_CTX *ctx)
+static int check_fork_int(PKCS11_CTX_private *ctx)
{
- PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
-
- if (_P11_detect_fork(cpriv->forkid)) {
+ if (ctx->forkid != P11_forkid) {
if (pkcs11_CTX_reload(ctx) < 0)
return -1;
- cpriv->forkid = _P11_get_forkid();
+ ctx->forkid = P11_forkid;
}
return 0;
}
@@ -121,48 +105,35 @@
* PKCS#11 reinitialization after fork
* Also relogins and reopens the session if needed
*/
-static int check_slot_fork_int(PKCS11_SLOT *slot)
+static int check_slot_fork_int(PKCS11_SLOT_private *slot)
{
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
-
- if (check_fork_int(SLOT2CTX(slot)) < 0)
- return -1;
- if (spriv->forkid != cpriv->forkid) {
- if (spriv->loggedIn) {
- int saved = spriv->haveSession;
- spriv->haveSession = 0;
- spriv->loggedIn = 0;
- if (pkcs11_relogin(slot) < 0)
- return -1;
- spriv->haveSession = saved;
- }
- if (spriv->haveSession) {
- spriv->haveSession = 0;
- if (pkcs11_reopen_session(slot) < 0)
- return -1;
- }
- spriv->forkid = cpriv->forkid;
+ PKCS11_CTX_private *ctx = slot->ctx;
+
+ if (check_fork_int(ctx) < 0)
+ return -1;
+ if (slot->forkid != ctx->forkid) {
+ if (pkcs11_reload_slot(slot) < 0)
+ return -1;
+ slot->forkid = ctx->forkid;
}
return 0;
}
/*
* PKCS#11 reinitialization after fork
- * Also reloads the key
+ * Also reloads the object
*/
-static int check_key_fork_int(PKCS11_KEY *key)
+static int check_object_fork_int(PKCS11_OBJECT_private *obj)
{
- PKCS11_SLOT *slot = KEY2SLOT(key);
- PKCS11_KEY_private *kpriv = PRIVKEY(key);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_SLOT_private *slot = obj->slot;
if (check_slot_fork_int(slot) < 0)
return -1;
- if (spriv->forkid != kpriv->forkid) {
- pkcs11_reload_key(key);
- kpriv->forkid = spriv->forkid;
+
+ if (slot->forkid != obj->forkid) {
+ if (pkcs11_reload_object(obj) < 0)
+ return -1;
+ obj->forkid = slot->forkid;
}
return 0;
}
@@ -170,72 +141,31 @@
/*
* Locking interface to check_fork_int()
*/
-int check_fork(PKCS11_CTX *ctx)
+int check_fork(PKCS11_CTX_private *ctx)
{
- PKCS11_CTX_private *cpriv;
- int rv;
-
if (!ctx)
return -1;
- cpriv = PRIVCTX(ctx);
- CRYPTO_THREAD_write_lock(cpriv->rwlock);
- rv = check_fork_int(ctx);
- CRYPTO_THREAD_unlock(cpriv->rwlock);
- return rv;
+ CHECK_FORKID(ctx, ctx->forkid, check_fork_int(ctx));
}
/*
* Locking interface to check_slot_fork_int()
*/
-int check_slot_fork(PKCS11_SLOT *slot)
+int check_slot_fork(PKCS11_SLOT_private *slot)
{
- PKCS11_CTX_private *cpriv;
- int rv;
-
if (!slot)
return -1;
- cpriv = PRIVCTX(SLOT2CTX(slot));
- CRYPTO_THREAD_write_lock(cpriv->rwlock);
- rv = check_slot_fork_int(slot);
- CRYPTO_THREAD_unlock(cpriv->rwlock);
- return rv;
-}
-
-/*
- * Reinitialize token (just its slot)
- */
-int check_token_fork(PKCS11_TOKEN *token)
-{
- if (!token)
- return -1;
- return check_slot_fork(TOKEN2SLOT(token));
-}
-
-/*
- * Locking interface to check_key_fork_int()
- */
-int check_key_fork(PKCS11_KEY *key)
-{
- PKCS11_CTX_private *cpriv;
- int rv;
-
- if (!key)
- return -1;
- cpriv = PRIVCTX(KEY2CTX(key));
- CRYPTO_THREAD_write_lock(cpriv->rwlock);
- rv = check_key_fork_int(key);
- CRYPTO_THREAD_unlock(cpriv->rwlock);
- return rv;
+ CHECK_FORKID(slot->ctx, slot->forkid, check_slot_fork_int(slot));
}
/*
- * Reinitialize cert (just its token)
+ * Locking interface to check_object_fork_int()
*/
-int check_cert_fork(PKCS11_CERT *cert)
+int check_object_fork(PKCS11_OBJECT_private *obj)
{
- if (!cert)
+ if (!obj)
return -1;
- return check_token_fork(CERT2TOKEN(cert));
+ CHECK_FORKID(obj->slot->ctx, obj->forkid, check_object_fork_int(obj));
}
/* vim: set noexpandtab: */
diff -Nru libp11-0.4.11/src/p11_attr.c libp11-0.4.12/src/p11_attr.c
--- libp11-0.4.11/src/p11_attr.c 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/src/p11_attr.c 2022-05-04 18:45:56.000000000 +0200
@@ -33,9 +33,9 @@
/*
* Query pkcs11 attributes
*/
-static int pkcs11_getattr_int(PKCS11_CTX *ctx, CK_SESSION_HANDLE session,
- CK_OBJECT_HANDLE o, CK_ATTRIBUTE_TYPE type, CK_BYTE *value,
- size_t *size)
+int pkcs11_getattr_var(PKCS11_CTX_private *ctx, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object, CK_ATTRIBUTE_TYPE type,
+ CK_BYTE *value, size_t *size)
{
CK_ATTRIBUTE templ;
int rv;
@@ -43,35 +43,27 @@
templ.type = type;
templ.pValue = value;
templ.ulValueLen = *size;
-
- rv = CRYPTOKI_call(ctx, C_GetAttributeValue(session, o, &templ, 1));
+ rv = CRYPTOKI_call(ctx, C_GetAttributeValue(session, object, &templ, 1));
CRYPTOKI_checkerr(CKR_F_PKCS11_GETATTR_INT, rv);
-
*size = templ.ulValueLen;
return 0;
}
-int pkcs11_getattr_var(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
- unsigned int type, CK_BYTE *value, size_t *size)
-{
- return pkcs11_getattr_int(TOKEN2CTX(token),
- PRIVSLOT(TOKEN2SLOT(token))->session,
- object, type, value, size);
-}
-
-int pkcs11_getattr_val(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
- unsigned int type, void *value, size_t size)
+int pkcs11_getattr_val(PKCS11_CTX_private *ctx, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object, CK_ATTRIBUTE_TYPE type,
+ void *value, size_t size)
{
- return pkcs11_getattr_var(token, object, type, value, &size);
+ return pkcs11_getattr_var(ctx, session, object, type, value, &size);
}
-int pkcs11_getattr_alloc(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
- unsigned int type, CK_BYTE **value, size_t *size)
+int pkcs11_getattr_alloc(PKCS11_CTX_private *ctx, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object, CK_ATTRIBUTE_TYPE type,
+ CK_BYTE **value, size_t *size)
{
CK_BYTE *data;
size_t len = 0;
- if (pkcs11_getattr_var(token, object, type, NULL, &len))
+ if (pkcs11_getattr_var(ctx, session, object, type, NULL, &len))
return -1;
data = OPENSSL_malloc(len+1);
if (!data) {
@@ -79,7 +71,7 @@
return -1;
}
memset(data, 0, len+1); /* also null-terminate the allocated data */
- if (pkcs11_getattr_var(token, object, type, data, &len)) {
+ if (pkcs11_getattr_var(ctx, session, object, type, data, &len)) {
OPENSSL_free(data);
return -1;
}
@@ -90,14 +82,14 @@
return 0;
}
-int pkcs11_getattr_bn(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
- unsigned int type, BIGNUM **bn)
+int pkcs11_getattr_bn(PKCS11_CTX_private *ctx, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object, CK_ATTRIBUTE_TYPE type, BIGNUM **bn)
{
CK_BYTE *binary;
size_t size;
size = 0;
- if (pkcs11_getattr_alloc(token, object, type, &binary, &size))
+ if (pkcs11_getattr_alloc(ctx, session, object, type, &binary, &size))
return -1;
/*
* @ALON: invalid object,
@@ -116,63 +108,68 @@
/*
* Add attributes to template
*/
-void pkcs11_addattr(CK_ATTRIBUTE_PTR ap, int type, const void *data, size_t size)
+unsigned int pkcs11_addattr(PKCS11_TEMPLATE *tmpl, int type, void *data, size_t size)
{
+ unsigned int n = tmpl->nattr;
+ CK_ATTRIBUTE_PTR ap;
+
+ assert(tmpl->nattr < sizeof(tmpl->attrs)/sizeof(tmpl->attrs[0]));
+ ap = &tmpl->attrs[tmpl->nattr++];
ap->type = type;
- ap->pValue = OPENSSL_malloc(size);
- if (!ap->pValue)
- return;
- memcpy(ap->pValue, data, size);
+ ap->pValue = data;
ap->ulValueLen = size;
+ return n;
}
-/* In PKCS11, virtually every integer is a CK_ULONG */
-void pkcs11_addattr_int(CK_ATTRIBUTE_PTR ap, int type, unsigned long value)
+void pkcs11_addattr_bool(PKCS11_TEMPLATE *tmpl, int type, int value)
{
- CK_ULONG ulValue = value;
-
- pkcs11_addattr(ap, type, &ulValue, sizeof(ulValue));
+ static CK_BBOOL true = CK_TRUE;
+ static CK_BBOOL false = CK_FALSE;
+ pkcs11_addattr(tmpl, type, value ? &true : &false, sizeof(CK_BBOOL));
}
-void pkcs11_addattr_bool(CK_ATTRIBUTE_PTR ap, int type, int value)
+void pkcs11_addattr_s(PKCS11_TEMPLATE *tmpl, int type, const char *s)
{
- pkcs11_addattr(ap, type, &value, sizeof(CK_BBOOL));
+ pkcs11_addattr(tmpl, type, (void*) s, s ? strlen(s) : 0);
}
-void pkcs11_addattr_s(CK_ATTRIBUTE_PTR ap, int type, const char *s)
+void pkcs11_addattr_bn(PKCS11_TEMPLATE *tmpl, int type, const BIGNUM *bn)
{
- pkcs11_addattr(ap, type, s, s ? strlen(s) : 0); /* RFC2279 string an unpadded string of CK_UTF8CHARs with no null-termination */
-}
+ int n = BN_num_bytes(bn);
+ uint8_t *buf = OPENSSL_malloc(n);
+ unsigned int i;
-void pkcs11_addattr_bn(CK_ATTRIBUTE_PTR ap, int type, const BIGNUM *bn)
-{
- unsigned char temp[1024];
- unsigned int n;
-
- assert((size_t)BN_num_bytes(bn) <= sizeof(temp));
- n = BN_bn2bin(bn, temp);
- pkcs11_addattr(ap, type, temp, n);
+ if (buf && BN_bn2bin(bn, buf) == n) {
+ i = pkcs11_addattr(tmpl, type, buf, n);
+ tmpl->allocated |= 1<<i;
+ }
}
-void pkcs11_addattr_obj(CK_ATTRIBUTE_PTR ap, int type, pkcs11_i2d_fn enc, void *obj)
+void pkcs11_addattr_obj(PKCS11_TEMPLATE *tmpl, int type, pkcs11_i2d_fn enc, void *obj)
{
- unsigned char *p;
-
- ap->type = type;
- ap->ulValueLen = enc(obj, NULL);
- ap->pValue = OPENSSL_malloc(ap->ulValueLen);
- if (!ap->pValue)
- return;
- p = ap->pValue;
- enc(obj, &p);
+ unsigned char *buf, *p;
+ unsigned int i;
+ size_t n;
+
+ n = enc(obj, NULL);
+ buf = p = OPENSSL_malloc(n);
+ if (n && p) {
+ enc(obj, &p);
+ i = pkcs11_addattr(tmpl, type, buf, n);
+ tmpl->allocated |= 1<<i;
+ }
}
-void pkcs11_zap_attrs(CK_ATTRIBUTE_PTR ap, unsigned int n)
+void pkcs11_zap_attrs(PKCS11_TEMPLATE *tmpl)
{
- while (n--) {
- if (ap[n].pValue)
- OPENSSL_free(ap[n].pValue);
+ if (!tmpl->allocated)
+ return;
+ for (unsigned i = 0; i < 32; i++) {
+ if (tmpl->allocated & (1<<i))
+ OPENSSL_free(tmpl->attrs[i].pValue);
}
+ tmpl->allocated = 0;
+ tmpl->nattr = 0;
}
/* vim: set noexpandtab: */
diff -Nru libp11-0.4.11/src/p11_cert.c libp11-0.4.12/src/p11_cert.c
--- libp11-0.4.11/src/p11_cert.c 2020-05-18 08:47:22.000000000 +0200
+++ libp11-0.4.12/src/p11_cert.c 2022-07-05 22:22:51.000000000 +0200
@@ -26,107 +26,51 @@
#include "libp11-int.h"
#include <string.h>
-static int pkcs11_find_certs(PKCS11_TOKEN *);
-static int pkcs11_next_cert(PKCS11_CTX *, PKCS11_TOKEN *, CK_SESSION_HANDLE);
-static int pkcs11_init_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
- CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o, PKCS11_CERT **);
+static int pkcs11_find_certs(PKCS11_SLOT_private *, CK_SESSION_HANDLE);
+static int pkcs11_next_cert(PKCS11_CTX_private *, PKCS11_SLOT_private *, CK_SESSION_HANDLE);
+static int pkcs11_init_cert(PKCS11_SLOT_private *token, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE o, PKCS11_CERT **);
/*
* Enumerate all certs on the card
*/
-int pkcs11_enumerate_certs(PKCS11_TOKEN *token,
- PKCS11_CERT **certp, unsigned int *countp)
+int pkcs11_enumerate_certs(PKCS11_SLOT_private *slot, PKCS11_CERT **certp, unsigned int *countp)
{
- PKCS11_SLOT *slot = TOKEN2SLOT(token);
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
- PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
+ CK_SESSION_HANDLE session;
int rv;
- /* Make sure we have a session */
- if (!spriv->haveSession && PKCS11_open_session(slot, 0))
+ if (pkcs11_get_session(slot, 0, &session))
return -1;
- CRYPTO_THREAD_write_lock(cpriv->rwlock);
- rv = pkcs11_find_certs(token);
- CRYPTO_THREAD_unlock(cpriv->rwlock);
+ rv = pkcs11_find_certs(slot, session);
+ pkcs11_put_session(slot, session);
if (rv < 0) {
- pkcs11_destroy_certs(token);
+ pkcs11_destroy_certs(slot);
return -1;
}
if (certp)
- *certp = tpriv->certs;
+ *certp = slot->certs;
if (countp)
- *countp = tpriv->ncerts;
- return 0;
-}
-
-/**
- * Remove a certificate from the associated token
- */
-int pkcs11_remove_certificate(PKCS11_CERT *cert){
- PKCS11_SLOT *slot = CERT2SLOT(cert);
- PKCS11_CTX *ctx = CERT2CTX(cert);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
- CK_OBJECT_HANDLE obj;
- CK_ULONG count;
- CK_ATTRIBUTE search_parameters[32];
- unsigned int n = 0;
- int rv;
-
- /* First, make sure we have a session */
- if (!spriv->haveSession && PKCS11_open_session(slot, 1)){
- return -1;
- }
-
- pkcs11_addattr_int(search_parameters + n++, CKA_CLASS, CKO_CERTIFICATE);
- if (cert->id && cert->id_len){
- pkcs11_addattr(search_parameters + n++, CKA_ID, cert->id, cert->id_len);
- }
- if (cert->label){
- pkcs11_addattr_s(search_parameters + n++, CKA_LABEL, cert->label);
- }
-
- rv = CRYPTOKI_call(ctx,
- C_FindObjectsInit(spriv->session, search_parameters, n));
- CRYPTOKI_checkerr(CKR_F_PKCS11_REMOVE_CERTIFICATE, rv);
-
- rv = CRYPTOKI_call(ctx, C_FindObjects(spriv->session, &obj, 1, &count));
- CRYPTOKI_checkerr(CKR_F_PKCS11_REMOVE_CERTIFICATE, rv);
-
- CRYPTOKI_call(ctx, C_FindObjectsFinal(spriv->session));
- if (count!=1){
- pkcs11_zap_attrs(search_parameters, n);
- return -1;
- }
- rv = CRYPTOKI_call(ctx, C_DestroyObject(spriv->session, obj));
- if (rv != CKR_OK){
- pkcs11_zap_attrs(search_parameters, n);
- return -1;
- }
- pkcs11_zap_attrs(search_parameters, n);
+ *countp = slot->ncerts;
return 0;
}
/*
* Find certificate matching a key
*/
-PKCS11_CERT *pkcs11_find_certificate(PKCS11_KEY *key)
+PKCS11_CERT *pkcs11_find_certificate(PKCS11_OBJECT_private *key)
{
- PKCS11_KEY_private *kpriv;
- PKCS11_CERT_private *cpriv;
+ PKCS11_OBJECT_private *cpriv;
PKCS11_CERT *cert;
unsigned int n, count;
- kpriv = PRIVKEY(key);
- if (PKCS11_enumerate_certs(KEY2TOKEN(key), &cert, &count))
+ if (pkcs11_enumerate_certs(key->slot, &cert, &count))
return NULL;
for (n = 0; n < count; n++, cert++) {
cpriv = PRIVCERT(cert);
- if (cpriv->id_len == kpriv->id_len
- && !memcmp(cpriv->id, kpriv->id, kpriv->id_len))
+ if (cpriv->id_len == key->id_len
+ && !memcmp(cpriv->id, key->id, key->id_len))
return cert;
}
return NULL;
@@ -135,11 +79,9 @@
/*
* Find all certs of a given type (public or private)
*/
-static int pkcs11_find_certs(PKCS11_TOKEN *token)
+static int pkcs11_find_certs(PKCS11_SLOT_private *slot, CK_SESSION_HANDLE session)
{
- PKCS11_SLOT *slot = TOKEN2SLOT(token);
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_CTX_private *ctx = slot->ctx;
CK_OBJECT_CLASS cert_search_class;
CK_ATTRIBUTE cert_search_attrs[] = {
{CKA_CLASS, &cert_search_class, sizeof(cert_search_class)},
@@ -148,19 +90,19 @@
/* Tell the PKCS11 lib to enumerate all matching objects */
cert_search_class = CKO_CERTIFICATE;
- rv = CRYPTOKI_call(ctx, C_FindObjectsInit(spriv->session, cert_search_attrs, 1));
+ rv = CRYPTOKI_call(ctx, C_FindObjectsInit(session, cert_search_attrs, 1));
CRYPTOKI_checkerr(CKR_F_PKCS11_FIND_CERTS, rv);
do {
- res = pkcs11_next_cert(ctx, token, spriv->session);
+ res = pkcs11_next_cert(ctx, slot, session);
} while (res == 0);
- CRYPTOKI_call(ctx, C_FindObjectsFinal(spriv->session));
+ CRYPTOKI_call(ctx, C_FindObjectsFinal(session));
return (res < 0) ? -1 : 0;
}
-static int pkcs11_next_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
+static int pkcs11_next_cert(PKCS11_CTX_private *ctx, PKCS11_SLOT_private *slot,
CK_SESSION_HANDLE session)
{
CK_OBJECT_HANDLE obj;
@@ -174,73 +116,50 @@
if (count == 0)
return 1;
- if (pkcs11_init_cert(ctx, token, session, obj, NULL))
+ if (pkcs11_init_cert(slot, session, obj, NULL))
return -1;
return 0;
}
-static int pkcs11_init_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
- CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj, PKCS11_CERT ** ret)
+static int pkcs11_init_cert(PKCS11_SLOT_private *slot, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object, PKCS11_CERT ** ret)
{
- PKCS11_TOKEN_private *tpriv;
- PKCS11_CERT_private *cpriv;
+ PKCS11_OBJECT_private *cpriv;
PKCS11_CERT *cert, *tmp;
- unsigned char *data;
- CK_CERTIFICATE_TYPE cert_type;
- size_t size;
int i;
- (void)ctx;
- (void)session;
-
- /* Ignore unknown certificate types */
- size = sizeof(CK_CERTIFICATE_TYPE);
- if (pkcs11_getattr_var(token, obj, CKA_CERTIFICATE_TYPE, (CK_BYTE *)&cert_type, &size))
- return -1;
- if (cert_type != CKC_X_509)
- return 0;
-
/* Prevent re-adding existing PKCS#11 object handles */
/* TODO: Rewrite the O(n) algorithm as O(log n),
* or it may be too slow with a large number of certificates */
- for (i=0; i < PRIVTOKEN(token)->ncerts; ++i)
- if (PRIVCERT(PRIVTOKEN(token)->certs + i)->object == obj)
+ for (i = 0; i < slot->ncerts; ++i) {
+ if (PRIVCERT(&slot->certs[i])->object == object) {
+ if (ret)
+ *ret = &slot->certs[i];
return 0;
+ }
+ }
- /* Allocate memory */
- cpriv = OPENSSL_malloc(sizeof(PKCS11_CERT_private));
+ cpriv = pkcs11_object_from_handle(slot, session, object);
if (!cpriv)
return -1;
- memset(cpriv, 0, sizeof(PKCS11_CERT_private));
- tpriv = PRIVTOKEN(token);
- tmp = OPENSSL_realloc(tpriv->certs,
- (tpriv->ncerts + 1) * sizeof(PKCS11_CERT));
- if (!tmp)
+
+ /* Allocate memory */
+ tmp = OPENSSL_realloc(slot->certs, (slot->ncerts + 1) * sizeof(PKCS11_CERT));
+ if (!tmp) {
+ pkcs11_object_free(cpriv);
return -1;
- tpriv->certs = tmp;
- cert = tpriv->certs + tpriv->ncerts++;
+ }
+ slot->certs = tmp;
+ cert = slot->certs + slot->ncerts++;
memset(cert, 0, sizeof(PKCS11_CERT));
/* Fill public properties */
- pkcs11_getattr_alloc(token, obj, CKA_LABEL, (CK_BYTE **)&cert->label, NULL);
- size = 0;
- if (!pkcs11_getattr_alloc(token, obj, CKA_VALUE, &data, &size)) {
- const unsigned char *p = data;
-
- cert->x509 = d2i_X509(NULL, &p, (long)size);
- OPENSSL_free(data);
- }
- cert->id_len = 0;
- pkcs11_getattr_alloc(token, obj, CKA_ID, &cert->id, &cert->id_len);
-
- /* Fill private properties */
+ cert->id = cpriv->id;
+ cert->id_len = cpriv->id_len;
+ cert->label = cpriv->label;
+ cert->x509 = cpriv->x509;
cert->_private = cpriv;
- cpriv->object = obj;
- cpriv->parent = token;
- cpriv->id_len = sizeof cpriv->id;
- if (pkcs11_getattr_var(token, obj, CKA_ID, cpriv->id, &cpriv->id_len))
- cpriv->id_len = 0;
if (ret)
*ret = cert;
@@ -250,68 +169,63 @@
/*
* Destroy all certs
*/
-void pkcs11_destroy_certs(PKCS11_TOKEN *token)
+void pkcs11_destroy_certs(PKCS11_SLOT_private *slot)
{
- PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
-
- while (tpriv->ncerts > 0) {
- PKCS11_CERT *cert = &tpriv->certs[--(tpriv->ncerts)];
-
- if (cert->x509)
- X509_free(cert->x509);
- OPENSSL_free(cert->label);
- if (cert->id)
- OPENSSL_free(cert->id);
+ while (slot->ncerts > 0) {
+ PKCS11_CERT *cert = &slot->certs[--slot->ncerts];
if (cert->_private)
- OPENSSL_free(cert->_private);
+ pkcs11_object_free(PRIVCERT(cert));
}
- if (tpriv->certs)
- OPENSSL_free(tpriv->certs);
- tpriv->certs = NULL;
- tpriv->ncerts = 0;
+ if (slot->certs)
+ OPENSSL_free(slot->certs);
+ slot->certs = NULL;
+ slot->ncerts = 0;
}
/*
* Store certificate
*/
-int pkcs11_store_certificate(PKCS11_TOKEN *token, X509 *x509, char *label,
- unsigned char *id, size_t id_len, PKCS11_CERT ** ret_cert)
+int pkcs11_store_certificate(PKCS11_SLOT_private *slot, X509 *x509, char *label,
+ unsigned char *id, size_t id_len, PKCS11_CERT **ret_cert)
{
- PKCS11_SLOT *slot = TOKEN2SLOT(token);
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_CTX_private *ctx = slot->ctx;
+ CK_SESSION_HANDLE session;
CK_OBJECT_HANDLE object;
- CK_ATTRIBUTE attrs[32];
- unsigned int n = 0;
- int rv;
+ int rv, r = -1;
int signature_nid;
+ int evp_md_nid = NID_sha1;
const EVP_MD* evp_md;
- CK_MECHANISM_TYPE ckm_md;
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int md_len;
+ PKCS11_TEMPLATE tmpl = {0};
+ CK_OBJECT_CLASS class_certificate = CKO_CERTIFICATE;
+ CK_CERTIFICATE_TYPE certificate_x509 = CKC_X_509;
+ CK_MECHANISM_TYPE ckm_md;
/* First, make sure we have a session */
- if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 1))
+ if (pkcs11_get_session(slot, 1, &session))
return -1;
/* Now build the template */
- pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_CERTIFICATE);
- pkcs11_addattr_bool(attrs + n++, CKA_TOKEN, TRUE);
- pkcs11_addattr_int(attrs + n++, CKA_CERTIFICATE_TYPE, CKC_X_509);
- pkcs11_addattr_obj(attrs + n++, CKA_SUBJECT,
+ pkcs11_addattr_var(&tmpl, CKA_CLASS, class_certificate);
+ pkcs11_addattr_bool(&tmpl, CKA_TOKEN, TRUE);
+ pkcs11_addattr_var(&tmpl, CKA_CERTIFICATE_TYPE, certificate_x509);
+ pkcs11_addattr_obj(&tmpl, CKA_SUBJECT,
(pkcs11_i2d_fn)i2d_X509_NAME, X509_get_subject_name(x509));
- pkcs11_addattr_obj(attrs + n++, CKA_ISSUER,
+ pkcs11_addattr_obj(&tmpl, CKA_ISSUER,
(pkcs11_i2d_fn)i2d_X509_NAME, X509_get_issuer_name(x509));
/* Get digest algorithm from x509 certificate */
-#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL )
signature_nid = X509_get_signature_nid(x509);
#else
signature_nid = OBJ_obj2nid(x509->sig_alg->algorithm);
#endif
- evp_md = EVP_get_digestbynid(signature_nid);
- switch (EVP_MD_type(evp_md)) {
+ OBJ_find_sigid_algs(signature_nid, &evp_md_nid, NULL);
+ switch (evp_md_nid) {
default:
+ evp_md_nid = NID_sha1;
+ /* fall through */
case NID_sha1:
ckm_md = CKM_SHA_1;
break;
@@ -327,29 +241,49 @@
case NID_sha384:
ckm_md = CKM_SHA384;
break;
+#if !defined(LIBRESSL_VERSION_NUMBER)
+ case NID_sha3_224:
+ ckm_md = CKM_SHA3_224;
+ break;
+ case NID_sha3_256:
+ ckm_md = CKM_SHA3_256;
+ break;
+ case NID_sha3_384:
+ ckm_md = CKM_SHA3_384;
+ break;
+ case NID_sha3_512:
+ ckm_md = CKM_SHA3_512;
+ break;
+#endif
}
+ evp_md = EVP_get_digestbynid(evp_md_nid);
+
/* Set hash algorithm; default is SHA-1 */
- pkcs11_addattr_int(attrs + n++, CKA_NAME_HASH_ALGORITHM, ckm_md);
- if(X509_pubkey_digest(x509,evp_md,md,&md_len))
- pkcs11_addattr(attrs + n++, CKA_HASH_OF_SUBJECT_PUBLIC_KEY,md,md_len);
+ pkcs11_addattr_var(&tmpl, CKA_NAME_HASH_ALGORITHM, ckm_md);
+ if (X509_pubkey_digest(x509,evp_md,md,&md_len))
+ pkcs11_addattr(&tmpl, CKA_HASH_OF_SUBJECT_PUBLIC_KEY, md, md_len);
- pkcs11_addattr_obj(attrs + n++, CKA_VALUE, (pkcs11_i2d_fn)i2d_X509, x509);
+ pkcs11_addattr_obj(&tmpl, CKA_VALUE, (pkcs11_i2d_fn)i2d_X509, x509);
if (label)
- pkcs11_addattr_s(attrs + n++, CKA_LABEL, label);
+ pkcs11_addattr_s(&tmpl, CKA_LABEL, label);
if (id && id_len)
- pkcs11_addattr(attrs + n++, CKA_ID, id, id_len);
+ pkcs11_addattr(&tmpl, CKA_ID, id, id_len);
/* Now call the pkcs11 module to create the object */
- rv = CRYPTOKI_call(ctx, C_CreateObject(spriv->session, attrs, n, &object));
+ rv = CRYPTOKI_call(ctx, C_CreateObject(session, tmpl.attrs, tmpl.nattr, &object));
/* Zap all memory allocated when building the template */
- pkcs11_zap_attrs(attrs, n);
-
- CRYPTOKI_checkerr(CKR_F_PKCS11_STORE_CERTIFICATE, rv);
+ pkcs11_zap_attrs(&tmpl);
/* Gobble the key object */
- return pkcs11_init_cert(ctx, token, spriv->session, object, ret_cert);
+ if (rv == CKR_OK) {
+ r = pkcs11_init_cert(slot, session, object, ret_cert);
+ }
+ pkcs11_put_session(slot, session);
+
+ CRYPTOKI_checkerr(CKR_F_PKCS11_STORE_CERTIFICATE, rv);
+ return r;
}
/* vim: set noexpandtab: */
diff -Nru libp11-0.4.11/src/p11_ckr.c libp11-0.4.12/src/p11_ckr.c
--- libp11-0.4.11/src/p11_ckr.c 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/src/p11_ckr.c 2021-10-30 14:20:08.000000000 +0200
@@ -52,10 +52,11 @@
{ERR_FUNC(CKR_F_PKCS11_PRIVATE_DECRYPT), "pkcs11_private_decrypt"},
{ERR_FUNC(CKR_F_PKCS11_PRIVATE_ENCRYPT), "pkcs11_private_encrypt"},
{ERR_FUNC(CKR_F_PKCS11_RELOAD_KEY), "pkcs11_reload_key"},
- {ERR_FUNC(CKR_F_PKCS11_REOPEN_SESSION), "pkcs11_reopen_session"},
{ERR_FUNC(CKR_F_PKCS11_SEED_RANDOM), "pkcs11_seed_random"},
{ERR_FUNC(CKR_F_PKCS11_STORE_CERTIFICATE), "pkcs11_store_certificate"},
{ERR_FUNC(CKR_F_PKCS11_STORE_KEY), "pkcs11_store_key"},
+ {ERR_FUNC(CKR_F_PKCS11_RELOAD_CERTIFICATE), "pkcs11_reload_certificate"},
+ {ERR_FUNC(CKR_F_PKCS11_GET_SESSION), "pkcs11_get_session"},
{0, NULL}
};
@@ -68,7 +69,7 @@
{CKR_ARGUMENTS_BAD, "Invalid arguments"},
{CKR_NO_EVENT, "No event"},
{CKR_NEED_TO_CREATE_THREADS, "Need to create threads"},
- {CKR_CANT_LOCK, "Cannott lock"},
+ {CKR_CANT_LOCK, "Cannot lock"},
{CKR_ATTRIBUTE_READ_ONLY, "Attribute read only"},
{CKR_ATTRIBUTE_SENSITIVE, "Attribute sensitive"},
{CKR_ATTRIBUTE_TYPE_INVALID, "Attribute type invalid"},
diff -Nru libp11-0.4.11/src/p11_ec.c libp11-0.4.12/src/p11_ec.c
--- libp11-0.4.11/src/p11_ec.c 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/src/p11_ec.c 2022-07-05 22:22:51.000000000 +0200
@@ -49,6 +49,7 @@
void *(*)(const void *, size_t, void *, size_t *));
#endif
static compute_key_fn ossl_ecdh_compute_key;
+static void (*ossl_ec_finish)(EC_KEY *);
static int ec_ex_index = 0;
@@ -187,14 +188,15 @@
/* Retrieve EC parameters from key into ec
* return nonzero on error */
-static int pkcs11_get_params(EC_KEY *ec, PKCS11_KEY *key)
+static int pkcs11_get_params(EC_KEY *ec, PKCS11_OBJECT_private *key, CK_SESSION_HANDLE session)
{
CK_BYTE *params;
size_t params_len = 0;
const unsigned char *a;
int rv;
- if (key_getattr_alloc(key, CKA_EC_PARAMS, ¶ms, ¶ms_len))
+ if (pkcs11_getattr_alloc(key->slot->ctx, session, key->object,
+ CKA_EC_PARAMS, ¶ms, ¶ms_len))
return -1;
a = params;
@@ -203,9 +205,41 @@
return rv;
}
+/* Retrieve EC point from x509 certificate into ec
+ * return nonzero on error */
+static int pkcs11_get_point_x509(EC_KEY *ec, X509 *x509)
+{
+ EVP_PKEY *pubkey = NULL;
+ EC_KEY *pubkey_ec;
+ const EC_POINT *point;
+ int rv = -1;
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+ pubkey = X509_get0_pubkey(x509);
+#else
+ pubkey = X509_get_pubkey(x509);
+#endif
+ if (!pubkey)
+ goto error;
+ pubkey_ec = (EC_KEY *)EVP_PKEY_get0_EC_KEY(pubkey);
+ if (!pubkey_ec)
+ goto error;
+ point = EC_KEY_get0_public_key(pubkey_ec);
+ if (!point)
+ goto error;
+ if (EC_KEY_set_public_key(ec, point) == 0)
+ goto error;
+ rv = 0;
+error:
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ EVP_PKEY_free(pubkey);
+#endif
+ return rv;
+}
+
/* Retrieve EC point from key into ec
* return nonzero on error */
-static int pkcs11_get_point_key(EC_KEY *ec, PKCS11_KEY *key)
+static int pkcs11_get_point(EC_KEY *ec, PKCS11_OBJECT_private *key, CK_SESSION_HANDLE session)
{
CK_BYTE *point;
size_t point_len = 0;
@@ -213,7 +247,11 @@
ASN1_OCTET_STRING *os;
int rv = -1;
- if (!key || key_getattr_alloc(key, CKA_EC_POINT, &point, &point_len))
+ if (key->x509 && pkcs11_get_point_x509(ec, key->x509) == 0)
+ return 0;
+
+ if (!key || pkcs11_getattr_alloc(key->slot->ctx, session, key->object,
+ CKA_EC_POINT, &point, &point_len))
return -1;
/* PKCS#11-compliant modules should return ASN1_OCTET_STRING */
@@ -232,42 +270,23 @@
return rv;
}
-/* Retrieve EC point from cert into ec
- * return nonzero on error */
-static int pkcs11_get_point_cert(EC_KEY *ec, PKCS11_CERT *cert)
+static int pkcs11_get_point_associated(EC_KEY *ec, PKCS11_OBJECT_private *key,
+ CK_OBJECT_CLASS object_class, CK_SESSION_HANDLE session)
{
- EVP_PKEY *pubkey = NULL;
- EC_KEY *pubkey_ec;
- const EC_POINT *point;
- int rv = -1;
+ int r;
+ PKCS11_OBJECT_private *obj = pkcs11_object_from_object(key, session, object_class);
- if (!cert)
- goto error;
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
- pubkey = X509_get0_pubkey(cert->x509);
-#else
- pubkey = X509_get_pubkey(cert->x509);
-#endif
- if (!pubkey)
- goto error;
- pubkey_ec = EVP_PKEY_get0_EC_KEY(pubkey);
- if (!pubkey_ec)
- goto error;
- point = EC_KEY_get0_public_key(pubkey_ec);
- if (!point)
- goto error;
- if (EC_KEY_set_public_key(ec, point) == 0)
- goto error;
- rv = 0;
-error:
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
- EVP_PKEY_free(pubkey);
-#endif
- return rv;
+ if (!obj)
+ return -1;
+ r = pkcs11_get_point(ec, obj, session);
+ pkcs11_object_free(obj);
+ return r;
}
-static EC_KEY *pkcs11_get_ec(PKCS11_KEY *key)
+static EC_KEY *pkcs11_get_ec(PKCS11_OBJECT_private *key)
{
+ PKCS11_SLOT_private *slot = key->slot;
+ CK_SESSION_HANDLE session;
EC_KEY *ec;
int no_params, no_point;
@@ -280,21 +299,26 @@
* Continue even if it fails, as the sign operation does not need
* it if the PKCS#11 module or the hardware can figure this out
*/
- no_params = pkcs11_get_params(ec, key);
- no_point = pkcs11_get_point_key(ec, key);
- if (no_point && key->isPrivate) /* Retry with the public key */
- no_point = pkcs11_get_point_key(ec, pkcs11_find_key_from_key(key));
- if (no_point && key->isPrivate) /* Retry with the certificate */
- no_point = pkcs11_get_point_cert(ec, pkcs11_find_certificate(key));
+ if (pkcs11_get_session(slot, 0, &session)) {
+ EC_KEY_free(ec);
+ return NULL;
+ }
+ no_params = pkcs11_get_params(ec, key, session);
+ no_point = pkcs11_get_point(ec, key, session);
+ if (no_point && key->object_class == CKO_PRIVATE_KEY) /* Retry with the public key */
+ no_point = pkcs11_get_point_associated(ec, key, CKO_PUBLIC_KEY, session);
+ if (no_point && key->object_class == CKO_PRIVATE_KEY) /* Retry with the certificate */
+ no_point = pkcs11_get_point_associated(ec, key, CKO_CERTIFICATE, session);
+ pkcs11_put_session(slot, session);
- if (key->isPrivate && EC_KEY_get0_private_key(ec) == NULL) {
+ if (key->object_class == CKO_PRIVATE_KEY && EC_KEY_get0_private_key(ec) == NULL) {
BIGNUM *bn = BN_new();
EC_KEY_set_private_key(ec, bn);
BN_free(bn);
}
/* A public keys requires both the params and the point to be present */
- if (!key->isPrivate && (no_params || no_point)) {
+ if (key->object_class == CKO_PUBLIC_KEY && (no_params || no_point)) {
EC_KEY_free(ec);
return NULL;
}
@@ -302,7 +326,7 @@
return ec;
}
-PKCS11_KEY *pkcs11_get_ex_data_ec(const EC_KEY *ec)
+PKCS11_OBJECT_private *pkcs11_get_ex_data_ec(const EC_KEY *ec)
{
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
return EC_KEY_get_ex_data(ec, ec_ex_index);
@@ -311,7 +335,7 @@
#endif
}
-static void pkcs11_set_ex_data_ec(EC_KEY *ec, PKCS11_KEY *key)
+static void pkcs11_set_ex_data_ec(EC_KEY *ec, PKCS11_OBJECT_private *key)
{
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
EC_KEY_set_ex_data(ec, ec_ex_index, key);
@@ -320,20 +344,6 @@
#endif
}
-static void pkcs11_update_ex_data_ec(PKCS11_KEY *key)
-{
- EVP_PKEY *evp = key->evp_key;
- EC_KEY *ec;
- if (!evp)
- return;
- if (EVP_PKEY_base_id(evp) != EVP_PKEY_EC)
- return;
-
- ec = EVP_PKEY_get1_EC_KEY(evp);
- pkcs11_set_ex_data_ec(ec, key);
- EC_KEY_free(ec);
-}
-
/*
* Get EC key material and stash pointer in ex_data
* Note we get called twice, once for private key, and once for public
@@ -343,7 +353,7 @@
* is not in the private key, and the params may or may not be.
*
*/
-static EVP_PKEY *pkcs11_get_evp_key_ec(PKCS11_KEY *key)
+static EVP_PKEY *pkcs11_get_evp_key_ec(PKCS11_OBJECT_private *key)
{
EVP_PKEY *pk;
EC_KEY *ec;
@@ -356,9 +366,8 @@
EC_KEY_free(ec);
return NULL;
}
- EVP_PKEY_set1_EC_KEY(pk, ec); /* Also increments the ec ref count */
- if (key->isPrivate) {
+ if (key->object_class == CKO_PRIVATE_KEY) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
EC_KEY_set_method(ec, PKCS11_get_ec_key_method());
#else
@@ -370,6 +379,7 @@
* 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;
}
@@ -379,13 +389,12 @@
/* Signature size is the issue, will assume the caller has a big buffer! */
/* No padding or other stuff needed. We can call PKCS11 from here */
static int pkcs11_ecdsa_sign(const unsigned char *msg, unsigned int msg_len,
- unsigned char *sigret, unsigned int *siglen, PKCS11_KEY *key)
+ unsigned char *sigret, unsigned int *siglen, PKCS11_OBJECT_private *key)
{
int rv;
- PKCS11_SLOT *slot = KEY2SLOT(key);
- PKCS11_CTX *ctx = KEY2CTX(key);
- PKCS11_KEY_private *kpriv = PRIVKEY(key);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_SLOT_private *slot = key->slot;
+ PKCS11_CTX_private *ctx = slot->ctx;
+ CK_SESSION_HANDLE session;
CK_MECHANISM mechanism;
CK_ULONG ck_sigsize;
@@ -394,15 +403,17 @@
memset(&mechanism, 0, sizeof(mechanism));
mechanism.mechanism = CKM_ECDSA;
- CRYPTO_THREAD_write_lock(PRIVCTX(ctx)->rwlock);
+ if (pkcs11_get_session(slot, 0, &session))
+ return -1;
+
rv = CRYPTOKI_call(ctx,
- C_SignInit(spriv->session, &mechanism, kpriv->object));
- if (!rv && kpriv->always_authenticate == CK_TRUE)
- rv = pkcs11_authenticate(key);
+ C_SignInit(session, &mechanism, key->object));
+ if (!rv && key->always_authenticate == CK_TRUE)
+ rv = pkcs11_authenticate(key, session);
if (!rv)
rv = CRYPTOKI_call(ctx,
- C_Sign(spriv->session, (CK_BYTE *)msg, msg_len, sigret, &ck_sigsize));
- CRYPTO_THREAD_unlock(PRIVCTX(ctx)->rwlock);
+ C_Sign(session, (CK_BYTE *)msg, msg_len, sigret, &ck_sigsize));
+ pkcs11_put_session(slot, session);
if (rv) {
CKRerr(CKR_F_PKCS11_ECDSA_SIGN, rv);
@@ -413,6 +424,19 @@
return ck_sigsize;
}
+static void pkcs11_ec_finish(EC_KEY *ec)
+{
+ PKCS11_OBJECT_private *key;
+
+ key = pkcs11_get_ex_data_ec(ec);
+ if (key) {
+ pkcs11_set_ex_data_ec(ec, NULL);
+ pkcs11_object_free(key);
+ }
+ if (ossl_ec_finish)
+ ossl_ec_finish(ec);
+}
+
/**
* ECDSA signing method (replaces ossl_ecdsa_sign_sig)
*
@@ -428,7 +452,7 @@
{
unsigned char sigret[512]; /* HACK for now */
ECDSA_SIG *sig;
- PKCS11_KEY *key;
+ PKCS11_OBJECT_private *key;
unsigned int siglen;
BIGNUM *r, *s, *order;
@@ -436,9 +460,9 @@
(void)rp; /* Precomputed values are not used for PKCS#11 */
key = pkcs11_get_ex_data_ec(ec);
- if (check_key_fork(key) < 0) {
+ if (check_object_fork(key) < 0) {
sign_sig_fn orig_sign_sig;
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL )
const EC_KEY_METHOD *meth = EC_KEY_OpenSSL();
EC_KEY_METHOD_get_sign((EC_KEY_METHOD *)meth,
NULL, NULL, &orig_sign_sig);
@@ -470,7 +494,7 @@
sig = ECDSA_SIG_new();
if (!sig)
return NULL;
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL )
ECDSA_SIG_set0(sig, r, s);
#else
BN_free(sig->r);
@@ -538,13 +562,11 @@
const unsigned long ecdh_mechanism,
const void *ec_params,
void *outnewkey,
- PKCS11_KEY *key)
+ PKCS11_OBJECT_private *key)
{
- PKCS11_SLOT *slot = KEY2SLOT(key);
- PKCS11_CTX *ctx = KEY2CTX(key);
- PKCS11_TOKEN *token = KEY2TOKEN(key);
- PKCS11_KEY_private *kpriv = PRIVKEY(key);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_SLOT_private *slot = key->slot;
+ PKCS11_CTX_private *ctx = slot->ctx;
+ CK_SESSION_HANDLE session;
CK_MECHANISM mechanism;
int rv;
@@ -585,28 +607,37 @@
return -1;
}
- rv = CRYPTOKI_call(ctx, C_DeriveKey(spriv->session, &mechanism, kpriv->object,
+ if (pkcs11_get_session(slot, 0, &session))
+ return -1;
+
+ rv = CRYPTOKI_call(ctx, C_DeriveKey(session, &mechanism, key->object,
newkey_template, sizeof(newkey_template)/sizeof(*newkey_template), &newkey));
- CRYPTOKI_checkerr(CKR_F_PKCS11_ECDH_DERIVE, rv);
+ if (rv != CKR_OK)
+ goto error;
/* Return the value of the secret key and/or the object handle of the secret key */
if (out && outlen) { /* pkcs11_ec_ckey only asks for the value */
- if (pkcs11_getattr_alloc(token, newkey, CKA_VALUE, out, outlen)) {
- CKRerr(CKR_F_PKCS11_ECDH_DERIVE, CKR_ATTRIBUTE_VALUE_INVALID);
- CRYPTOKI_call(ctx, C_DestroyObject(spriv->session, newkey));
- return -1;
+ if (pkcs11_getattr_alloc(ctx, session, newkey, CKA_VALUE, out, outlen)) {
+ CRYPTOKI_call(ctx, C_DestroyObject(session, newkey));
+ goto error;
}
}
if (tmpnewkey) /* For future use (not used by pkcs11_ec_ckey) */
*tmpnewkey = newkey;
else /* Destroy the temporary key */
- CRYPTOKI_call(ctx, C_DestroyObject(spriv->session, newkey));
+ CRYPTOKI_call(ctx, C_DestroyObject(session, newkey));
+
+ pkcs11_put_session(slot, session);
return 0;
+error:
+ pkcs11_put_session(slot, session);
+ CKRerr(CKR_F_PKCS11_ECDH_DERIVE, rv);
+ return -1;
}
static int pkcs11_ecdh_compute_key(unsigned char **buf, size_t *buflen,
- const EC_POINT *peer_point, const EC_KEY *ecdh, PKCS11_KEY *key)
+ const EC_POINT *peer_point, const EC_KEY *ecdh, PKCS11_OBJECT_private *key)
{
const EC_GROUP *group = EC_KEY_get0_group(ecdh);
const int key_len = (EC_GROUP_get_degree(group) + 7) / 8;
@@ -636,12 +667,12 @@
static int pkcs11_ec_ckey(unsigned char **out, size_t *outlen,
const EC_POINT *peer_point, const EC_KEY *ecdh)
{
- PKCS11_KEY *key;
+ PKCS11_OBJECT_private *key;
unsigned char *buf = NULL;
size_t buflen;
key = pkcs11_get_ex_data_ec(ecdh);
- if (check_key_fork(key) < 0)
+ if (check_object_fork(key) < 0)
return ossl_ecdh_compute_key(out, outlen, peer_point, ecdh);
if (pkcs11_ecdh_compute_key(&buf, &buflen, peer_point, ecdh, key) < 0)
return 0;
@@ -667,12 +698,12 @@
const EC_POINT *peer_point, const EC_KEY *ecdh,
void *(*KDF)(const void *, size_t, void *, size_t *))
{
- PKCS11_KEY *key;
+ PKCS11_OBJECT_private *key;
unsigned char *buf = NULL;
size_t buflen;
key = pkcs11_get_ex_data_ec(ecdh);
- if (check_key_fork(key) < 0)
+ if (check_object_fork(key) < 0)
return ossl_ecdh_compute_key(out, outlen, peer_point, ecdh, KDF);
if (pkcs11_ecdh_compute_key(&buf, &buflen, peer_point, ecdh, key) < 0)
return -1;
@@ -708,12 +739,21 @@
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 *);
int (*orig_sign)(int, const unsigned char *, int, unsigned char *,
unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL;
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,
+ &orig_set_group, &orig_set_private, &orig_set_public);
+ EC_KEY_METHOD_set_init(ops, orig_init, pkcs11_ec_finish, orig_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);
EC_KEY_METHOD_get_compute_key(ops, &ossl_ecdh_compute_key);
@@ -768,17 +808,13 @@
#endif /* OPENSSL_VERSION_NUMBER */
-PKCS11_KEY_ops pkcs11_ec_ops_s = {
+PKCS11_OBJECT_ops pkcs11_ec_ops = {
EVP_PKEY_EC,
pkcs11_get_evp_key_ec,
- pkcs11_update_ex_data_ec,
};
-PKCS11_KEY_ops *pkcs11_ec_ops = {&pkcs11_ec_ops_s};
#else /* OPENSSL_NO_EC */
-PKCS11_KEY_ops *pkcs11_ec_ops = {NULL};
-
/* if not built with EC or OpenSSL does not support ECDSA
* add these routines so engine_pkcs11 can be built now and not
* require further changes */
diff -Nru libp11-0.4.11/src/p11_front.c libp11-0.4.12/src/p11_front.c
--- libp11-0.4.11/src/p11_front.c 2018-12-12 21:07:46.000000000 +0100
+++ libp11-0.4.12/src/p11_front.c 2022-05-04 18:45:56.000000000 +0200
@@ -34,95 +34,149 @@
void PKCS11_CTX_init_args(PKCS11_CTX *ctx, const char *init_args)
{
- if (check_fork(ctx) < 0)
+ if (check_fork(PRIVCTX(ctx)) < 0)
return;
pkcs11_CTX_init_args(ctx, init_args);
}
int PKCS11_CTX_load(PKCS11_CTX *ctx, const char *ident)
{
- if (check_fork(ctx) < 0)
+ if (check_fork(PRIVCTX(ctx)) < 0)
return -1;
return pkcs11_CTX_load(ctx, ident);
}
void PKCS11_CTX_unload(PKCS11_CTX *ctx)
{
- if (check_fork(ctx) < 0)
+ if (check_fork(PRIVCTX(ctx)) < 0)
return;
pkcs11_CTX_unload(ctx);
}
void PKCS11_CTX_free(PKCS11_CTX *ctx)
{
- if (check_fork(ctx) < 0)
+ if (check_fork(PRIVCTX(ctx)) < 0)
return;
pkcs11_CTX_free(ctx);
}
-int PKCS11_open_session(PKCS11_SLOT *slot, int rw)
+int PKCS11_open_session(PKCS11_SLOT *pslot, int rw)
{
+ PKCS11_SLOT_private *slot = PRIVSLOT(pslot);
if (check_slot_fork(slot) < 0)
return -1;
- return pkcs11_open_session(slot, rw, 0);
+ return pkcs11_open_session(slot, rw);
}
-int PKCS11_enumerate_slots(PKCS11_CTX *ctx,
+int PKCS11_enumerate_slots(PKCS11_CTX *pctx,
PKCS11_SLOT **slotsp, unsigned int *nslotsp)
{
+ PKCS11_CTX_private *ctx = PRIVCTX(pctx);
if (check_fork(ctx) < 0)
return -1;
+ if (!nslotsp)
+ return -1;
+ if (slotsp)
+ *slotsp = 0;
+ if (nslotsp)
+ *nslotsp = 0;
return pkcs11_enumerate_slots(ctx, slotsp, nslotsp);
}
-unsigned long PKCS11_get_slotid_from_slot(PKCS11_SLOT *slot)
+int PKCS11_update_slots(PKCS11_CTX *pctx,
+ PKCS11_SLOT **slotsp, unsigned int *nslotsp)
{
+ PKCS11_CTX_private *ctx = PRIVCTX(pctx);
+ if (check_fork(ctx) < 0)
+ return -1;
+ if (!nslotsp)
+ return -1;
+ return pkcs11_enumerate_slots(ctx, slotsp, nslotsp);
+}
+
+unsigned long PKCS11_get_slotid_from_slot(PKCS11_SLOT *pslot)
+{
+ PKCS11_SLOT_private *slot = PRIVSLOT(pslot);
if (check_slot_fork(slot) < 0)
return 0L;
return pkcs11_get_slotid_from_slot(slot);
}
-void PKCS11_release_all_slots(PKCS11_CTX *ctx,
+void PKCS11_release_all_slots(PKCS11_CTX *pctx,
PKCS11_SLOT *slots, unsigned int nslots)
{
+ PKCS11_CTX_private *ctx = PRIVCTX(pctx);
if (check_fork(ctx) < 0)
return;
- pkcs11_release_all_slots(ctx, slots, nslots);
+ pkcs11_release_all_slots(slots, nslots);
}
PKCS11_SLOT *PKCS11_find_token(PKCS11_CTX *ctx,
PKCS11_SLOT *slots, unsigned int nslots)
{
- if (check_fork(ctx) < 0)
+ PKCS11_SLOT *slot, *best;
+ PKCS11_TOKEN *tok;
+ unsigned int n;
+
+ if (check_fork(PRIVCTX(ctx)) < 0)
return NULL;
- return pkcs11_find_token(ctx, slots, nslots);
+ if (!slots)
+ return NULL;
+
+ best = NULL;
+ for (n = 0, slot = slots; n < nslots; n++, slot++) {
+ if ((tok = slot->token) != NULL) {
+ if (!best ||
+ (tok->initialized > best->token->initialized &&
+ tok->userPinSet > best->token->userPinSet &&
+ tok->loginRequired > best->token->loginRequired))
+ best = slot;
+ }
+ }
+ return best;
}
PKCS11_SLOT *PKCS11_find_next_token(PKCS11_CTX *ctx,
PKCS11_SLOT *slots, unsigned int nslots,
PKCS11_SLOT *current)
{
- if (check_fork(ctx) < 0)
+ int offset;
+
+ if (check_fork(PRIVCTX(ctx)) < 0)
+ return NULL;
+ if (!slots)
return NULL;
- return pkcs11_find_next_token(ctx, slots, nslots, current);
+
+ if (current) {
+ offset = current + 1 - slots;
+ if (offset < 1 || (unsigned int)offset >= nslots)
+ return NULL;
+ } else {
+ offset = 0;
+ }
+
+ return PKCS11_find_token(ctx, slots + offset, nslots - offset);
}
-int PKCS11_is_logged_in(PKCS11_SLOT *slot, int so, int *res)
+int PKCS11_is_logged_in(PKCS11_SLOT *pslot, int so, int *res)
{
+ PKCS11_SLOT_private *slot = PRIVSLOT(pslot);
if (check_slot_fork(slot) < 0)
return -1;
return pkcs11_is_logged_in(slot, so, res);
}
-int PKCS11_login(PKCS11_SLOT *slot, int so, const char *pin)
+int PKCS11_login(PKCS11_SLOT *pslot, int so, const char *pin)
{
+ PKCS11_SLOT_private *slot = PRIVSLOT(pslot);
if (check_slot_fork(slot) < 0)
return -1;
- return pkcs11_login(slot, so, pin, 0);
+ return pkcs11_login(slot, so, pin);
}
-int PKCS11_logout(PKCS11_SLOT *slot)
+int PKCS11_logout(PKCS11_SLOT *pslot)
{
+ PKCS11_SLOT_private *slot = PRIVSLOT(pslot);
if (check_slot_fork(slot) < 0)
return -1;
return pkcs11_logout(slot);
@@ -131,57 +185,65 @@
int PKCS11_enumerate_keys(PKCS11_TOKEN *token,
PKCS11_KEY **keys, unsigned int *nkeys)
{
- if (check_token_fork(token) < 0)
+ PKCS11_SLOT_private *slot = PRIVSLOT(token->slot);
+ if (check_slot_fork(slot) < 0)
return -1;
- return pkcs11_enumerate_keys(token, CKO_PRIVATE_KEY, keys, nkeys);
+ return pkcs11_enumerate_keys(slot, CKO_PRIVATE_KEY, keys, nkeys);
}
-int PKCS11_remove_key(PKCS11_KEY *key)
+int PKCS11_remove_key(PKCS11_KEY *pkey)
{
- if (check_key_fork(key) < 0)
+ PKCS11_OBJECT_private *key = PRIVKEY(pkey);
+ if (check_object_fork(key) < 0)
return -1;
- return pkcs11_remove_key(key);
+ return pkcs11_remove_object(key);
}
int PKCS11_enumerate_public_keys(PKCS11_TOKEN *token,
PKCS11_KEY **keys, unsigned int *nkeys)
{
- if (check_token_fork(token) < 0)
+ PKCS11_SLOT_private *slot = PRIVSLOT(token->slot);
+ if (check_slot_fork(slot) < 0)
return -1;
- return pkcs11_enumerate_keys(token, CKO_PUBLIC_KEY, keys, nkeys);
+ return pkcs11_enumerate_keys(slot, CKO_PUBLIC_KEY, keys, nkeys);
}
-int PKCS11_get_key_type(PKCS11_KEY *key)
+int PKCS11_get_key_type(PKCS11_KEY *pkey)
{
- if (check_key_fork(key) < 0)
+ PKCS11_OBJECT_private *key = PRIVKEY(pkey);
+ if (check_object_fork(key) < 0)
return -1;
return pkcs11_get_key_type(key);
}
-EVP_PKEY *PKCS11_get_private_key(PKCS11_KEY *key)
+EVP_PKEY *PKCS11_get_private_key(PKCS11_KEY *pkey)
{
- if (check_key_fork(key) < 0)
+ PKCS11_OBJECT_private *key = PRIVKEY(pkey);
+ if (check_object_fork(key) < 0)
return NULL;
- return pkcs11_get_key(key, 1);
+ return pkcs11_get_key(key, CKO_PRIVATE_KEY);
}
-EVP_PKEY *PKCS11_get_public_key(PKCS11_KEY *key)
+EVP_PKEY *PKCS11_get_public_key(PKCS11_KEY *pkey)
{
- if (check_key_fork(key) < 0)
+ PKCS11_OBJECT_private *key = PRIVKEY(pkey);
+ if (check_object_fork(key) < 0)
return NULL;
- return pkcs11_get_key(key, 0);
+ return pkcs11_get_key(key, CKO_PUBLIC_KEY);
}
-PKCS11_CERT *PKCS11_find_certificate(PKCS11_KEY *key)
+PKCS11_CERT *PKCS11_find_certificate(PKCS11_KEY *pkey)
{
- if (check_key_fork(key) < 0)
+ PKCS11_OBJECT_private *key = PRIVKEY(pkey);
+ if (check_object_fork(key) < 0)
return NULL;
return pkcs11_find_certificate(key);
}
-PKCS11_KEY *PKCS11_find_key(PKCS11_CERT *cert)
+PKCS11_KEY *PKCS11_find_key(PKCS11_CERT *pcert)
{
- if (check_cert_fork(cert) < 0)
+ PKCS11_OBJECT_private *cert = PRIVCERT(pcert);
+ if (check_object_fork(cert) < 0)
return NULL;
return pkcs11_find_key(cert);
}
@@ -189,75 +251,100 @@
int PKCS11_enumerate_certs(PKCS11_TOKEN *token,
PKCS11_CERT **certs, unsigned int *ncerts)
{
- if (check_token_fork(token) < 0)
+ PKCS11_SLOT_private *slot = PRIVSLOT(token->slot);
+ if (check_slot_fork(slot) < 0)
return -1;
- return pkcs11_enumerate_certs(token, certs, ncerts);
+ return pkcs11_enumerate_certs(slot, certs, ncerts);
}
-int PKCS11_remove_certificate(PKCS11_CERT *cert)
+int PKCS11_remove_certificate(PKCS11_CERT *pcert)
{
- if (check_cert_fork(cert) < 0)
+ PKCS11_OBJECT_private *cert = PRIVCERT(pcert);
+ if (check_object_fork(cert) < 0)
return -1;
- return pkcs11_remove_certificate(cert);
+ return pkcs11_remove_object(cert);
}
int PKCS11_init_token(PKCS11_TOKEN *token, const char *pin,
const char *label)
{
- if (check_token_fork(token) < 0)
+ PKCS11_SLOT_private *slot = PRIVSLOT(token->slot);
+ if (check_slot_fork(slot) < 0)
return -1;
- return pkcs11_init_token(token, pin, label);
+ return pkcs11_init_token(slot, pin, label);
}
int PKCS11_init_pin(PKCS11_TOKEN *token, const char *pin)
{
- if (check_token_fork(token) < 0)
+ PKCS11_SLOT_private *slot = PRIVSLOT(token->slot);
+ int r;
+
+ if (check_slot_fork(slot) < 0)
return -1;
- return pkcs11_init_pin(token, pin);
+ r = pkcs11_init_pin(slot, pin);
+ if (r == 0)
+ r = pkcs11_refresh_token(token->slot);
+ return r;
}
-int PKCS11_change_pin(PKCS11_SLOT *slot,
+int PKCS11_change_pin(PKCS11_SLOT *pslot,
const char *old_pin, const char *new_pin)
{
+ PKCS11_SLOT_private *slot = PRIVSLOT(pslot);
+ int r;
+
if (check_slot_fork(slot) < 0)
return -1;
- return pkcs11_change_pin(slot, old_pin, new_pin);
+ r = pkcs11_change_pin(slot, old_pin, new_pin);
+ if (r == 0)
+ r = pkcs11_refresh_token(pslot);
+ return r;
}
int PKCS11_store_private_key(PKCS11_TOKEN *token,
EVP_PKEY *pk, char *label, unsigned char *id, size_t id_len)
{
- if (check_token_fork(token) < 0)
+ PKCS11_SLOT_private *slot = PRIVSLOT(token->slot);
+ if (check_slot_fork(slot) < 0)
return -1;
- return pkcs11_store_private_key(token, pk, label, id, id_len);
+ return pkcs11_store_private_key(slot, pk, label, id, id_len);
}
int PKCS11_store_public_key(PKCS11_TOKEN *token,
EVP_PKEY *pk, char *label, unsigned char *id, size_t id_len)
{
- if (check_token_fork(token) < 0)
+ PKCS11_SLOT_private *slot = PRIVSLOT(token->slot);
+ if (check_slot_fork(slot) < 0)
return -1;
- return pkcs11_store_public_key(token, pk, label, id, id_len);
+ return pkcs11_store_public_key(slot, pk, label, id, id_len);
}
int PKCS11_store_certificate(PKCS11_TOKEN *token, X509 *x509,
char *label, unsigned char *id, size_t id_len,
PKCS11_CERT **ret_cert)
{
- if (check_token_fork(token) < 0)
+ PKCS11_SLOT_private *slot = PRIVSLOT(token->slot);
+ if (check_slot_fork(slot) < 0)
return -1;
- return pkcs11_store_certificate(token, x509, label, id, id_len, ret_cert);
+ return pkcs11_store_certificate(slot, x509, label, id, id_len, ret_cert);
}
-int PKCS11_seed_random(PKCS11_SLOT *slot, const unsigned char *s, unsigned int s_len)
+int PKCS11_seed_random(PKCS11_SLOT *pslot, const unsigned char *s, unsigned int s_len)
{
+ PKCS11_SLOT_private *slot = PRIVSLOT(pslot);
+ int r;
+
if (check_slot_fork(slot) < 0)
return -1;
- return pkcs11_seed_random(slot, s, s_len);
+ r = pkcs11_seed_random(slot, s, s_len);
+ if (r == 0)
+ r = pkcs11_refresh_token(pslot);
+ return r;
}
-int PKCS11_generate_random(PKCS11_SLOT *slot, unsigned char *r, unsigned int r_len)
+int PKCS11_generate_random(PKCS11_SLOT *pslot, unsigned char *r, unsigned int r_len)
{
+ PKCS11_SLOT_private *slot = PRIVSLOT(pslot);
if (check_slot_fork(slot) < 0)
return -1;
return pkcs11_generate_random(slot, r, r_len);
@@ -272,8 +359,9 @@
ERR_load_CKR_strings();
}
-int PKCS11_set_ui_method(PKCS11_CTX *ctx, UI_METHOD *ui_method, void *ui_user_data)
+int PKCS11_set_ui_method(PKCS11_CTX *pctx, UI_METHOD *ui_method, void *ui_user_data)
{
+ PKCS11_CTX_private *ctx = PRIVCTX(pctx);
if (check_fork(ctx) < 0)
return -1;
return pkcs11_set_ui_method(ctx, ui_method, ui_user_data);
@@ -285,52 +373,59 @@
int algorithm, unsigned int bits,
char *label, unsigned char *id, size_t id_len)
{
- if (check_token_fork(token) < 0)
+ PKCS11_SLOT_private *slot = PRIVSLOT(token->slot);
+ if (check_slot_fork(slot) < 0)
return -1;
- return pkcs11_generate_key(token, algorithm, bits, label, id, id_len);
+ return pkcs11_generate_key(slot, algorithm, bits, label, id, id_len);
}
-int PKCS11_get_key_size(PKCS11_KEY *key)
+int PKCS11_get_key_size(PKCS11_KEY *pkey)
{
- if (check_key_fork(key) < 0)
+ PKCS11_OBJECT_private *key = PRIVKEY(pkey);
+ if (check_object_fork(key) < 0)
return -1;
return pkcs11_get_key_size(key);
}
-int PKCS11_get_key_modulus(PKCS11_KEY *key, BIGNUM **bn)
+int PKCS11_get_key_modulus(PKCS11_KEY *pkey, BIGNUM **bn)
{
- if (check_key_fork(key) < 0)
+ PKCS11_OBJECT_private *key = PRIVKEY(pkey);
+ if (check_object_fork(key) < 0)
return -1;
return pkcs11_get_key_modulus(key, bn);
}
-int PKCS11_get_key_exponent(PKCS11_KEY *key, BIGNUM **bn)
+int PKCS11_get_key_exponent(PKCS11_KEY *pkey, BIGNUM **bn)
{
- if (check_key_fork(key) < 0)
+ PKCS11_OBJECT_private *key = PRIVKEY(pkey);
+ if (check_object_fork(key) < 0)
return -1;
return pkcs11_get_key_exponent(key, bn);
}
int PKCS11_sign(int type, const unsigned char *m, unsigned int m_len,
- unsigned char *sigret, unsigned int *siglen, PKCS11_KEY *key)
+ unsigned char *sigret, unsigned int *siglen, PKCS11_KEY *pkey)
{
- if (check_key_fork(key) < 0)
+ PKCS11_OBJECT_private *key = PRIVKEY(pkey);
+ if (check_object_fork(key) < 0)
return -1;
return pkcs11_sign(type, m, m_len, sigret, siglen, key);
}
int PKCS11_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
- PKCS11_KEY *key, int padding)
+ PKCS11_KEY *pkey, int padding)
{
- if (check_key_fork(key) < 0)
+ PKCS11_OBJECT_private *key = PRIVKEY(pkey);
+ if (check_object_fork(key) < 0)
return -1;
return pkcs11_private_encrypt(flen, from, to, key, padding);
}
int PKCS11_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
- PKCS11_KEY *key, int padding)
+ PKCS11_KEY *pkey, int padding)
{
- if (check_key_fork(key) < 0)
+ PKCS11_OBJECT_private *key = PRIVKEY(pkey);
+ if (check_object_fork(key) < 0)
return -1;
return pkcs11_private_decrypt(flen, from, to, key, padding);
}
diff -Nru libp11-0.4.11/src/p11_key.c libp11-0.4.12/src/p11_key.c
--- libp11-0.4.11/src/p11_key.c 2020-10-04 22:13:22.000000000 +0200
+++ libp11-0.4.12/src/p11_key.c 2022-07-05 22:22:51.000000000 +0200
@@ -22,172 +22,288 @@
#include <openssl/ui.h>
#include <openssl/bn.h>
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(strncasecmp)
#define strncasecmp strnicmp
#endif
/* The maximum length of PIN */
#define MAX_PIN_LENGTH 32
-static int pkcs11_find_keys(PKCS11_TOKEN *, unsigned int);
-static int pkcs11_next_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
+static int pkcs11_find_keys(PKCS11_SLOT_private *, CK_SESSION_HANDLE, unsigned int);
+static int pkcs11_next_key(PKCS11_CTX_private *ctx, PKCS11_SLOT_private *,
CK_SESSION_HANDLE session, CK_OBJECT_CLASS type);
-static int pkcs11_init_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
- CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o,
- CK_OBJECT_CLASS type, PKCS11_KEY **);
-static int pkcs11_store_key(PKCS11_TOKEN *, EVP_PKEY *, unsigned int,
+static int pkcs11_init_key(PKCS11_SLOT_private *, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE o, CK_OBJECT_CLASS type, PKCS11_KEY **);
+static int pkcs11_store_key(PKCS11_SLOT_private *, EVP_PKEY *, CK_OBJECT_CLASS,
char *, unsigned char *, size_t, PKCS11_KEY **);
-/* Set UI method to allow retrieving CKU_CONTEXT_SPECIFIC PINs interactively */
-int pkcs11_set_ui_method(PKCS11_CTX *ctx,
- UI_METHOD *ui_method, void *ui_user_data)
+/* Helper to acquire object handle from given template */
+static CK_OBJECT_HANDLE pkcs11_handle_from_template(PKCS11_SLOT_private *slot,
+ CK_SESSION_HANDLE session, PKCS11_TEMPLATE *tmpl)
{
- PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
- if (!cpriv)
- return -1;
- cpriv->ui_method = ui_method;
- cpriv->ui_user_data = ui_user_data;
- return 0;
+ PKCS11_CTX_private *ctx = slot->ctx;
+ CK_OBJECT_HANDLE object;
+ CK_ULONG count;
+ CK_RV rv;
+
+ rv = CRYPTOKI_call(ctx,
+ C_FindObjectsInit(session, tmpl->attrs, tmpl->nattr));
+ if (rv == CKR_OK) {
+ rv = CRYPTOKI_call(ctx,
+ C_FindObjects(session, &object, 1, &count));
+ CRYPTOKI_call(ctx, C_FindObjectsFinal(session));
+ }
+ pkcs11_zap_attrs(tmpl);
+
+ if (rv == CKR_OK && count == 1)
+ return object;
+
+ return CK_INVALID_HANDLE;
}
-/*
- * Find private key matching a certificate
- */
-PKCS11_KEY *pkcs11_find_key(PKCS11_CERT *cert)
+/* Get object from a handle */
+PKCS11_OBJECT_private *pkcs11_object_from_handle(PKCS11_SLOT_private *slot,
+ CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object)
{
- PKCS11_CERT_private *cpriv = PRIVCERT(cert);
- PKCS11_KEY *keys;
- unsigned int n, count;
+ PKCS11_CTX_private *ctx = slot->ctx;
+ PKCS11_OBJECT_private *obj;
+ PKCS11_OBJECT_ops *ops = NULL;
+ CK_OBJECT_CLASS object_class = -1;
+ CK_KEY_TYPE key_type = -1;
+ CK_CERTIFICATE_TYPE cert_type = -1;
+ size_t size;
+ unsigned char *data;
- if (pkcs11_enumerate_keys(CERT2TOKEN(cert), CKO_PRIVATE_KEY, &keys, &count))
+ if (pkcs11_getattr_val(ctx, session, object, CKA_CLASS,
+ (CK_BYTE *) &object_class, sizeof(object_class)))
+ return NULL;
+
+ switch (object_class) {
+ case CKO_PUBLIC_KEY:
+ case CKO_PRIVATE_KEY:
+ if (pkcs11_getattr_val(ctx, session, object, CKA_KEY_TYPE,
+ (CK_BYTE *)&key_type, sizeof(key_type)))
+ return NULL;
+ switch (key_type) {
+ case CKK_RSA:
+ ops = &pkcs11_rsa_ops;
+ break;
+#ifndef OPENSSL_NO_EC
+ case CKK_EC:
+ ops = &pkcs11_ec_ops;
+ break;
+#endif
+ default:
+ /* Ignore any keys we don't understand */
+ return 0;
+ }
+ break;
+ case CKO_CERTIFICATE:
+ if (pkcs11_getattr_val(ctx, session, object, CKA_CERTIFICATE_TYPE,
+ (CK_BYTE *)&cert_type, sizeof(cert_type)))
+ return NULL;
+ /* Ignore unknown certificate types */
+ if (cert_type != CKC_X_509)
+ return 0;
+ break;
+ default:
return NULL;
- for (n = 0; n < count; n++) {
- PKCS11_KEY_private *kpriv = PRIVKEY(&keys[n]);
- if (kpriv && cpriv->id_len == kpriv->id_len
- && !memcmp(cpriv->id, kpriv->id, cpriv->id_len))
- return &keys[n];
}
- return NULL;
+
+ obj = OPENSSL_malloc(sizeof(*obj));
+ if (!obj)
+ return NULL;
+
+ memset(obj, 0, sizeof(*obj));
+ obj->object_class = object_class;
+ obj->object = object;
+ obj->slot = pkcs11_slot_ref(slot);
+ obj->id_len = sizeof(obj->id);
+ if (pkcs11_getattr_var(ctx, session, object, CKA_ID, obj->id, &obj->id_len))
+ obj->id_len = 0;
+ pkcs11_getattr_alloc(ctx, session, object, CKA_LABEL, (CK_BYTE **)&obj->label, NULL);
+ obj->ops = ops;
+ obj->forkid = get_forkid();
+ switch (object_class) {
+ case CKO_PRIVATE_KEY:
+ if (pkcs11_getattr_val(ctx, session, object, CKA_ALWAYS_AUTHENTICATE,
+ &obj->always_authenticate, sizeof(CK_BBOOL))) {
+#ifdef DEBUG
+ fprintf(stderr, "Missing CKA_ALWAYS_AUTHENTICATE attribute\n");
+#endif
+ }
+ break;
+ case CKO_CERTIFICATE:
+ if (!pkcs11_getattr_alloc(ctx, session, object, CKA_VALUE,
+ &data, &size)) {
+ const unsigned char *p = data;
+ obj->x509 = d2i_X509(NULL, &p, (long)size);
+ OPENSSL_free(data);
+ }
+ break;
+ }
+ return obj;
+}
+
+/* Get object based on template */
+PKCS11_OBJECT_private *pkcs11_object_from_template(PKCS11_SLOT_private *slot,
+ CK_SESSION_HANDLE session, PKCS11_TEMPLATE *tmpl)
+{
+ PKCS11_OBJECT_private *obj;
+ int release = 0;
+
+ if (session == CK_INVALID_HANDLE) {
+ if (pkcs11_get_session(slot, 0, &session))
+ return NULL;
+ release = 1;
+ }
+
+ obj = pkcs11_object_from_handle(slot, session,
+ pkcs11_handle_from_template(slot, session, tmpl));
+
+ if (release)
+ pkcs11_put_session(slot, session);
+
+ return obj;
+}
+
+PKCS11_OBJECT_private *pkcs11_object_from_object(PKCS11_OBJECT_private *obj,
+ CK_SESSION_HANDLE session, CK_OBJECT_CLASS object_class)
+{
+ PKCS11_TEMPLATE tmpl = {0};
+ pkcs11_addattr_var(&tmpl, CKA_CLASS, object_class);
+ pkcs11_addattr(&tmpl, CKA_ID, obj->id, obj->id_len);
+ return pkcs11_object_from_template(obj->slot, session, &tmpl);
+}
+
+void pkcs11_object_free(PKCS11_OBJECT_private *obj)
+{
+ if (obj->evp_key) {
+ /* When the EVP object is reference count goes to zero,
+ * it will call this function again. */
+ EVP_PKEY *pkey = obj->evp_key;
+ obj->evp_key = NULL;
+ EVP_PKEY_free(pkey);
+ return;
+ }
+ pkcs11_slot_unref(obj->slot);
+ X509_free(obj->x509);
+ OPENSSL_free(obj->label);
+ OPENSSL_free(obj);
+}
+
+/* Set UI method to allow retrieving CKU_CONTEXT_SPECIFIC PINs interactively */
+int pkcs11_set_ui_method(PKCS11_CTX_private *ctx,
+ UI_METHOD *ui_method, void *ui_user_data)
+{
+ if (!ctx)
+ return -1;
+ ctx->ui_method = ui_method;
+ ctx->ui_user_data = ui_user_data;
+ return 0;
}
/*
- * Find key matching a key of the other type (public vs private)
+ * Find private key matching a certificate
*/
-PKCS11_KEY *pkcs11_find_key_from_key(PKCS11_KEY *keyin)
+PKCS11_KEY *pkcs11_find_key(PKCS11_OBJECT_private *cert)
{
- PKCS11_KEY_private *kinpriv = PRIVKEY(keyin);
PKCS11_KEY *keys;
- unsigned int n, count, type =
- keyin->isPrivate ? CKO_PUBLIC_KEY : CKO_PRIVATE_KEY;
+ unsigned int n, count;
- if (pkcs11_enumerate_keys(KEY2TOKEN(keyin), type, &keys, &count))
+ if (pkcs11_enumerate_keys(cert->slot, CKO_PRIVATE_KEY, &keys, &count))
return NULL;
for (n = 0; n < count; n++) {
- PKCS11_KEY_private *kpriv = PRIVKEY(&keys[n]);
- if (kpriv && kinpriv->id_len == kpriv->id_len
- && !memcmp(kinpriv->id, kpriv->id, kinpriv->id_len))
+ PKCS11_OBJECT_private *kpriv = PRIVKEY(&keys[n]);
+ if (kpriv && cert->id_len == kpriv->id_len
+ && !memcmp(cert->id, kpriv->id, cert->id_len))
return &keys[n];
}
return NULL;
}
/*
- * Reopens the object associated with the key
+ * Reopens the object by refresing the object handle
*/
-int pkcs11_reload_key(PKCS11_KEY *key)
+int pkcs11_reload_object(PKCS11_OBJECT_private *obj)
{
- PKCS11_KEY_private *kpriv = PRIVKEY(key);
- PKCS11_SLOT *slot = KEY2SLOT(key);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- CK_OBJECT_CLASS key_search_class =
- key->isPrivate ? CKO_PRIVATE_KEY : CKO_PUBLIC_KEY;
- CK_ATTRIBUTE key_search_attrs[2] = {
- {CKA_CLASS, &key_search_class, sizeof(key_search_class)},
- {CKA_ID, kpriv->id, kpriv->id_len},
- };
- CK_ULONG count;
- int rv;
+ PKCS11_SLOT_private *slot = obj->slot;
+ CK_SESSION_HANDLE session;
+ PKCS11_TEMPLATE tmpl = {0};
- /* this is already covered with a per-ctx lock */
+ if (pkcs11_get_session(slot, 0, &session))
+ return -1;
- rv = CRYPTOKI_call(ctx,
- C_FindObjectsInit(spriv->session, key_search_attrs, 2));
- CRYPTOKI_checkerr(CKR_F_PKCS11_RELOAD_KEY, rv);
+ pkcs11_addattr_var(&tmpl, CKA_CLASS, obj->object_class);
+ if (obj->id_len)
+ pkcs11_addattr(&tmpl, CKA_ID, obj->id, obj->id_len);
+ if (obj->label)
+ pkcs11_addattr_s(&tmpl, CKA_LABEL, obj->label);
- rv = CRYPTOKI_call(ctx,
- C_FindObjects(spriv->session, &kpriv->object, 1, &count));
- CRYPTOKI_checkerr(CKR_F_PKCS11_RELOAD_KEY, rv);
+ obj->object = pkcs11_handle_from_template(slot, session, &tmpl);
+ pkcs11_put_session(slot, session);
- CRYPTOKI_call(ctx, C_FindObjectsFinal(spriv->session));
+ if (obj->object == CK_INVALID_HANDLE)
+ CRYPTOKI_checkerr(CKR_F_PKCS11_RELOAD_KEY, CKR_OBJECT_HANDLE_INVALID);
return 0;
}
/**
- * Generate a keyPair directly on token
+ * Generate a key pair directly on token
*/
-int pkcs11_generate_key(PKCS11_TOKEN *token, int algorithm, unsigned int bits,
+int pkcs11_generate_key(PKCS11_SLOT_private *slot, int algorithm, unsigned int bits,
char *label, unsigned char* id, size_t id_len) {
- PKCS11_SLOT *slot = TOKEN2SLOT(token);
- PKCS11_CTX *ctx = TOKEN2CTX(token);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
-
- CK_ATTRIBUTE pubkey_attrs[32];
- CK_ATTRIBUTE privkey_attrs[32];
- unsigned int n_pub = 0, n_priv = 0;
+ PKCS11_CTX_private *ctx = slot->ctx;
+ CK_SESSION_HANDLE session;
+ PKCS11_TEMPLATE pubtmpl = {0}, privtmpl = {0};
CK_MECHANISM mechanism = {
CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0
};
+ CK_ULONG num_bits = bits;
CK_BYTE public_exponent[] = { 1, 0, 1 };
CK_OBJECT_HANDLE pub_key_obj, priv_key_obj;
int rv;
(void)algorithm; /* squash the unused parameter warning */
- /* make sure we have a session */
- if (!spriv->haveSession && PKCS11_open_session(slot, 1))
+ if (pkcs11_get_session(slot, 1, &session))
return -1;
/* pubkey attributes */
- pkcs11_addattr(pubkey_attrs + n_pub++, CKA_ID, id, id_len);
+ pkcs11_addattr(&pubtmpl, CKA_ID, id, id_len);
if (label)
- pkcs11_addattr_s(pubkey_attrs + n_pub++, CKA_LABEL, label);
- pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_TOKEN, TRUE);
-
- pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_ENCRYPT, TRUE);
- pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_VERIFY, TRUE);
- pkcs11_addattr_bool(pubkey_attrs + n_pub++, CKA_WRAP, TRUE);
- pkcs11_addattr_int(pubkey_attrs + n_pub++, CKA_MODULUS_BITS, bits);
- pkcs11_addattr(pubkey_attrs + n_pub++, CKA_PUBLIC_EXPONENT, public_exponent, 3);
+ pkcs11_addattr_s(&pubtmpl, CKA_LABEL, label);
+ pkcs11_addattr_bool(&pubtmpl, CKA_TOKEN, TRUE);
+ pkcs11_addattr_bool(&pubtmpl, CKA_ENCRYPT, TRUE);
+ pkcs11_addattr_bool(&pubtmpl, CKA_VERIFY, TRUE);
+ pkcs11_addattr_bool(&pubtmpl, CKA_WRAP, TRUE);
+ pkcs11_addattr_var(&pubtmpl, CKA_MODULUS_BITS, num_bits);
+ pkcs11_addattr(&pubtmpl, CKA_PUBLIC_EXPONENT, public_exponent, 3);
/* privkey attributes */
- pkcs11_addattr(privkey_attrs + n_priv++, CKA_ID, id, id_len);
+ pkcs11_addattr(&privtmpl, CKA_ID, id, id_len);
if (label)
- pkcs11_addattr_s(privkey_attrs + n_priv++, CKA_LABEL, label);
- pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_TOKEN, TRUE);
- pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_PRIVATE, TRUE);
- pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_SENSITIVE, TRUE);
- pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_DECRYPT, TRUE);
- pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_SIGN, TRUE);
- pkcs11_addattr_bool(privkey_attrs + n_priv++, CKA_UNWRAP, TRUE);
+ pkcs11_addattr_s(&privtmpl, CKA_LABEL, label);
+ pkcs11_addattr_bool(&privtmpl, CKA_TOKEN, TRUE);
+ pkcs11_addattr_bool(&privtmpl, CKA_PRIVATE, TRUE);
+ pkcs11_addattr_bool(&privtmpl, CKA_SENSITIVE, TRUE);
+ pkcs11_addattr_bool(&privtmpl, CKA_DECRYPT, TRUE);
+ pkcs11_addattr_bool(&privtmpl, CKA_SIGN, TRUE);
+ pkcs11_addattr_bool(&privtmpl, CKA_UNWRAP, TRUE);
/* call the pkcs11 module to create the key pair */
rv = CRYPTOKI_call(ctx, C_GenerateKeyPair(
- spriv->session,
- &mechanism,
- pubkey_attrs,
- n_pub,
- privkey_attrs,
- n_priv,
- &pub_key_obj,
- &priv_key_obj
- ));
+ session, &mechanism,
+ pubtmpl.attrs, pubtmpl.nattr,
+ privtmpl.attrs, privtmpl.nattr,
+ &pub_key_obj, &priv_key_obj));
+ pkcs11_put_session(slot, session);
/* zap all memory allocated when building the template */
- pkcs11_zap_attrs(privkey_attrs, n_priv);
- pkcs11_zap_attrs(pubkey_attrs, n_pub);
+ pkcs11_zap_attrs(&privtmpl);
+ pkcs11_zap_attrs(&pubtmpl);
CRYPTOKI_checkerr(CKR_F_PKCS11_GENERATE_KEY, rv);
@@ -197,18 +313,18 @@
/*
* Store a private key on the token
*/
-int pkcs11_store_private_key(PKCS11_TOKEN *token, EVP_PKEY *pk,
+int pkcs11_store_private_key(PKCS11_SLOT_private *slot, EVP_PKEY *pk,
char *label, unsigned char *id, size_t id_len)
{
- if (pkcs11_store_key(token, pk, CKO_PRIVATE_KEY, label, id, id_len, NULL))
+ if (pkcs11_store_key(slot, pk, CKO_PRIVATE_KEY, label, id, id_len, NULL))
return -1;
return 0;
}
-int pkcs11_store_public_key(PKCS11_TOKEN *token, EVP_PKEY *pk,
+int pkcs11_store_public_key(PKCS11_SLOT_private *slot, EVP_PKEY *pk,
char *label, unsigned char *id, size_t id_len)
{
- if (pkcs11_store_key(token, pk, CKO_PUBLIC_KEY, label, id, id_len, NULL))
+ if (pkcs11_store_key(slot, pk, CKO_PUBLIC_KEY, label, id, id_len, NULL))
return -1;
return 0;
}
@@ -216,45 +332,39 @@
/*
* Store private key
*/
-static int pkcs11_store_key(PKCS11_TOKEN *token, EVP_PKEY *pk,
- unsigned int type, char *label, unsigned char *id, size_t id_len,
+static int pkcs11_store_key(PKCS11_SLOT_private *slot, EVP_PKEY *pk,
+ CK_OBJECT_CLASS type, char *label, unsigned char *id, size_t id_len,
PKCS11_KEY ** ret_key)
{
- PKCS11_SLOT *slot = TOKEN2SLOT(token);
- PKCS11_CTX *ctx = TOKEN2CTX(token);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_CTX_private *ctx = slot->ctx;
+ PKCS11_TEMPLATE tmpl = {0};
+ CK_SESSION_HANDLE session;
CK_OBJECT_HANDLE object;
- CK_ATTRIBUTE attrs[32];
- unsigned int n = 0;
- int rv;
+ CK_KEY_TYPE key_type_rsa = CKK_RSA;
+ int rv, r = -1;
const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_p, *rsa_q, *rsa_dmp1, *rsa_dmq1, *rsa_iqmp;
- /* First, make sure we have a session */
- if (!spriv->haveSession && PKCS11_open_session(slot, 1))
- return -1;
-
/* Now build the key attrs */
- pkcs11_addattr_int(attrs + n++, CKA_CLASS, type);
+ pkcs11_addattr_var(&tmpl, CKA_CLASS, type);
if (label)
- pkcs11_addattr_s(attrs + n++, CKA_LABEL, label);
+ pkcs11_addattr_s(&tmpl, CKA_LABEL, label);
if (id && id_len)
- pkcs11_addattr(attrs + n++, CKA_ID, id, id_len);
- pkcs11_addattr_bool(attrs + n++, CKA_TOKEN, TRUE);
+ pkcs11_addattr(&tmpl, CKA_ID, id, id_len);
+ pkcs11_addattr_bool(&tmpl, CKA_TOKEN, TRUE);
if (type == CKO_PRIVATE_KEY) {
- pkcs11_addattr_bool(attrs + n++, CKA_PRIVATE, TRUE);
- pkcs11_addattr_bool(attrs + n++, CKA_SENSITIVE, TRUE);
- pkcs11_addattr_bool(attrs + n++, CKA_DECRYPT, TRUE);
- pkcs11_addattr_bool(attrs + n++, CKA_SIGN, TRUE);
- pkcs11_addattr_bool(attrs + n++, CKA_UNWRAP, TRUE);
+ pkcs11_addattr_bool(&tmpl, CKA_PRIVATE, TRUE);
+ pkcs11_addattr_bool(&tmpl, CKA_SENSITIVE, TRUE);
+ pkcs11_addattr_bool(&tmpl, CKA_DECRYPT, TRUE);
+ pkcs11_addattr_bool(&tmpl, CKA_SIGN, TRUE);
+ pkcs11_addattr_bool(&tmpl, CKA_UNWRAP, TRUE);
} else { /* CKO_PUBLIC_KEY */
- pkcs11_addattr_bool(attrs + n++, CKA_ENCRYPT, TRUE);
- pkcs11_addattr_bool(attrs + n++, CKA_VERIFY, TRUE);
- pkcs11_addattr_bool(attrs + n++, CKA_WRAP, TRUE);
+ pkcs11_addattr_bool(&tmpl, CKA_ENCRYPT, TRUE);
+ pkcs11_addattr_bool(&tmpl, CKA_VERIFY, TRUE);
+ pkcs11_addattr_bool(&tmpl, CKA_WRAP, TRUE);
}
-#if OPENSSL_VERSION_NUMBER >= 0x10100003L && !defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER >= 0x10100003L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL )
if (EVP_PKEY_base_id(pk) == EVP_PKEY_RSA) {
RSA *rsa = EVP_PKEY_get1_RSA(pk);
- pkcs11_addattr_int(attrs + n++, CKA_KEY_TYPE, CKK_RSA);
RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
RSA_get0_factors(rsa, &rsa_p, &rsa_q);
RSA_get0_crt_params(rsa, &rsa_dmp1, &rsa_dmq1, &rsa_iqmp);
@@ -262,7 +372,6 @@
#else
if (pk->type == EVP_PKEY_RSA) {
RSA *rsa = pk->pkey.rsa;
- pkcs11_addattr_int(attrs + n++, CKA_KEY_TYPE, CKK_RSA);
rsa_n=rsa->n;
rsa_e=rsa->e;
rsa_d=rsa->d;
@@ -272,107 +381,114 @@
rsa_dmq1=rsa->dmq1;
rsa_iqmp=rsa->iqmp;
#endif
- pkcs11_addattr_bn(attrs + n++, CKA_MODULUS, rsa_n);
- pkcs11_addattr_bn(attrs + n++, CKA_PUBLIC_EXPONENT, rsa_e);
+ pkcs11_addattr_var(&tmpl, CKA_KEY_TYPE, key_type_rsa);
+ pkcs11_addattr_bn(&tmpl, CKA_MODULUS, rsa_n);
+ pkcs11_addattr_bn(&tmpl, CKA_PUBLIC_EXPONENT, rsa_e);
if (type == CKO_PRIVATE_KEY) {
- pkcs11_addattr_bn(attrs + n++, CKA_PRIVATE_EXPONENT, rsa_d);
- pkcs11_addattr_bn(attrs + n++, CKA_PRIME_1, rsa_p);
- pkcs11_addattr_bn(attrs + n++, CKA_PRIME_2, rsa_q);
+ pkcs11_addattr_bn(&tmpl, CKA_PRIVATE_EXPONENT, rsa_d);
+ pkcs11_addattr_bn(&tmpl, CKA_PRIME_1, rsa_p);
+ pkcs11_addattr_bn(&tmpl, CKA_PRIME_2, rsa_q);
if (rsa_dmp1)
- pkcs11_addattr_bn(attrs + n++, CKA_EXPONENT_1, rsa_dmp1);
+ pkcs11_addattr_bn(&tmpl, CKA_EXPONENT_1, rsa_dmp1);
if (rsa_dmq1)
- pkcs11_addattr_bn(attrs + n++, CKA_EXPONENT_2, rsa_dmq1);
+ pkcs11_addattr_bn(&tmpl, CKA_EXPONENT_2, rsa_dmq1);
if (rsa_iqmp)
- pkcs11_addattr_bn(attrs + n++, CKA_COEFFICIENT, rsa_iqmp);
+ pkcs11_addattr_bn(&tmpl, CKA_COEFFICIENT, rsa_iqmp);
}
} else {
- pkcs11_zap_attrs(attrs, n);
+ pkcs11_zap_attrs(&tmpl);
P11err(P11_F_PKCS11_STORE_KEY, P11_R_NOT_SUPPORTED);
return -1;
}
+ if (pkcs11_get_session(slot, 1, &session)) {
+ pkcs11_zap_attrs(&tmpl);
+ return -1;
+ }
+
/* Now call the pkcs11 module to create the object */
- rv = CRYPTOKI_call(ctx, C_CreateObject(spriv->session, attrs, n, &object));
+ rv = CRYPTOKI_call(ctx, C_CreateObject(session, tmpl.attrs, tmpl.nattr, &object));
/* Zap all memory allocated when building the template */
- pkcs11_zap_attrs(attrs, n);
+ pkcs11_zap_attrs(&tmpl);
+
+ if (rv == CKR_OK) {
+ /* Gobble the key object */
+ r = pkcs11_init_key(slot, session, object, type, ret_key);
+ }
+ pkcs11_put_session(slot, session);
CRYPTOKI_checkerr(CKR_F_PKCS11_STORE_KEY, rv);
+ return r;
- /* Gobble the key object */
- return pkcs11_init_key(ctx, token, spriv->session, object, type, ret_key);
}
/*
* Get the key type
*/
-int pkcs11_get_key_type(PKCS11_KEY *key)
+int pkcs11_get_key_type(PKCS11_OBJECT_private *key)
{
- PKCS11_KEY_private *kpriv = PRIVKEY(key);
-
- return kpriv->ops->type;
+ if (key->ops)
+ return key->ops->pkey_type;
+ return EVP_PKEY_NONE;
}
/*
* Create an EVP_PKEY OpenSSL object for a given key
- * Returns private or public key depending on isPrivate
+ * Returns the key type specified in object_class.
*/
-EVP_PKEY *pkcs11_get_key(PKCS11_KEY *key, int isPrivate)
+EVP_PKEY *pkcs11_get_key(PKCS11_OBJECT_private *key0, CK_OBJECT_CLASS object_class)
{
- if (key->isPrivate != isPrivate)
- key = pkcs11_find_key_from_key(key);
- if (!key)
- return NULL;
+ PKCS11_OBJECT_private *key = key0;
+ EVP_PKEY *ret = NULL;
+
+ if (key->object_class != object_class)
+ key = pkcs11_object_from_object(key, CK_INVALID_HANDLE, object_class);
+ if (!key || !key->ops)
+ goto err;
if (!key->evp_key) {
- PKCS11_KEY_private *kpriv = PRIVKEY(key);
- key->evp_key = kpriv->ops->get_evp_key(key);
+ key->evp_key = key->ops->get_evp_key(key);
if (!key->evp_key)
- return NULL;
- kpriv->always_authenticate = CK_FALSE;
- if (isPrivate && key_getattr_val(key, CKA_ALWAYS_AUTHENTICATE,
- &kpriv->always_authenticate, sizeof(CK_BBOOL))) {
-#ifdef DEBUG
- fprintf(stderr, "Missing CKA_ALWAYS_AUTHENTICATE attribute\n");
-#endif
- }
+ goto err;
}
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL )
EVP_PKEY_up_ref(key->evp_key);
#else
CRYPTO_add(&key->evp_key->references, 1, CRYPTO_LOCK_EVP_PKEY);
#endif
- return key->evp_key;
+ ret = key->evp_key;
+err:
+ if (key != key0)
+ pkcs11_object_free(key);
+ return ret;
}
/*
* Authenticate a private the key operation if needed
* This function *only* handles CKU_CONTEXT_SPECIFIC logins.
*/
-int pkcs11_authenticate(PKCS11_KEY *key)
+int pkcs11_authenticate(PKCS11_OBJECT_private *key, CK_SESSION_HANDLE session)
{
- PKCS11_TOKEN *token = KEY2TOKEN(key);
- PKCS11_SLOT *slot = TOKEN2SLOT(token);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
+ PKCS11_SLOT_private *slot = key->slot;
+ PKCS11_CTX_private *ctx = slot->ctx;
char pin[MAX_PIN_LENGTH+1];
char* prompt;
UI *ui;
int rv;
/* Handle CKF_PROTECTED_AUTHENTICATION_PATH */
- if (token->secureLogin) {
+ if (slot->secure_login) {
rv = CRYPTOKI_call(ctx,
- C_Login(spriv->session, CKU_CONTEXT_SPECIFIC, NULL, 0));
+ C_Login(session, CKU_CONTEXT_SPECIFIC, NULL, 0));
return rv == CKR_USER_ALREADY_LOGGED_IN ? 0 : rv;
}
/* Call UI to ask for a PIN */
- ui = UI_new_method(cpriv->ui_method);
+ ui = UI_new_method(ctx->ui_method);
if (!ui)
return P11_R_UI_FAILED;
- if (cpriv->ui_user_data)
- UI_add_user_data(ui, cpriv->ui_user_data);
+ if (ctx->ui_user_data)
+ UI_add_user_data(ui, ctx->ui_user_data);
memset(pin, 0, MAX_PIN_LENGTH+1);
prompt = UI_construct_prompt(ui, "PKCS#11 key PIN", key->label);
if (!prompt) {
@@ -394,7 +510,7 @@
/* Login with the PIN */
rv = CRYPTOKI_call(ctx,
- C_Login(spriv->session, CKU_CONTEXT_SPECIFIC,
+ C_Login(session, CKU_CONTEXT_SPECIFIC,
(CK_UTF8CHAR *)pin, strlen(pin)));
OPENSSL_cleanse(pin, MAX_PIN_LENGTH+1);
return rv == CKR_USER_ALREADY_LOGGED_IN ? 0 : rv;
@@ -404,40 +520,23 @@
* Return keys of a given type (public or private)
* Use the cached values if available
*/
-int pkcs11_enumerate_keys(PKCS11_TOKEN *token, unsigned int type,
- PKCS11_KEY ** keyp, unsigned int *countp)
+int pkcs11_enumerate_keys(PKCS11_SLOT_private *slot, unsigned int type,
+ PKCS11_KEY **keyp, unsigned int *countp)
{
- PKCS11_SLOT *slot = TOKEN2SLOT(token);
- PKCS11_CTX *ctx = TOKEN2CTX(token);
- PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
- PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
- PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &tpriv->prv : &tpriv->pub;
- PKCS11_KEY *first_key_prev = keys->keys;
+ PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &slot->prv : &slot->pub;
+ CK_SESSION_HANDLE session;
int rv;
- int i;
- /* Make sure we have a session */
- if (!spriv->haveSession && PKCS11_open_session(slot, 0))
+ if (pkcs11_get_session(slot, 0, &session))
return -1;
- CRYPTO_THREAD_write_lock(cpriv->rwlock);
- rv = pkcs11_find_keys(token, type);
- CRYPTO_THREAD_unlock(cpriv->rwlock);
+ rv = pkcs11_find_keys(slot, session, type);
+ pkcs11_put_session(slot, session);
if (rv < 0) {
- pkcs11_destroy_keys(token, type);
+ pkcs11_destroy_keys(slot, type);
return -1;
}
- /* Always update key references if the keys pointer changed */
- if (first_key_prev && first_key_prev != keys->keys) {
- for (i = 0; i < keys->num; ++i) {
- PKCS11_KEY *key = keys->keys + i;
- PKCS11_KEY_private *kpriv = PRIVKEY(key);
- kpriv->ops->update_ex_data(key);
- }
- }
-
if (keyp)
*keyp = keys->keys;
if (countp)
@@ -446,59 +545,31 @@
}
/**
- * Remove a key from the associated token
+ * Remove an object from the associated token
*/
-int pkcs11_remove_key(PKCS11_KEY *key) {
- PKCS11_SLOT *slot = KEY2SLOT(key);
- PKCS11_CTX *ctx = KEY2CTX(key);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
- CK_OBJECT_HANDLE obj;
- CK_ULONG count;
- CK_ATTRIBUTE search_parameters[32];
- unsigned int n = 0;
+int pkcs11_remove_object(PKCS11_OBJECT_private *obj)
+{
+ PKCS11_SLOT_private *slot = obj->slot;
+ PKCS11_CTX_private *ctx = slot->ctx;
+ CK_SESSION_HANDLE session;
int rv;
- /* First, make sure we have a session */
- if (!spriv->haveSession && PKCS11_open_session(slot, 1))
+ if (pkcs11_get_session(slot, 1, &session))
return -1;
- if (key->isPrivate)
- pkcs11_addattr_int(search_parameters + n++, CKA_CLASS, CKO_PRIVATE_KEY);
- else
- pkcs11_addattr_int(search_parameters + n++, CKA_CLASS, CKO_PUBLIC_KEY);
- if (key->id && key->id_len)
- pkcs11_addattr(search_parameters + n++, CKA_ID, key->id, key->id_len);
- if (key->label)
- pkcs11_addattr_s(search_parameters + n++, CKA_LABEL, key->label);
-
- rv = CRYPTOKI_call(ctx,
- C_FindObjectsInit(spriv->session, search_parameters, n));
- CRYPTOKI_checkerr(CKR_F_PKCS11_REMOVE_KEY, rv);
- rv = CRYPTOKI_call(ctx, C_FindObjects(spriv->session, &obj, 1, &count));
+ rv = CRYPTOKI_call(ctx, C_DestroyObject(session, obj->object));
+ pkcs11_put_session(slot, session);
CRYPTOKI_checkerr(CKR_F_PKCS11_REMOVE_KEY, rv);
- CRYPTOKI_call(ctx, C_FindObjectsFinal(spriv->session));
- if (count!=1) {
- pkcs11_zap_attrs(search_parameters, n);
- return -1;
- }
- rv = CRYPTOKI_call(ctx, C_DestroyObject(spriv->session, obj));
- if (rv != CKR_OK) {
- pkcs11_zap_attrs(search_parameters, n);
- return -1;
- }
- pkcs11_zap_attrs(search_parameters, n);
return 0;
}
/*
* Find all keys of a given type (public or private)
*/
-static int pkcs11_find_keys(PKCS11_TOKEN *token, unsigned int type)
+static int pkcs11_find_keys(PKCS11_SLOT_private *slot, CK_SESSION_HANDLE session, unsigned int type)
{
- PKCS11_SLOT *slot = TOKEN2SLOT(token);
- PKCS11_CTX *ctx = TOKEN2CTX(token);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_CTX_private *ctx = slot->ctx;
CK_OBJECT_CLASS key_search_class;
CK_ATTRIBUTE key_search_attrs[1] = {
{CKA_CLASS, &key_search_class, sizeof(key_search_class)},
@@ -508,19 +579,19 @@
/* Tell the PKCS11 lib to enumerate all matching objects */
key_search_class = type;
rv = CRYPTOKI_call(ctx,
- C_FindObjectsInit(spriv->session, key_search_attrs, 1));
+ C_FindObjectsInit(session, key_search_attrs, 1));
CRYPTOKI_checkerr(CKR_F_PKCS11_FIND_KEYS, rv);
do {
- res = pkcs11_next_key(ctx, token, spriv->session, type);
+ res = pkcs11_next_key(ctx, slot, session, type);
} while (res == 0);
- CRYPTOKI_call(ctx, C_FindObjectsFinal(spriv->session));
+ CRYPTOKI_call(ctx, C_FindObjectsFinal(session));
return (res < 0) ? -1 : 0;
}
-static int pkcs11_next_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
+static int pkcs11_next_key(PKCS11_CTX_private *ctx, PKCS11_SLOT_private *slot,
CK_SESSION_HANDLE session, CK_OBJECT_CLASS type)
{
CK_OBJECT_HANDLE obj;
@@ -534,80 +605,51 @@
if (count == 0)
return 1;
- if (pkcs11_init_key(ctx, token, session, obj, type, NULL))
+ if (pkcs11_init_key(slot, session, obj, type, NULL))
return -1;
return 0;
}
-static int pkcs11_init_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
- CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj,
- CK_OBJECT_CLASS type, PKCS11_KEY ** ret)
-{
- PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
- PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &tpriv->prv : &tpriv->pub;
- PKCS11_KEY_private *kpriv;
+static int pkcs11_init_key(PKCS11_SLOT_private *slot, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object, CK_OBJECT_CLASS type, PKCS11_KEY **ret)
+{
+ PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &slot->prv : &slot->pub;
+ PKCS11_OBJECT_private *kpriv;
PKCS11_KEY *key, *tmp;
- CK_KEY_TYPE key_type;
- PKCS11_KEY_ops *ops;
- size_t size;
int i;
- (void)ctx;
- (void)session;
-
- /* Ignore unknown key types */
- size = sizeof(CK_KEY_TYPE);
- if (pkcs11_getattr_var(token, obj, CKA_KEY_TYPE, (CK_BYTE *)&key_type, &size))
- return -1;
- switch (key_type) {
- case CKK_RSA:
- ops = &pkcs11_rsa_ops;
- break;
- case CKK_EC:
- ops = pkcs11_ec_ops;
- if (!ops)
- return 0; /* not supported */
- break;
- default:
- /* Ignore any keys we don't understand */
- return 0;
- }
-
/* Prevent re-adding existing PKCS#11 object handles */
/* TODO: Rewrite the O(n) algorithm as O(log n),
* or it may be too slow with a large number of keys */
- for (i=0; i < keys->num; ++i)
- if (PRIVKEY(keys->keys + i)->object == obj)
+ for (i = 0; i < keys->num; ++i) {
+ if (PRIVKEY(&keys->keys[i])->object == object) {
+ if (ret)
+ *ret = &keys->keys[i];
return 0;
+ }
+ }
- /* Allocate memory */
- kpriv = OPENSSL_malloc(sizeof(PKCS11_KEY_private));
+ kpriv = pkcs11_object_from_handle(slot, session, object);
if (!kpriv)
return -1;
- memset(kpriv, 0, sizeof(PKCS11_KEY_private));
+
+ /* Allocate memory */
tmp = OPENSSL_realloc(keys->keys, (keys->num + 1) * sizeof(PKCS11_KEY));
- if (!tmp)
+ if (!tmp) {
+ pkcs11_object_free(kpriv);
return -1;
+ }
keys->keys = tmp;
key = keys->keys + keys->num++;
memset(key, 0, sizeof(PKCS11_KEY));
/* Fill public properties */
- pkcs11_getattr_alloc(token, obj, CKA_LABEL, (CK_BYTE **)&key->label, NULL);
- key->id_len = 0;
- pkcs11_getattr_alloc(token, obj, CKA_ID, &key->id, &key->id_len);
- key->isPrivate = (type == CKO_PRIVATE_KEY);
-
- /* Fill private properties */
key->_private = kpriv;
- kpriv->object = obj;
- kpriv->parent = token;
- kpriv->id_len = sizeof kpriv->id;
- if (pkcs11_getattr_var(token, obj, CKA_ID, kpriv->id, &kpriv->id_len))
- kpriv->id_len = 0;
- kpriv->ops = ops;
- kpriv->forkid = get_forkid();
+ key->id = kpriv->id;
+ key->id_len = kpriv->id_len;
+ key->label = kpriv->label;
+ key->isPrivate = (type == CKO_PRIVATE_KEY);
if (ret)
*ret = key;
@@ -617,22 +659,14 @@
/*
* Destroy all keys of a given type (public or private)
*/
-void pkcs11_destroy_keys(PKCS11_TOKEN *token, unsigned int type)
+void pkcs11_destroy_keys(PKCS11_SLOT_private *slot, unsigned int type)
{
- PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
- PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &tpriv->prv : &tpriv->pub;
+ PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &slot->prv : &slot->pub;
while (keys->num > 0) {
- PKCS11_KEY *key = &keys->keys[--(keys->num)];
-
- if (key->evp_key)
- EVP_PKEY_free(key->evp_key);
- if (key->label)
- OPENSSL_free(key->label);
- if (key->id)
- OPENSSL_free(key->id);
+ PKCS11_KEY *key = &keys->keys[--keys->num];
if (key->_private)
- OPENSSL_free(key->_private);
+ pkcs11_object_free(PRIVKEY(key));
}
if (keys->keys)
OPENSSL_free(keys->keys);
diff -Nru libp11-0.4.11/src/p11_load.c libp11-0.4.12/src/p11_load.c
--- libp11-0.4.11/src/p11_load.c 2020-10-04 22:13:22.000000000 +0200
+++ libp11-0.4.12/src/p11_load.c 2022-05-04 18:45:56.000000000 +0200
@@ -40,9 +40,7 @@
memset(ctx, 0, sizeof(PKCS11_CTX));
ctx->_private = cpriv;
cpriv->forkid = get_forkid();
- cpriv->rwlock = CRYPTO_THREAD_lock_new();
- cpriv->sign_initialized = 0;
- cpriv->decrypt_initialized = 0;
+ pthread_mutex_init(&cpriv->fork_lock, 0);
return ctx;
fail:
@@ -113,23 +111,22 @@
/*
* Reinitialize (e.g., after a fork).
*/
-int pkcs11_CTX_reload(PKCS11_CTX *ctx)
+int pkcs11_CTX_reload(PKCS11_CTX_private *ctx)
{
- PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
CK_C_INITIALIZE_ARGS _args;
CK_C_INITIALIZE_ARGS *args = NULL;
int rv;
- if (!cpriv->method) /* Module not loaded */
+ if (!ctx->method) /* Module not loaded */
return 0;
/* Tell the PKCS11 to initialize itself */
- if (cpriv->init_args) {
+ if (ctx->init_args) {
memset(&_args, 0, sizeof(_args));
args = &_args;
- args->pReserved = cpriv->init_args;
+ args->pReserved = ctx->init_args;
}
- rv = cpriv->method->C_Initialize(args);
+ rv = ctx->method->C_Initialize(args);
if (rv && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
CKRerr(P11_F_PKCS11_CTX_RELOAD, rv);
return -1;
@@ -172,7 +169,7 @@
if (cpriv->handle) {
OPENSSL_free(cpriv->handle);
}
- CRYPTO_THREAD_lock_free(cpriv->rwlock);
+ pthread_mutex_destroy(&cpriv->fork_lock);
OPENSSL_free(ctx->manufacturer);
OPENSSL_free(ctx->description);
OPENSSL_free(ctx->_private);
diff -Nru libp11-0.4.11/src/p11_misc.c libp11-0.4.12/src/p11_misc.c
--- libp11-0.4.11/src/p11_misc.c 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/src/p11_misc.c 2022-07-05 22:22:51.000000000 +0200
@@ -39,32 +39,25 @@
return res;
}
-/*
- * CRYPTO dynlock wrappers: 0 is an invalid dynamic lock ID
- */
-
-#if OPENSSL_VERSION_NUMBER < 0x10100004L || defined(LIBRESSL_VERSION_NUMBER)
-
-int CRYPTO_THREAD_lock_new()
-{
- int i;
-
- if (CRYPTO_get_dynlock_create_callback() == NULL ||
- CRYPTO_get_dynlock_lock_callback() == NULL ||
- CRYPTO_get_dynlock_destroy_callback() == NULL)
- return 0; /* Dynamic callbacks not set */
- i = CRYPTO_get_new_dynlockid();
- if (i == 0)
- ERR_clear_error(); /* Dynamic locks are optional -> ignore */
- return i;
-}
-
-void CRYPTO_THREAD_lock_free(int i)
+int pkcs11_atomic_add(int *value, int amount, pthread_mutex_t *lock)
{
- if (i)
- CRYPTO_destroy_dynlockid(i);
-}
+#if defined( _WIN32)
+ (void) lock;
+ /* both int and long are 32-bit on all WIN32 platforms */
+ return InterlockedExchangeAdd((LONG *)value, amount) + amount;
+#elif defined(__GNUC__) && defined(__ATOMIC_ACQ_REL)
+ (void) lock;
+ return __atomic_add_fetch(value, amount, __ATOMIC_ACQ_REL);
+#else
+ int ret;
+
+ pthread_mutex_lock(lock);
+ *value += amount;
+ ret = *value;
+ pthread_mutex_unlock(lock);
+ return ret;
#endif
+}
/* vim: set noexpandtab: */
diff -Nru libp11-0.4.11/src/p11_pkey.c libp11-0.4.12/src/p11_pkey.c
--- libp11-0.4.11/src/p11_pkey.c 2020-10-11 15:41:03.000000000 +0200
+++ libp11-0.4.12/src/p11_pkey.c 2022-07-15 21:48:10.000000000 +0200
@@ -197,6 +197,16 @@
return CKM_SHA512;
case NID_sha384:
return CKM_SHA384;
+#if !defined(LIBRESSL_VERSION_NUMBER)
+ case NID_sha3_224:
+ return CKM_SHA3_224;
+ case NID_sha3_256:
+ return CKM_SHA3_256;
+ case NID_sha3_384:
+ return CKM_SHA3_384;
+ case NID_sha3_512:
+ return CKM_SHA3_512;
+#endif
default:
return 0;
}
@@ -215,6 +225,16 @@
return CKG_MGF1_SHA512;
case NID_sha384:
return CKG_MGF1_SHA384;
+#if !defined(LIBRESSL_VERSION_NUMBER)
+ case NID_sha3_224:
+ return CKG_MGF1_SHA3_224;
+ case NID_sha3_256:
+ return CKG_MGF1_SHA3_256;
+ case NID_sha3_384:
+ return CKG_MGF1_SHA3_384;
+ case NID_sha3_512:
+ return CKG_MGF1_SHA3_512;
+#endif
default:
return 0;
}
@@ -285,8 +305,8 @@
if (!oaep->hashAlg || !oaep->mgf)
return -1;
/* we do not support the OAEP "label" parameter yet... */
- oaep->source = 0UL; /* empty parameter (label) */
- oaep->pSourceData = NULL;
+ oaep->source = CKZ_DATA_SPECIFIED;
+ oaep->pSourceData = NULL; /* empty parameter (label) */
oaep->ulSourceDataLen = 0;
return 0;
}
@@ -297,36 +317,39 @@
{
EVP_PKEY *pkey;
RSA *rsa;
- PKCS11_KEY *key;
- int rv = 0;
+ int rv = 0, padding;
CK_ULONG size = *siglen;
- PKCS11_SLOT *slot;
- PKCS11_CTX *ctx;
- PKCS11_KEY_private *kpriv;
- PKCS11_SLOT_private *spriv;
- PKCS11_CTX_private *cpriv;
+ PKCS11_OBJECT_private *key;
+ PKCS11_SLOT_private *slot;
+ PKCS11_CTX_private *ctx;
const EVP_MD *sig_md;
+ CK_SESSION_HANDLE session;
+ CK_MECHANISM mechanism;
+ CK_RSA_PKCS_PSS_PARAMS pss_params;
#ifdef DEBUG
fprintf(stderr, "%s:%d pkcs11_try_pkey_rsa_sign() "
"sig=%p *siglen=%lu tbs=%p tbslen=%lu\n",
__FILE__, __LINE__, sig, *siglen, tbs, tbslen);
#endif
+ /* RSA method has EVP_PKEY_FLAG_AUTOARGLEN set. OpenSSL core will handle
+ * the size inquiry internally. */
+ if (!sig)
+ return -1;
+
pkey = EVP_PKEY_CTX_get0_pkey(evp_pkey_ctx);
if (!pkey)
return -1;
- rsa = EVP_PKEY_get0_RSA(pkey);
+ rsa = (RSA *)EVP_PKEY_get0_RSA(pkey);
if (!rsa)
return -1;
+
key = pkcs11_get_ex_data_rsa(rsa);
- if (check_key_fork(key) < 0)
+ if (check_object_fork(key) < 0)
return -1;
- slot = KEY2SLOT(key);
- ctx = KEY2CTX(key);
- kpriv = PRIVKEY(key);
- spriv = PRIVSLOT(slot);
- cpriv = PRIVCTX(ctx);
+ slot = key->slot;
+ ctx = slot->ctx;
if (!evp_pkey_ctx)
return -1;
if (EVP_PKEY_CTX_get_signature_md(evp_pkey_ctx, &sig_md) <= 0)
@@ -334,45 +357,39 @@
if (tbslen != (size_t)EVP_MD_size(sig_md))
return -1;
- if (!cpriv->sign_initialized) {
- int padding;
- CK_MECHANISM mechanism;
- CK_RSA_PKCS_PSS_PARAMS pss_params;
-
- memset(&mechanism, 0, sizeof mechanism);
- EVP_PKEY_CTX_get_rsa_padding(evp_pkey_ctx, &padding);
- switch (padding) {
- case RSA_PKCS1_PSS_PADDING:
-#ifdef DEBUG
- fprintf(stderr, "%s:%d padding=RSA_PKCS1_PSS_PADDING\n",
- __FILE__, __LINE__);
-#endif
- if (pkcs11_params_pss(&pss_params, evp_pkey_ctx) < 0)
- return -1;
- mechanism.mechanism = CKM_RSA_PKCS_PSS;
- mechanism.pParameter = &pss_params;
- mechanism.ulParameterLen = sizeof pss_params;
- break;
- default:
+ memset(&mechanism, 0, sizeof mechanism);
+ EVP_PKEY_CTX_get_rsa_padding(evp_pkey_ctx, &padding);
+ switch (padding) {
+ case RSA_PKCS1_PSS_PADDING:
#ifdef DEBUG
- fprintf(stderr, "%s:%d unsupported padding: %d\n",
- __FILE__, __LINE__, padding);
+ fprintf(stderr, "%s:%d padding=RSA_PKCS1_PSS_PADDING\n",
+ __FILE__, __LINE__);
#endif
+ if (pkcs11_params_pss(&pss_params, evp_pkey_ctx) < 0)
return -1;
- } /* end switch(padding) */
+ mechanism.mechanism = CKM_RSA_PKCS_PSS;
+ mechanism.pParameter = &pss_params;
+ mechanism.ulParameterLen = sizeof pss_params;
+ break;
+ default:
+#ifdef DEBUG
+ fprintf(stderr, "%s:%d unsupported padding: %d\n",
+ __FILE__, __LINE__, padding);
+#endif
+ return -1;
+ } /* end switch(padding) */
- CRYPTO_THREAD_write_lock(cpriv->rwlock);
- rv = CRYPTOKI_call(ctx,
- C_SignInit(spriv->session, &mechanism, kpriv->object));
- if (!rv && kpriv->always_authenticate == CK_TRUE)
- rv = pkcs11_authenticate(key);
- }
+ if (pkcs11_get_session(slot, 0, &session))
+ return -1;
+
+ rv = CRYPTOKI_call(ctx,
+ C_SignInit(session, &mechanism, key->object));
+ if (!rv && key->always_authenticate == CK_TRUE)
+ rv = pkcs11_authenticate(key, session);
if (!rv)
rv = CRYPTOKI_call(ctx,
- C_Sign(spriv->session, (CK_BYTE_PTR)tbs, tbslen, sig, &size));
- cpriv->sign_initialized = !rv && sig == NULL;
- if (!cpriv->sign_initialized)
- CRYPTO_THREAD_unlock(cpriv->rwlock);
+ C_Sign(session, (CK_BYTE_PTR)tbs, tbslen, sig, &size));
+ pkcs11_put_session(slot, session);
#ifdef DEBUG
fprintf(stderr, "%s:%d C_SignInit or C_Sign rv=%d\n",
__FILE__, __LINE__, rv);
@@ -402,85 +419,84 @@
{
EVP_PKEY *pkey;
RSA *rsa;
- PKCS11_KEY *key;
- int rv = 0;
+ int rv = 0, padding;
CK_ULONG size = *outlen;
- PKCS11_SLOT *slot;
- PKCS11_CTX *ctx;
- PKCS11_KEY_private *kpriv;
- PKCS11_SLOT_private *spriv;
- PKCS11_CTX_private *cpriv;
+ PKCS11_OBJECT_private *key;
+ PKCS11_SLOT_private *slot;
+ PKCS11_CTX_private *ctx;
+ CK_SESSION_HANDLE session;
+ CK_MECHANISM mechanism;
+ CK_RSA_PKCS_OAEP_PARAMS oaep_params;
#ifdef DEBUG
fprintf(stderr, "%s:%d pkcs11_try_pkey_rsa_decrypt() "
"out=%p *outlen=%lu in=%p inlen=%lu\n",
__FILE__, __LINE__, out, *outlen, in, inlen);
#endif
+ /* RSA method has EVP_PKEY_FLAG_AUTOARGLEN set. OpenSSL core will handle
+ * the size inquiry internally. */
+ if (!out)
+ return -1;
+
pkey = EVP_PKEY_CTX_get0_pkey(evp_pkey_ctx);
if (!pkey)
return -1;
- rsa = EVP_PKEY_get0_RSA(pkey);
+ rsa = (RSA *)EVP_PKEY_get0_RSA(pkey);
if (!rsa)
return -1;
+
key = pkcs11_get_ex_data_rsa(rsa);
- if (check_key_fork(key) < 0)
+ if (check_object_fork(key) < 0)
return -1;
- slot = KEY2SLOT(key);
- ctx = KEY2CTX(key);
- kpriv = PRIVKEY(key);
- spriv = PRIVSLOT(slot);
- cpriv = PRIVCTX(ctx);
+
+ slot = key->slot;
+ ctx = slot->ctx;
if (!evp_pkey_ctx)
return -1;
- if (!cpriv->decrypt_initialized) {
- int padding;
- CK_MECHANISM mechanism;
- CK_RSA_PKCS_OAEP_PARAMS oaep_params;
-
- memset(&mechanism, 0, sizeof mechanism);
- EVP_PKEY_CTX_get_rsa_padding(evp_pkey_ctx, &padding);
- switch (padding) {
- case RSA_PKCS1_OAEP_PADDING:
-#ifdef DEBUG
- fprintf(stderr, "%s:%d padding=RSA_PKCS1_OAEP_PADDING\n",
- __FILE__, __LINE__);
-#endif
- if (pkcs11_params_oaep(&oaep_params, evp_pkey_ctx) < 0)
- return -1;
- mechanism.mechanism = CKM_RSA_PKCS_OAEP;
- mechanism.pParameter = &oaep_params;
- mechanism.ulParameterLen = sizeof oaep_params;
- break;
- case CKM_RSA_PKCS:
-#ifdef DEBUG
- fprintf(stderr, "%s:%d padding=CKM_RSA_PKCS\n",
- __FILE__, __LINE__);
-#endif
- mechanism.pParameter = NULL;
- mechanism.ulParameterLen = 0;
- break;
- default:
+ memset(&mechanism, 0, sizeof mechanism);
+ EVP_PKEY_CTX_get_rsa_padding(evp_pkey_ctx, &padding);
+ switch (padding) {
+ case RSA_PKCS1_OAEP_PADDING:
#ifdef DEBUG
- fprintf(stderr, "%s:%d unsupported padding: %d\n",
- __FILE__, __LINE__, padding);
+ fprintf(stderr, "%s:%d padding=RSA_PKCS1_OAEP_PADDING\n",
+ __FILE__, __LINE__);
#endif
+ if (pkcs11_params_oaep(&oaep_params, evp_pkey_ctx) < 0)
return -1;
- } /* end switch(padding) */
+ mechanism.mechanism = CKM_RSA_PKCS_OAEP;
+ mechanism.pParameter = &oaep_params;
+ mechanism.ulParameterLen = sizeof oaep_params;
+ break;
+ case RSA_PKCS1_PADDING:
+#ifdef DEBUG
+ fprintf(stderr, "%s:%d padding=RSA_PKCS1_PADDING\n",
+ __FILE__, __LINE__);
+#endif
+ mechanism.mechanism = CKM_RSA_PKCS;
+ mechanism.pParameter = NULL;
+ mechanism.ulParameterLen = 0;
+ break;
+ default:
+#ifdef DEBUG
+ fprintf(stderr, "%s:%d unsupported padding: %d\n",
+ __FILE__, __LINE__, padding);
+#endif
+ return -1;
+ } /* end switch(padding) */
- CRYPTO_THREAD_write_lock(cpriv->rwlock);
- rv = CRYPTOKI_call(ctx,
- C_DecryptInit(spriv->session, &mechanism, kpriv->object));
- if (!rv && kpriv->always_authenticate == CK_TRUE)
- rv = pkcs11_authenticate(key);
- }
+ if (pkcs11_get_session(slot, 0, &session))
+ return -1;
+
+ rv = CRYPTOKI_call(ctx,
+ C_DecryptInit(session, &mechanism, key->object));
+ if (!rv && key->always_authenticate == CK_TRUE)
+ rv = pkcs11_authenticate(key, session);
if (!rv)
rv = CRYPTOKI_call(ctx,
- C_Decrypt(spriv->session, (CK_BYTE_PTR)in, inlen, out, &size));
- cpriv->decrypt_initialized = !rv && out == NULL;
- if (!cpriv->decrypt_initialized)
- CRYPTO_THREAD_unlock(cpriv->rwlock);
+ C_Decrypt(session, (CK_BYTE_PTR)in, inlen, out, &size));
+ pkcs11_put_session(slot, session);
#ifdef DEBUG
fprintf(stderr, "%s:%d C_DecryptInit or C_Decrypt rv=%d\n",
__FILE__, __LINE__, rv);
@@ -541,16 +557,15 @@
{
EVP_PKEY *pkey;
EC_KEY *eckey;
- PKCS11_KEY *key;
int rv = CKR_GENERAL_ERROR;
CK_ULONG size = *siglen;
- PKCS11_SLOT *slot;
- PKCS11_CTX *ctx;
- PKCS11_KEY_private *kpriv;
- PKCS11_SLOT_private *spriv;
- PKCS11_CTX_private *cpriv;
+ PKCS11_OBJECT_private *key;
+ PKCS11_SLOT_private *slot;
+ PKCS11_CTX_private *ctx;
+ CK_SESSION_HANDLE session;
const EVP_MD *sig_md;
ECDSA_SIG *ossl_sig;
+ CK_MECHANISM mechanism;
#ifdef DEBUG
fprintf(stderr, "%s:%d pkcs11_try_pkey_ec_sign() "
@@ -570,18 +585,21 @@
if (!eckey)
goto error;
+ if (!sig) {
+ *siglen = (size_t)ECDSA_size(eckey);
+ rv = CKR_OK;
+ goto error;
+ }
+
if (*siglen < (size_t)ECDSA_size(eckey))
goto error;
key = pkcs11_get_ex_data_ec(eckey);
- if (check_key_fork(key) < 0)
+ if (check_object_fork(key) < 0)
goto error;
- slot = KEY2SLOT(key);
- ctx = KEY2CTX(key);
- kpriv = PRIVKEY(key);
- spriv = PRIVSLOT(slot);
- cpriv = PRIVCTX(ctx);
+ slot = key->slot;
+ ctx = slot->ctx;
if (!evp_pkey_ctx)
goto error;
@@ -593,25 +611,20 @@
goto error;
rv = 0;
- if (!cpriv->sign_initialized) {
- CK_MECHANISM mechanism;
- memset(&mechanism, 0, sizeof mechanism);
+ memset(&mechanism, 0, sizeof mechanism);
+ mechanism.mechanism = CKM_ECDSA;
- mechanism.mechanism = CKM_ECDSA;
-
- CRYPTO_THREAD_write_lock(cpriv->rwlock);
- rv = CRYPTOKI_call(ctx,
- C_SignInit(spriv->session, &mechanism, kpriv->object));
- if (!rv && kpriv->always_authenticate == CK_TRUE)
- rv = pkcs11_authenticate(key);
- }
+ if (pkcs11_get_session(slot, 0, &session))
+ return -1;
+ rv = CRYPTOKI_call(ctx,
+ C_SignInit(session, &mechanism, key->object));
+ if (!rv && key->always_authenticate == CK_TRUE)
+ rv = pkcs11_authenticate(key, session);
if (!rv)
rv = CRYPTOKI_call(ctx,
- C_Sign(spriv->session, (CK_BYTE_PTR)tbs, tbslen, sig, &size));
+ C_Sign(session, (CK_BYTE_PTR)tbs, tbslen, sig, &size));
+ pkcs11_put_session(slot, session);
- cpriv->sign_initialized = !rv && sig == NULL;
- if (!cpriv->sign_initialized)
- CRYPTO_THREAD_unlock(cpriv->rwlock);
#ifdef DEBUG
fprintf(stderr, "%s:%d C_SignInit or C_Sign rv=%d\n",
__FILE__, __LINE__, rv);
@@ -621,7 +634,7 @@
BIGNUM *r = BN_bin2bn(sig, size/2, NULL);
BIGNUM *s = BN_bin2bn(sig + size/2, size/2, NULL);
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL )
ECDSA_SIG_set0(ossl_sig, r, s);
#else
BN_free(ossl_sig->r);
diff -Nru libp11-0.4.11/src/p11_pthread.h libp11-0.4.12/src/p11_pthread.h
--- libp11-0.4.11/src/p11_pthread.h 1970-01-01 01:00:00.000000000 +0100
+++ libp11-0.4.12/src/p11_pthread.h 2021-10-30 14:20:08.000000000 +0200
@@ -0,0 +1,94 @@
+/* libp11, a simple layer on to of PKCS#11 API
+ * Copyright (C) 2017 Douglas E. Engert <deengert at gmail.com>
+ * Copyright (C) 2017-2018 Michał Trojnara <Michal.Trojnara at stunnel.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#if defined(HAVE_PTHREAD)
+
+#include <pthread.h>
+
+#elif defined( _WIN32)
+
+/* Simple wrappers for used pthread API using Windows Vista+ APIs. */
+#if _WIN32_WINNT < 0x0600
+#error Windows Vista (or Server 2008) or later required.
+#endif
+
+#include <windows.h>
+
+typedef CRITICAL_SECTION pthread_mutex_t;
+typedef void pthread_mutexattr_t;
+
+static int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr)
+{
+ (void)attr;
+ InitializeCriticalSection(mutex);
+ return 0;
+}
+
+static int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+ DeleteCriticalSection(mutex);
+ return 0;
+}
+
+static int pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+ EnterCriticalSection(mutex);
+ return 0;
+}
+
+static int pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+ LeaveCriticalSection(mutex);
+ return 0;
+}
+
+typedef CONDITION_VARIABLE pthread_cond_t;
+typedef void pthread_condattr_t;
+
+static int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr)
+{
+ (void)attr;
+ InitializeConditionVariable(cond);
+ return 0;
+}
+
+static int pthread_cond_destroy(pthread_cond_t *cond)
+{
+ (void)cond;
+ return 0;
+}
+
+static int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+ if (!SleepConditionVariableCS(cond, mutex, INFINITE))
+ return 1;
+ return 0;
+}
+
+static int pthread_cond_signal(pthread_cond_t *cond)
+{
+ WakeConditionVariable(cond);
+ return 0;
+}
+
+#else
+
+#error Locking not supported on this platform.
+
+#endif
diff -Nru libp11-0.4.11/src/p11_rsa.c libp11-0.4.12/src/p11_rsa.c
--- libp11-0.4.11/src/p11_rsa.c 2020-10-11 15:41:00.000000000 +0200
+++ libp11-0.4.12/src/p11_rsa.c 2022-07-05 22:22:51.000000000 +0200
@@ -29,13 +29,16 @@
static int rsa_ex_index = 0;
-static RSA *pkcs11_rsa(PKCS11_KEY *key)
+static RSA *pkcs11_rsa(PKCS11_OBJECT_private *key)
{
- EVP_PKEY *evp_key = pkcs11_get_key(key, key->isPrivate);
+ EVP_PKEY *evp_key = pkcs11_get_key(key, key->object_class);
RSA *rsa;
if (!evp_key)
return NULL;
- rsa = EVP_PKEY_get0_RSA(evp_key);
+ rsa = (RSA *)EVP_PKEY_get0_RSA(evp_key);
+ /* Danger: this assumes evp_key returned above has at least reference
+ * count of 2. Which is true in current code as long as key->object_class
+ * is used for the object_class. */
EVP_PKEY_free(evp_key);
return rsa;
}
@@ -43,7 +46,7 @@
/* PKCS#1 v1.5 RSA signature */
/* TODO: remove this function in libp11 0.5.0 */
int pkcs11_sign(int type, const unsigned char *m, unsigned int m_len,
- unsigned char *sigret, unsigned int *siglen, PKCS11_KEY *key)
+ unsigned char *sigret, unsigned int *siglen, PKCS11_OBJECT_private *key)
{
RSA *rsa = pkcs11_rsa(key);
if (!rsa)
@@ -76,14 +79,13 @@
/* OpenSSL assumes that the output buffer is always big enough */
int pkcs11_private_encrypt(int flen,
const unsigned char *from, unsigned char *to,
- PKCS11_KEY *key, int padding)
+ PKCS11_OBJECT_private *key, int padding)
{
- PKCS11_SLOT *slot = KEY2SLOT(key);
- PKCS11_CTX *ctx = KEY2CTX(key);
- PKCS11_KEY_private *kpriv = PRIVKEY(key);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_SLOT_private *slot = key->slot;
+ PKCS11_CTX_private *ctx = slot->ctx;
CK_MECHANISM mechanism;
CK_ULONG size;
+ CK_SESSION_HANDLE session;
int rv;
size = pkcs11_get_key_size(key);
@@ -91,26 +93,28 @@
if (pkcs11_mechanism(&mechanism, padding) < 0)
return -1;
- CRYPTO_THREAD_write_lock(PRIVCTX(ctx)->rwlock);
+ if (pkcs11_get_session(slot, 0, &session))
+ return -1;
+
/* Try signing first, as applications are more likely to use it */
rv = CRYPTOKI_call(ctx,
- C_SignInit(spriv->session, &mechanism, kpriv->object));
- if (!rv && kpriv->always_authenticate == CK_TRUE)
- rv = pkcs11_authenticate(key);
+ C_SignInit(session, &mechanism, key->object));
+ if (!rv && key->always_authenticate == CK_TRUE)
+ rv = pkcs11_authenticate(key, session);
if (!rv)
rv = CRYPTOKI_call(ctx,
- C_Sign(spriv->session, (CK_BYTE *)from, flen, to, &size));
+ C_Sign(session, (CK_BYTE *)from, flen, to, &size));
if (rv == CKR_KEY_FUNCTION_NOT_PERMITTED) {
/* OpenSSL may use it for encryption rather than signing */
rv = CRYPTOKI_call(ctx,
- C_EncryptInit(spriv->session, &mechanism, kpriv->object));
- if (!rv && kpriv->always_authenticate == CK_TRUE)
- rv = pkcs11_authenticate(key);
+ C_EncryptInit(session, &mechanism, key->object));
+ if (!rv && key->always_authenticate == CK_TRUE)
+ rv = pkcs11_authenticate(key, session);
if (!rv)
rv = CRYPTOKI_call(ctx,
- C_Encrypt(spriv->session, (CK_BYTE *)from, flen, to, &size));
+ C_Encrypt(session, (CK_BYTE *)from, flen, to, &size));
}
- CRYPTO_THREAD_unlock(PRIVCTX(ctx)->rwlock);
+ pkcs11_put_session(slot, session);
if (rv) {
CKRerr(CKR_F_PKCS11_PRIVATE_ENCRYPT, rv);
@@ -122,12 +126,11 @@
/* RSA private key decryption */
int pkcs11_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
- PKCS11_KEY *key, int padding)
+ PKCS11_OBJECT_private *key, int padding)
{
- PKCS11_SLOT *slot = KEY2SLOT(key);
- PKCS11_CTX *ctx = KEY2CTX(key);
- PKCS11_KEY_private *kpriv = PRIVKEY(key);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_SLOT_private *slot = key->slot;
+ PKCS11_CTX_private *ctx = slot->ctx;
+ CK_SESSION_HANDLE session;
CK_MECHANISM mechanism;
CK_ULONG size = flen;
CK_RV rv;
@@ -135,16 +138,18 @@
if (pkcs11_mechanism(&mechanism, padding) < 0)
return -1;
- CRYPTO_THREAD_write_lock(PRIVCTX(ctx)->rwlock);
+ if (pkcs11_get_session(slot, 0, &session))
+ return -1;
+
rv = CRYPTOKI_call(ctx,
- C_DecryptInit(spriv->session, &mechanism, kpriv->object));
- if (!rv && kpriv->always_authenticate == CK_TRUE)
- rv = pkcs11_authenticate(key);
+ C_DecryptInit(session, &mechanism, key->object));
+ if (!rv && key->always_authenticate == CK_TRUE)
+ rv = pkcs11_authenticate(key, session);
if (!rv)
rv = CRYPTOKI_call(ctx,
- C_Decrypt(spriv->session, (CK_BYTE *)from, size,
+ C_Decrypt(session, (CK_BYTE *)from, size,
(CK_BYTE_PTR)to, &size));
- CRYPTO_THREAD_unlock(PRIVCTX(ctx)->rwlock);
+ pkcs11_put_session(slot, session);
if (rv) {
CKRerr(CKR_F_PKCS11_PRIVATE_DECRYPT, rv);
@@ -156,7 +161,7 @@
/* TODO: remove this function in libp11 0.5.0 */
int pkcs11_verify(int type, const unsigned char *m, unsigned int m_len,
- unsigned char *signature, unsigned int siglen, PKCS11_KEY *key)
+ unsigned char *signature, unsigned int siglen, PKCS11_OBJECT_private *key)
{
(void)type;
(void)m;
@@ -173,19 +178,27 @@
/*
* Get RSA key material
*/
-static RSA *pkcs11_get_rsa(PKCS11_KEY *key)
+static RSA *pkcs11_get_rsa(PKCS11_OBJECT_private *key)
{
+ CK_OBJECT_CLASS class_public_key = CKO_PUBLIC_KEY;
+ PKCS11_SLOT_private *slot = key->slot;
+ PKCS11_CTX_private *ctx = slot->ctx;
+ PKCS11_OBJECT_private *pubkey;
+ PKCS11_TEMPLATE tmpl = {0};
+ CK_OBJECT_HANDLE object = key->object;
+ CK_SESSION_HANDLE session;
RSA *rsa;
- PKCS11_KEY *keys;
- unsigned int i, count;
BIGNUM *rsa_n = NULL, *rsa_e = NULL;
- /* Retrieve the modulus */
- if (key_getattr_bn(key, CKA_MODULUS, &rsa_n))
+ if (pkcs11_get_session(slot, 0, &session))
return NULL;
+ /* Retrieve the modulus */
+ if (pkcs11_getattr_bn(ctx, session, object, CKA_MODULUS, &rsa_n))
+ goto failure;
+
/* Retrieve the public exponent */
- if (!key_getattr_bn(key, CKA_PUBLIC_EXPONENT, &rsa_e)) {
+ if (!pkcs11_getattr_bn(ctx, session, object, CKA_PUBLIC_EXPONENT, &rsa_e)) {
if (!BN_is_zero(rsa_e)) /* A valid public exponent */
goto success;
BN_clear_free(rsa_e);
@@ -194,18 +207,15 @@
/* The public exponent was not found in the private key:
* retrieve it from the corresponding public key */
- if (!PKCS11_enumerate_public_keys(KEY2TOKEN(key), &keys, &count)) {
- for (i = 0; i < count; i++) {
- BIGNUM *pubmod = NULL;
- if (!key_getattr_bn(&keys[i], CKA_MODULUS, &pubmod)) {
- int found = BN_cmp(rsa_n, pubmod) == 0;
- BN_clear_free(pubmod);
- if (found && !key_getattr_bn(&keys[i],
- CKA_PUBLIC_EXPONENT, &rsa_e))
- goto success;
- }
- }
+ pkcs11_addattr_var(&tmpl, CKA_CLASS, class_public_key);
+ pkcs11_addattr_bn(&tmpl, CKA_MODULUS, rsa_n);
+ pubkey = pkcs11_object_from_template(slot, session, &tmpl);
+ if (pubkey && !pkcs11_getattr_bn(ctx, session, pubkey->object,
+ CKA_PUBLIC_EXPONENT, &rsa_e)) {
+ pkcs11_object_free(pubkey);
+ goto success;
}
+ pkcs11_object_free(pubkey);
/* Last resort: use the most common default */
rsa_e = BN_new();
@@ -213,6 +223,7 @@
goto success;
failure:
+ pkcs11_put_session(slot, session);
if (rsa_n)
BN_clear_free(rsa_n);
if (rsa_e)
@@ -220,10 +231,11 @@
return NULL;
success:
+ pkcs11_put_session(slot, session);
rsa = RSA_new();
if (!rsa)
goto failure;
-#if OPENSSL_VERSION_NUMBER >= 0x10100005L && !defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER >= 0x10100005L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL )
RSA_set0_key(rsa, rsa_n, rsa_e, NULL);
#else
rsa->n = rsa_n;
@@ -232,33 +244,20 @@
return rsa;
}
-PKCS11_KEY *pkcs11_get_ex_data_rsa(const RSA *rsa)
+PKCS11_OBJECT_private *pkcs11_get_ex_data_rsa(const RSA *rsa)
{
return RSA_get_ex_data(rsa, rsa_ex_index);
}
-static void pkcs11_set_ex_data_rsa(RSA *rsa, PKCS11_KEY *key)
+static void pkcs11_set_ex_data_rsa(RSA *rsa, PKCS11_OBJECT_private *key)
{
RSA_set_ex_data(rsa, rsa_ex_index, key);
}
-static void pkcs11_update_ex_data_rsa(PKCS11_KEY *key)
-{
- EVP_PKEY *evp = key->evp_key;
- RSA *rsa;
- if (!evp)
- return;
- if (EVP_PKEY_base_id(evp) != EVP_PKEY_RSA)
- return;
-
- rsa = EVP_PKEY_get1_RSA(evp);
- pkcs11_set_ex_data_rsa(rsa, key);
- RSA_free(rsa);
-}
/*
* Build an EVP_PKEY object
*/
-static EVP_PKEY *pkcs11_get_evp_key_rsa(PKCS11_KEY *key)
+static EVP_PKEY *pkcs11_get_evp_key_rsa(PKCS11_OBJECT_private *key)
{
EVP_PKEY *pk;
RSA *rsa;
@@ -271,11 +270,9 @@
RSA_free(rsa);
return NULL;
}
- EVP_PKEY_set1_RSA(pk, rsa); /* Also increments the rsa ref count */
-
- if (key->isPrivate) {
+ if (key->object_class == CKO_PRIVATE_KEY) {
RSA_set_method(rsa, PKCS11_get_rsa_method());
-#if OPENSSL_VERSION_NUMBER >= 0x10100005L && !defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER >= 0x10100005L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL )
RSA_set_flags(rsa, RSA_FLAG_EXT_PKEY);
#else
rsa->flags |= RSA_FLAG_EXT_PKEY;
@@ -289,19 +286,21 @@
rsa->flags |= RSA_FLAG_SIGN_VER;
#endif
pkcs11_set_ex_data_rsa(rsa, key);
+
+ EVP_PKEY_set1_RSA(pk, rsa); /* Also increments the rsa ref count */
RSA_free(rsa); /* Drops our reference to it */
return pk;
}
/* TODO: remove this function in libp11 0.5.0 */
-int pkcs11_get_key_modulus(PKCS11_KEY *key, BIGNUM **bn)
+int pkcs11_get_key_modulus(PKCS11_OBJECT_private *key, BIGNUM **bn)
{
RSA *rsa = pkcs11_rsa(key);
const BIGNUM *rsa_n;
if (!rsa)
return 0;
-#if OPENSSL_VERSION_NUMBER >= 0x10100005L && !defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER >= 0x10100005L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL )
RSA_get0_key(rsa, &rsa_n, NULL, NULL);
#else
rsa_n=rsa->n;
@@ -311,14 +310,14 @@
}
/* TODO: remove this function in libp11 0.5.0 */
-int pkcs11_get_key_exponent(PKCS11_KEY *key, BIGNUM **bn)
+int pkcs11_get_key_exponent(PKCS11_OBJECT_private *key, BIGNUM **bn)
{
RSA *rsa = pkcs11_rsa(key);
const BIGNUM *rsa_e;
if (!rsa)
return 0;
-#if OPENSSL_VERSION_NUMBER >= 0x10100005L && !defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER >= 0x10100005L || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3050000fL )
RSA_get0_key(rsa, NULL, &rsa_e, NULL);
#else
rsa_e=rsa->e;
@@ -328,7 +327,7 @@
}
/* TODO: make this function static in libp11 0.5.0 */
-int pkcs11_get_key_size(PKCS11_KEY *key)
+int pkcs11_get_key_size(PKCS11_OBJECT_private *key)
{
RSA *rsa = pkcs11_rsa(key);
if (!rsa)
@@ -336,7 +335,7 @@
return RSA_size(rsa);
}
-#if OPENSSL_VERSION_NUMBER < 0x10100005L || defined(LIBRESSL_VERSION_NUMBER)
+#if ( ( defined (OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100005L ) || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3020199L ) )
int (*RSA_meth_get_priv_enc(const RSA_METHOD *meth))
(int flen, const unsigned char *from,
@@ -362,32 +361,36 @@
static int pkcs11_rsa_priv_dec_method(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- PKCS11_KEY *key = pkcs11_get_ex_data_rsa(rsa);
+ PKCS11_OBJECT_private *key = pkcs11_get_ex_data_rsa(rsa);
int (*priv_dec) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
- if (check_key_fork(key) < 0) {
+ if (check_object_fork(key) < 0) {
priv_dec = RSA_meth_get_priv_dec(RSA_get_default_method());
return priv_dec(flen, from, to, rsa, padding);
}
- return PKCS11_private_decrypt(flen, from, to, key, padding);
+ return pkcs11_private_decrypt(flen, from, to, key, padding);
}
static int pkcs11_rsa_priv_enc_method(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- PKCS11_KEY *key = pkcs11_get_ex_data_rsa(rsa);
+ PKCS11_OBJECT_private *key = pkcs11_get_ex_data_rsa(rsa);
int (*priv_enc) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
- if (check_key_fork(key) < 0) {
+ if (check_object_fork(key) < 0) {
priv_enc = RSA_meth_get_priv_enc(RSA_get_default_method());
return priv_enc(flen, from, to, rsa, padding);
}
- return PKCS11_private_encrypt(flen, from, to, key, padding);
+ return pkcs11_private_encrypt(flen, from, to, key, padding);
}
static int pkcs11_rsa_free_method(RSA *rsa)
{
- RSA_set_ex_data(rsa, rsa_ex_index, NULL);
+ PKCS11_OBJECT_private *key = pkcs11_get_ex_data_rsa(rsa);
+ if (key) {
+ pkcs11_set_ex_data_rsa(rsa, NULL);
+ pkcs11_object_free(key);
+ }
int (*orig_rsa_free_method)(RSA *rsa) =
RSA_meth_get_finish(RSA_get_default_method());
if (orig_rsa_free_method) {
@@ -508,10 +511,9 @@
free_rsa_ex_index();
}
-PKCS11_KEY_ops pkcs11_rsa_ops = {
+PKCS11_OBJECT_ops pkcs11_rsa_ops = {
EVP_PKEY_RSA,
pkcs11_get_evp_key_rsa,
- pkcs11_update_ex_data_rsa
};
/* vim: set noexpandtab: */
diff -Nru libp11-0.4.11/src/p11_slot.c libp11-0.4.12/src/p11_slot.c
--- libp11-0.4.11/src/p11_slot.c 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/src/p11_slot.c 2022-05-04 18:45:56.000000000 +0200
@@ -21,53 +21,52 @@
#include <string.h>
#include <openssl/buffer.h>
-static int pkcs11_init_slot(PKCS11_CTX *, PKCS11_SLOT *, CK_SLOT_ID);
-static void pkcs11_release_slot(PKCS11_CTX *, PKCS11_SLOT *);
-static int pkcs11_check_token(PKCS11_CTX *, PKCS11_SLOT *);
+static PKCS11_SLOT_private *pkcs11_slot_new(PKCS11_CTX_private *, CK_SLOT_ID);
+static int pkcs11_init_slot(PKCS11_CTX_private *, PKCS11_SLOT *, PKCS11_SLOT_private *);
+static void pkcs11_release_slot(PKCS11_SLOT *);
static void pkcs11_destroy_token(PKCS11_TOKEN *);
/*
* Get slotid from private
*/
-unsigned long pkcs11_get_slotid_from_slot(PKCS11_SLOT *slot)
+unsigned long pkcs11_get_slotid_from_slot(PKCS11_SLOT_private *slot)
{
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
-
- return spriv->id;
+ return slot->id;
}
/*
* Enumerate slots
*/
-int pkcs11_enumerate_slots(PKCS11_CTX *ctx, PKCS11_SLOT **slotp,
+int pkcs11_enumerate_slots(PKCS11_CTX_private *ctx, PKCS11_SLOT **slotp,
unsigned int *countp)
{
- PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
CK_SLOT_ID *slotid;
- CK_ULONG nslots, n;
+ CK_ULONG nslots, n, i;
PKCS11_SLOT *slots;
- size_t alloc_size;
int rv;
- rv = cpriv->method->C_GetSlotList(FALSE, NULL_PTR, &nslots);
+ rv = ctx->method->C_GetSlotList(FALSE, NULL_PTR, &nslots);
CRYPTOKI_checkerr(CKR_F_PKCS11_ENUMERATE_SLOTS, rv);
-
- alloc_size = nslots * sizeof(CK_SLOT_ID);
- if (alloc_size / sizeof(CK_SLOT_ID) != nslots) /* integer overflow */
+ if (nslots > 0x10000)
return -1;
- slotid = OPENSSL_malloc(alloc_size);
+
+ if (!slotp) {
+ /* Fast path for size inquiry */
+ *countp = nslots;
+ return 0;
+ }
+
+ slotid = OPENSSL_malloc(nslots * sizeof(*slotid));
if (!slotid)
return -1;
- rv = cpriv->method->C_GetSlotList(FALSE, slotid, &nslots);
- CRYPTOKI_checkerr(CKR_F_PKCS11_ENUMERATE_SLOTS, rv);
-
- alloc_size = nslots * sizeof(PKCS11_SLOT);
- if (alloc_size / sizeof(PKCS11_SLOT) != nslots) { /* integer overflow */
+ rv = ctx->method->C_GetSlotList(FALSE, slotid, &nslots);
+ if (rv != CKR_OK) {
OPENSSL_free(slotid);
- return -1;
+ CRYPTOKI_checkerr(CKR_F_PKCS11_ENUMERATE_SLOTS, rv);
}
- slots = OPENSSL_malloc(alloc_size);
+
+ slots = OPENSSL_malloc(nslots * sizeof(*slots));
if (!slots) {
OPENSSL_free(slotid);
return -1;
@@ -75,238 +74,209 @@
memset(slots, 0, nslots * sizeof(PKCS11_SLOT));
for (n = 0; n < nslots; n++) {
- if (pkcs11_init_slot(ctx, &slots[n], slotid[n])) {
- while (n--)
- pkcs11_release_slot(ctx, slots + n);
+ PKCS11_SLOT_private *slot = NULL;
+ for (i = 0; i < *countp; i++) {
+ if (PRIVSLOT(slotp[i])->id != slotid[n])
+ continue;
+ slot = pkcs11_slot_ref(PRIVSLOT(slotp[i]));
+ break;
+ }
+ if (!slot)
+ slot = pkcs11_slot_new(ctx, slotid[n]);
+
+ if (pkcs11_init_slot(ctx, &slots[n], slot)) {
+ pkcs11_slot_unref(slot);
+ pkcs11_release_all_slots(slots, n);
OPENSSL_free(slotid);
- OPENSSL_free(slots);
return -1;
}
}
- if (slotp)
- *slotp = slots;
- else
- OPENSSL_free(slots);
- if (countp)
- *countp = nslots;
OPENSSL_free(slotid);
+ pkcs11_release_all_slots(*slotp, *countp);
+ *slotp = slots;
+ *countp = nslots;
return 0;
}
/*
- * Find a slot with a token that looks "valuable"
+ * Open a session with this slot
*/
-PKCS11_SLOT *pkcs11_find_token(PKCS11_CTX *ctx, PKCS11_SLOT *slots,
- unsigned int nslots)
+int pkcs11_open_session(PKCS11_SLOT_private *slot, int rw)
{
- PKCS11_SLOT *slot, *best;
- PKCS11_TOKEN *tok;
- unsigned int n;
+ PKCS11_CTX_private *ctx = slot->ctx;
- (void)ctx;
+ pthread_mutex_lock(&slot->lock);
+ /* If different mode requested, flush pool */
+ if (rw != slot->rw_mode) {
+ CRYPTOKI_call(ctx, C_CloseAllSessions(slot->id));
+ slot->rw_mode = rw;
+ }
+ slot->num_sessions = 0;
+ slot->session_head = slot->session_tail = 0;
+ pthread_mutex_unlock(&slot->lock);
- if (!slots)
- return NULL;
-
- best = NULL;
- for (n = 0, slot = slots; n < nslots; n++, slot++) {
- if ((tok = slot->token) != NULL) {
- if (!best ||
- (tok->initialized > best->token->initialized &&
- tok->userPinSet > best->token->userPinSet &&
- tok->loginRequired > best->token->loginRequired))
- best = slot;
- }
- }
- return best;
+ return 0;
}
-/*
- * Find the next slot with a token that looks "valuable"
- */
-PKCS11_SLOT *pkcs11_find_next_token(PKCS11_CTX *ctx, PKCS11_SLOT *slots,
- unsigned int nslots, PKCS11_SLOT *current)
+int pkcs11_get_session(PKCS11_SLOT_private * slot, int rw, CK_SESSION_HANDLE *sessionp)
{
- int offset;
-
- if (!slots)
- return NULL;
+ PKCS11_CTX_private *ctx = slot->ctx;
+ int rv = CKR_OK;
- if (current) {
- offset = current + 1 - slots;
- if (offset < 1 || (unsigned int)offset >= nslots)
- return NULL;
- } else {
- offset = 0;
- }
-
- return pkcs11_find_token(ctx, slots + offset, nslots - offset);
-}
+ if (rw < 0)
+ return -1;
-/*
- * Open a session with this slot
- */
-int pkcs11_open_session(PKCS11_SLOT *slot, int rw, int relogin)
-{
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- int rv;
+ pthread_mutex_lock(&slot->lock);
+ if (slot->rw_mode < 0)
+ slot->rw_mode = rw;
+ rw = slot->rw_mode;
+ do {
+ /* Get session from the pool */
+ if (slot->session_head != slot->session_tail) {
+ *sessionp = slot->session_pool[slot->session_head];
+ slot->session_head = (slot->session_head + 1) % slot->session_poolsize;
+ break;
+ }
- if (relogin == 0) {
- if (spriv->haveSession) {
- CRYPTOKI_call(ctx, C_CloseSession(spriv->session));
- spriv->haveSession = 0;
+ /* Check if new can be instantiated */
+ if (slot->num_sessions < slot->max_sessions) {
+ rv = CRYPTOKI_call(ctx,
+ C_OpenSession(slot->id,
+ CKF_SERIAL_SESSION | (rw ? CKF_RW_SESSION : 0),
+ NULL, NULL, sessionp));
+ if (rv == CKR_OK) {
+ slot->num_sessions++;
+ break;
+ }
+
+ /* Remember the maximum session count */
+ if (rv == CKR_SESSION_COUNT)
+ slot->max_sessions = slot->num_sessions;
}
- }
- rv = CRYPTOKI_call(ctx,
- C_OpenSession(spriv->id,
- CKF_SERIAL_SESSION | (rw ? CKF_RW_SESSION : 0),
- NULL, NULL, &spriv->session));
- CRYPTOKI_checkerr(CKR_F_PKCS11_OPEN_SESSION, rv);
- spriv->haveSession = 1;
- spriv->prev_rw = rw;
+
+ /* Wait for a session to become available */
+ pthread_cond_wait(&slot->cond, &slot->lock);
+ } while (1);
+ pthread_mutex_unlock(&slot->lock);
return 0;
}
-int pkcs11_reopen_session(PKCS11_SLOT *slot)
+void pkcs11_put_session(PKCS11_SLOT_private *slot, CK_SESSION_HANDLE session)
{
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- int rv;
+ pthread_mutex_lock(&slot->lock);
- rv = CRYPTOKI_call(ctx,
- C_OpenSession(spriv->id,
- CKF_SERIAL_SESSION | (spriv->prev_rw ? CKF_RW_SESSION : 0),
- NULL, NULL, &spriv->session));
- CRYPTOKI_checkerr(CKR_F_PKCS11_REOPEN_SESSION, rv);
- spriv->haveSession = 1;
+ slot->session_pool[slot->session_tail] = session;
+ slot->session_tail = (slot->session_tail + 1) % slot->session_poolsize;
+ pthread_cond_signal(&slot->cond);
- return 0;
+ pthread_mutex_unlock(&slot->lock);
}
/*
* Determines if user is authenticated with token
*/
-int pkcs11_is_logged_in(PKCS11_SLOT *slot, int so, int *res)
+int pkcs11_is_logged_in(PKCS11_SLOT_private *slot, int so, int *res)
{
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
- CK_SESSION_INFO session_info;
- int rv;
-
- if (spriv->loggedIn) {
- *res = 1;
- return 0;
- }
- if (!spriv->haveSession) {
- /* SO gets a r/w session by default,
- * user gets a r/o session by default. */
- if (PKCS11_open_session(slot, so))
- return -1;
- }
-
- rv = CRYPTOKI_call(ctx, C_GetSessionInfo(spriv->session, &session_info));
- CRYPTOKI_checkerr(CKR_F_PKCS11_IS_LOGGED_IN, rv);
- if (so) {
- *res = session_info.state == CKS_RW_SO_FUNCTIONS;
- } else {
- *res = session_info.state == CKS_RO_USER_FUNCTIONS ||
- session_info.state == CKS_RW_USER_FUNCTIONS;
- }
+ *res = slot->logged_in == so;
return 0;
}
/*
- * Authenticate with the card. relogin should be set if we automatically
- * relogin after a fork.
+ * Authenticate with the card.
*/
-int pkcs11_login(PKCS11_SLOT *slot, int so, const char *pin, int relogin)
+int pkcs11_login(PKCS11_SLOT_private *slot, int so, const char *pin)
{
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_CTX_private *ctx = slot->ctx;
+ CK_SESSION_HANDLE session;
int rv;
- if (!relogin && spriv->loggedIn)
+ if (slot->logged_in >= 0)
return 0; /* Nothing to do */
- if (!spriv->haveSession) {
- /* SO gets a r/w session by default,
- * user gets a r/o session by default. */
- if (pkcs11_open_session(slot, so, relogin))
- return -1;
- }
+ /* SO needs a r/w session, user can be checked with a r/o session. */
+ if (pkcs11_get_session(slot, so, &session))
+ return -1;
rv = CRYPTOKI_call(ctx,
- C_Login(spriv->session, so ? CKU_SO : CKU_USER,
+ C_Login(session, so ? CKU_SO : CKU_USER,
(CK_UTF8CHAR *) pin, pin ? (unsigned long) strlen(pin) : 0));
- if (rv && rv != CKR_USER_ALREADY_LOGGED_IN) /* logged in -> OK */
- CRYPTOKI_checkerr(CKR_F_PKCS11_LOGIN, rv);
- spriv->loggedIn = 1;
+ pkcs11_put_session(slot, session);
- if (spriv->prev_pin != pin) {
- if (spriv->prev_pin) {
- OPENSSL_cleanse(spriv->prev_pin, strlen(spriv->prev_pin));
- OPENSSL_free(spriv->prev_pin);
+ if (rv && rv != CKR_USER_ALREADY_LOGGED_IN) { /* logged in -> OK */
+ CRYPTOKI_checkerr(CKR_F_PKCS11_LOGIN, rv);
+ }
+ if (slot->prev_pin != pin) {
+ if (slot->prev_pin) {
+ OPENSSL_cleanse(slot->prev_pin, strlen(slot->prev_pin));
+ OPENSSL_free(slot->prev_pin);
}
- spriv->prev_pin = OPENSSL_strdup(pin);
+ slot->prev_pin = OPENSSL_strdup(pin);
}
- spriv->prev_so = so;
+ slot->logged_in = so;
return 0;
}
/*
- * Authenticate with the card
+ * Reopens the slot by creating a session and logging in if needed.
*/
-int pkcs11_relogin(PKCS11_SLOT *slot)
+int pkcs11_reload_slot(PKCS11_SLOT_private *slot)
{
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ int logged_in = slot->logged_in;
+
+ slot->num_sessions = 0;
+ slot->session_head = slot->session_tail = 0;
+ if (logged_in >= 0) {
+ slot->logged_in = -1;
+ if (pkcs11_login(slot, logged_in, slot->prev_pin))
+ return -1;
+ }
- return pkcs11_login(slot, spriv->prev_so, spriv->prev_pin, 1);
+ return 0;
+}
+
+static void pkcs11_wipe_cache(PKCS11_SLOT_private *slot)
+{
+ pkcs11_destroy_keys(slot, CKO_PRIVATE_KEY);
+ pkcs11_destroy_keys(slot, CKO_PUBLIC_KEY);
+ pkcs11_destroy_certs(slot);
}
/*
* Log out
*/
-int pkcs11_logout(PKCS11_SLOT *slot)
+int pkcs11_logout(PKCS11_SLOT_private *slot)
{
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
- int rv;
+ PKCS11_CTX_private *ctx = slot->ctx;
+ CK_SESSION_HANDLE session;
+ int rv = CKR_OK;
/* Calling PKCS11_logout invalidates all cached
* keys we have */
- if (slot->token) {
- pkcs11_destroy_keys(slot->token, CKO_PRIVATE_KEY);
- pkcs11_destroy_keys(slot->token, CKO_PUBLIC_KEY);
- pkcs11_destroy_certs(slot->token);
- }
- if (!spriv->haveSession) {
- P11err(P11_F_PKCS11_LOGOUT, P11_R_NO_SESSION);
- return -1;
- }
+ pkcs11_wipe_cache(slot);
- rv = CRYPTOKI_call(ctx, C_Logout(spriv->session));
+ if (pkcs11_get_session(slot, slot->logged_in, &session) == 0) {
+ rv = CRYPTOKI_call(ctx, C_Logout(session));
+ pkcs11_put_session(slot, session);
+ }
CRYPTOKI_checkerr(CKR_F_PKCS11_LOGOUT, rv);
- spriv->loggedIn = 0;
+ slot->logged_in = -1;
return 0;
}
/*
* Initialize the token
*/
-int pkcs11_init_token(PKCS11_TOKEN *token, const char *pin, const char *label)
+int pkcs11_init_token(PKCS11_SLOT_private *slot, const char *pin, const char *label)
{
- PKCS11_SLOT *slot = TOKEN2SLOT(token);
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_CTX_private *ctx = slot->ctx;
int rv;
if (!label)
label = "PKCS#11 Token";
rv = CRYPTOKI_call(ctx,
- C_InitToken(spriv->id,
+ C_InitToken(slot->id,
(CK_UTF8CHAR *) pin, (unsigned long) strlen(pin),
(CK_UTF8CHAR *) label));
CRYPTOKI_checkerr(CKR_F_PKCS11_INIT_TOKEN, rv);
@@ -327,36 +297,36 @@
/*
* Set the User PIN
*/
-int pkcs11_init_pin(PKCS11_TOKEN *token, const char *pin)
+int pkcs11_init_pin(PKCS11_SLOT_private *slot, const char *pin)
{
- PKCS11_SLOT *slot = TOKEN2SLOT(token);
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_CTX_private *ctx = slot->ctx;
+ CK_OBJECT_HANDLE session;
int len, rv;
- if (!spriv->haveSession) {
+ if (pkcs11_get_session(slot, 1, &session)) {
P11err(P11_F_PKCS11_INIT_PIN, P11_R_NO_SESSION);
return -1;
}
len = pin ? (int) strlen(pin) : 0;
- rv = CRYPTOKI_call(ctx, C_InitPIN(spriv->session, (CK_UTF8CHAR *) pin, len));
+ rv = CRYPTOKI_call(ctx, C_InitPIN(session, (CK_UTF8CHAR *) pin, len));
+ pkcs11_put_session(slot, session);
CRYPTOKI_checkerr(CKR_F_PKCS11_INIT_PIN, rv);
- return pkcs11_check_token(ctx, TOKEN2SLOT(token));
+ return 0;
}
/*
* Change the User PIN
*/
-int pkcs11_change_pin(PKCS11_SLOT *slot, const char *old_pin,
+int pkcs11_change_pin(PKCS11_SLOT_private *slot, const char *old_pin,
const char *new_pin)
{
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_CTX_private *ctx = slot->ctx;
+ CK_SESSION_HANDLE session;
int old_len, new_len, rv;
- if (!spriv->haveSession) {
+ if (pkcs11_get_session(slot, 1, &session)) {
P11err(P11_F_PKCS11_CHANGE_PIN, P11_R_NO_SESSION);
return -1;
}
@@ -364,139 +334,163 @@
old_len = old_pin ? (int) strlen(old_pin) : 0;
new_len = new_pin ? (int) strlen(new_pin) : 0;
rv = CRYPTOKI_call(ctx,
- C_SetPIN(spriv->session, (CK_UTF8CHAR *) old_pin, old_len,
+ C_SetPIN(session, (CK_UTF8CHAR *) old_pin, old_len,
(CK_UTF8CHAR *) new_pin, new_len));
+ pkcs11_put_session(slot, session);
CRYPTOKI_checkerr(CKR_F_PKCS11_CHANGE_PIN, rv);
- return pkcs11_check_token(ctx, slot);
+ return 0;
}
/*
* Seed the random number generator
*/
-int pkcs11_seed_random(PKCS11_SLOT *slot, const unsigned char *s,
+int pkcs11_seed_random(PKCS11_SLOT_private *slot, const unsigned char *s,
unsigned int s_len)
{
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_CTX_private *ctx = slot->ctx;
+ CK_SESSION_HANDLE session;
int rv;
- if (!spriv->haveSession && PKCS11_open_session(slot, 0)) {
+ if (pkcs11_get_session(slot, 0, &session)) {
P11err(P11_F_PKCS11_SEED_RANDOM, P11_R_NO_SESSION);
return -1;
}
rv = CRYPTOKI_call(ctx,
- C_SeedRandom(spriv->session, (CK_BYTE_PTR) s, s_len));
+ C_SeedRandom(session, (CK_BYTE_PTR) s, s_len));
+ pkcs11_put_session(slot, session);
CRYPTOKI_checkerr(CKR_F_PKCS11_SEED_RANDOM, rv);
- return pkcs11_check_token(ctx, slot);
+ return 0;
}
/*
* Generate random numbers
*/
-int pkcs11_generate_random(PKCS11_SLOT *slot, unsigned char *r,
+int pkcs11_generate_random(PKCS11_SLOT_private *slot, unsigned char *r,
unsigned int r_len)
{
- PKCS11_CTX *ctx = SLOT2CTX(slot);
- PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
+ PKCS11_CTX_private *ctx = slot->ctx;
+ CK_SESSION_HANDLE session;
int rv;
- if (!spriv->haveSession && PKCS11_open_session(slot, 0)) {
+ if (pkcs11_get_session(slot, 0, &session)) {
P11err(P11_F_PKCS11_GENERATE_RANDOM, P11_R_NO_SESSION);
return -1;
}
rv = CRYPTOKI_call(ctx,
- C_GenerateRandom(spriv->session, (CK_BYTE_PTR) r, r_len));
+ C_GenerateRandom(session, (CK_BYTE_PTR) r, r_len));
+ pkcs11_put_session(slot, session);
+
CRYPTOKI_checkerr(CKR_F_PKCS11_GENERATE_RANDOM, rv);
- return pkcs11_check_token(ctx, slot);
+ return 0;
}
/*
* Helper functions
*/
-static int pkcs11_init_slot(PKCS11_CTX *ctx, PKCS11_SLOT *slot, CK_SLOT_ID id)
+static PKCS11_SLOT_private *pkcs11_slot_new(PKCS11_CTX_private *ctx, CK_SLOT_ID id)
+{
+ PKCS11_SLOT_private *slot;
+
+ slot = OPENSSL_malloc(sizeof(*slot));
+ if (!slot)
+ return NULL;
+ memset(slot, 0, sizeof(*slot));
+ slot->refcnt = 1;
+ slot->ctx = ctx;
+ slot->id = id;
+ slot->forkid = ctx->forkid;
+ slot->logged_in = -1;
+ slot->rw_mode = -1;
+ slot->max_sessions = 16;
+ slot->session_poolsize = slot->max_sessions + 1;
+ slot->session_pool = OPENSSL_malloc(slot->session_poolsize * sizeof(CK_SESSION_HANDLE));
+ pthread_mutex_init(&slot->lock, 0);
+ pthread_cond_init(&slot->cond, 0);
+ return slot;
+}
+
+PKCS11_SLOT_private *pkcs11_slot_ref(PKCS11_SLOT_private *slot)
+{
+ pkcs11_atomic_add(&slot->refcnt, 1, &slot->lock);
+ return slot;
+}
+
+void pkcs11_slot_unref(PKCS11_SLOT_private *slot)
+{
+ if (pkcs11_atomic_add(&slot->refcnt, -1, &slot->lock) != 0)
+ return;
+
+ pkcs11_wipe_cache(slot);
+ if (slot->prev_pin) {
+ OPENSSL_cleanse(slot->prev_pin, strlen(slot->prev_pin));
+ OPENSSL_free(slot->prev_pin);
+ }
+ CRYPTOKI_call(slot->ctx, C_CloseAllSessions(slot->id));
+ OPENSSL_free(slot->session_pool);
+ pthread_mutex_destroy(&slot->lock);
+ pthread_cond_destroy(&slot->cond);
+}
+
+static int pkcs11_init_slot(PKCS11_CTX_private *ctx, PKCS11_SLOT *slot, PKCS11_SLOT_private *spriv)
{
- PKCS11_SLOT_private *spriv;
CK_SLOT_INFO info;
int rv;
- rv = CRYPTOKI_call(ctx, C_GetSlotInfo(id, &info));
+ rv = CRYPTOKI_call(ctx, C_GetSlotInfo(spriv->id, &info));
CRYPTOKI_checkerr(CKR_F_PKCS11_INIT_SLOT, rv);
- spriv = OPENSSL_malloc(sizeof(PKCS11_SLOT_private));
- if (!spriv)
- return -1;
- memset(spriv, 0, sizeof(PKCS11_SLOT_private));
-
- spriv->parent = ctx;
- spriv->id = id;
- spriv->forkid = PRIVCTX(ctx)->forkid;
- spriv->prev_rw = 0;
- spriv->prev_pin = NULL;
- spriv->prev_so = 0;
-
+ slot->_private = spriv;
slot->description = PKCS11_DUP(info.slotDescription);
slot->manufacturer = PKCS11_DUP(info.manufacturerID);
slot->removable = (info.flags & CKF_REMOVABLE_DEVICE) ? 1 : 0;
- slot->_private = spriv;
-
- if ((info.flags & CKF_TOKEN_PRESENT) && pkcs11_check_token(ctx, slot))
- return -1;
+ if (info.flags & CKF_TOKEN_PRESENT) {
+ if (pkcs11_refresh_token(slot))
+ return -1;
+ }
return 0;
}
-void pkcs11_release_all_slots(PKCS11_CTX *ctx, PKCS11_SLOT *slots,
- unsigned int nslots)
+void pkcs11_release_all_slots(PKCS11_SLOT *slots, unsigned int nslots)
{
unsigned int i;
for (i=0; i < nslots; i++)
- pkcs11_release_slot(ctx, &slots[i]);
+ pkcs11_release_slot(&slots[i]);
OPENSSL_free(slots);
}
-static void pkcs11_release_slot(PKCS11_CTX *ctx, PKCS11_SLOT *slot)
+static void pkcs11_release_slot(PKCS11_SLOT *slot)
{
PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
- if (spriv) {
- if (spriv->prev_pin) {
- OPENSSL_cleanse(spriv->prev_pin, strlen(spriv->prev_pin));
- OPENSSL_free(spriv->prev_pin);
- }
- CRYPTOKI_call(ctx, C_CloseAllSessions(spriv->id));
- }
- OPENSSL_free(slot->_private);
- OPENSSL_free(slot->description);
- OPENSSL_free(slot->manufacturer);
if (slot->token) {
pkcs11_destroy_token(slot->token);
OPENSSL_free(slot->token);
}
+ if (spriv)
+ pkcs11_slot_unref(spriv);
+ OPENSSL_free(slot->description);
+ OPENSSL_free(slot->manufacturer);
+ OPENSSL_free(slot->_private);
memset(slot, 0, sizeof(*slot));
}
-static int pkcs11_check_token(PKCS11_CTX *ctx, PKCS11_SLOT *slot)
+int pkcs11_refresh_token(PKCS11_SLOT *slot)
{
PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
- PKCS11_TOKEN_private *tpriv;
+ PKCS11_CTX_private *ctx = spriv->ctx;
CK_TOKEN_INFO info;
int rv;
- if (slot->token) {
+ if (slot->token)
pkcs11_destroy_token(slot->token);
- } else {
- slot->token = OPENSSL_malloc(sizeof(PKCS11_TOKEN));
- if (!slot->token)
- return -1;
- memset(slot->token, 0, sizeof(PKCS11_TOKEN));
- }
rv = CRYPTOKI_call(ctx, C_GetTokenInfo(spriv->id, &info));
if (rv == CKR_TOKEN_NOT_PRESENT || rv == CKR_TOKEN_NOT_RECOGNIZED) {
@@ -507,16 +501,12 @@
CRYPTOKI_checkerr(CKR_F_PKCS11_CHECK_TOKEN, rv);
/* We have a token */
- tpriv = OPENSSL_malloc(sizeof(PKCS11_TOKEN_private));
- if (!tpriv)
- return -1;
- memset(tpriv, 0, sizeof(PKCS11_TOKEN_private));
- tpriv->parent = slot;
- tpriv->prv.keys = NULL;
- tpriv->prv.num = 0;
- tpriv->pub.keys = NULL;
- tpriv->pub.num = 0;
- tpriv->ncerts = 0;
+ if (!slot->token) {
+ slot->token = OPENSSL_malloc(sizeof(PKCS11_TOKEN));
+ if (!slot->token)
+ return -1;
+ memset(slot->token, 0, sizeof(PKCS11_TOKEN));
+ }
slot->token->label = PKCS11_DUP(info.label);
slot->token->manufacturer = PKCS11_DUP(info.manufacturerID);
@@ -536,22 +526,20 @@
slot->token->soPinFinalTry = (info.flags & CKF_SO_PIN_FINAL_TRY) ? 1 : 0;
slot->token->soPinLocked = (info.flags & CKF_SO_PIN_LOCKED) ? 1 : 0;
slot->token->soPinToBeChanged = (info.flags & CKF_SO_PIN_TO_BE_CHANGED) ? 1 : 0;
- slot->token->_private = tpriv;
+ slot->token->slot = slot;
+
+ spriv->secure_login = (info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) ? 1 : 0;
return 0;
}
static void pkcs11_destroy_token(PKCS11_TOKEN *token)
{
- pkcs11_destroy_keys(token, CKO_PRIVATE_KEY);
- pkcs11_destroy_keys(token, CKO_PUBLIC_KEY);
- pkcs11_destroy_certs(token);
-
+ pkcs11_wipe_cache(PRIVSLOT(token->slot));
OPENSSL_free(token->label);
OPENSSL_free(token->manufacturer);
OPENSSL_free(token->model);
OPENSSL_free(token->serialnr);
- OPENSSL_free(token->_private);
memset(token, 0, sizeof(*token));
}
diff -Nru libp11-0.4.11/src/pkcs11.h libp11-0.4.12/src/pkcs11.h
--- libp11-0.4.11/src/pkcs11.h 2020-05-18 08:47:22.000000000 +0200
+++ libp11-0.4.12/src/pkcs11.h 2022-03-15 18:13:43.000000000 +0100
@@ -592,6 +592,22 @@
#define CKM_SHA512 (0x270UL)
#define CKM_SHA512_HMAC (0x271UL)
#define CKM_SHA512_HMAC_GENERAL (0x272UL)
+#define CKM_SHA3_256 (0x2B0UL)
+#define CKM_SHA3_256_HMAC (0x2B1UL)
+#define CKM_SHA3_256_HMAC_GENERAL (0x2B2UL)
+#define CKM_SHA3_256_KEY_GEN (0x2B3UL)
+#define CKM_SHA3_224 (0x2B5UL)
+#define CKM_SHA3_224_HMAC (0x2B6UL)
+#define CKM_SHA3_224_HMAC_GENERAL (0x2B7UL)
+#define CKM_SHA3_224_KEY_GEN (0x2B8UL)
+#define CKM_SHA3_384 (0x2C0UL)
+#define CKM_SHA3_384_HMAC (0x2C1UL)
+#define CKM_SHA3_384_HMAC_GENERAL (0x2C2UL)
+#define CKM_SHA3_384_KEY_GEN (0x2C3UL)
+#define CKM_SHA3_512 (0x2D0UL)
+#define CKM_SHA3_512_HMAC (0x2D1UL)
+#define CKM_SHA3_512_HMAC_GENERAL (0x2D2UL)
+#define CKM_SHA3_512_KEY_GEN (0x2D3UL)
#define CKM_CAST_KEY_GEN (0x300UL)
#define CKM_CAST_ECB (0x301UL)
#define CKM_CAST_CBC (0x302UL)
@@ -845,6 +861,10 @@
#define CKG_MGF1_SHA256 (0x00000002UL)
#define CKG_MGF1_SHA384 (0x00000003UL)
#define CKG_MGF1_SHA512 (0x00000004UL)
+#define CKG_MGF1_SHA3_224 (0x00000006UL)
+#define CKG_MGF1_SHA3_256 (0x00000007UL)
+#define CKG_MGF1_SHA3_384 (0x00000008UL)
+#define CKG_MGF1_SHA3_512 (0x00000009UL)
#define CKZ_DATA_SPECIFIED (0x00000001UL)
diff -Nru libp11-0.4.11/src/pkcs11.rc libp11-0.4.12/src/pkcs11.rc
--- libp11-0.4.11/src/pkcs11.rc 2020-10-11 17:18:13.000000000 +0200
+++ libp11-0.4.12/src/pkcs11.rc 2022-07-15 21:56:30.000000000 +0200
@@ -1,8 +1,8 @@
#include <winresrc.h>
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,4,11,0
- PRODUCTVERSION 0,4,11,0
+ FILEVERSION 0,4,12,0
+ PRODUCTVERSION 0,4,12,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x21L
@@ -20,14 +20,14 @@
VALUE "Comments", "Provided under the terms of the GNU General Public License (LGPLv2.1+).\0"
VALUE "CompanyName", "OpenSC Project\0"
VALUE "FileDescription", "OpenSSL PKCS#11 engine\0"
- VALUE "FileVersion", "0.4.11.0\0"
+ VALUE "FileVersion", "0.4.12.0\0"
VALUE "InternalName", "libp11\0"
VALUE "LegalCopyright", "OpenSC Project\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "pkcs11.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "libp11\0"
- VALUE "ProductVersion", "0.4.11.0\0"
+ VALUE "ProductVersion", "0.4.12.0\0"
VALUE "SpecialBuild", "\0"
END
END
diff -Nru libp11-0.4.11/test-driver libp11-0.4.12/test-driver
--- libp11-0.4.11/test-driver 2018-10-02 20:47:03.000000000 +0200
+++ libp11-0.4.12/test-driver 2022-03-15 18:14:17.000000000 +0100
@@ -3,7 +3,7 @@
scriptversion=2018-03-07.03; # UTC
-# Copyright (C) 2011-2018 Free Software Foundation, Inc.
+# Copyright (C) 2011-2020 Free Software Foundation, Inc.
#
# 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
@@ -42,11 +42,13 @@
{
cat <<END
Usage:
- test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
- [--expect-failure={yes|no}] [--color-tests={yes|no}]
- [--enable-hard-errors={yes|no}] [--]
+ test-driver --test-name NAME --log-file PATH --trs-file PATH
+ [--expect-failure {yes|no}] [--color-tests {yes|no}]
+ [--enable-hard-errors {yes|no}] [--]
TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
+
The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+See the GNU Automake documentation for information.
END
}
diff -Nru libp11-0.4.11/tests/ec-cert-store.softhsm libp11-0.4.12/tests/ec-cert-store.softhsm
--- libp11-0.4.11/tests/ec-cert-store.softhsm 1970-01-01 01:00:00.000000000 +0100
+++ libp11-0.4.12/tests/ec-cert-store.softhsm 2021-02-08 12:17:15.000000000 +0100
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+# Copyright (C) 2015 Nikos Mavrogiannopoulos
+# Copyright (C) 2019 Anderson Toshiyuki Sasaki
+# Copyright (C) 2019 Red Hat, Inc.
+# Copyright (C) 2020 Mateusz Kwiatkowski
+# Copyright (C) 2020 AVSystem
+#
+# 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/"
+CERTIFICATE="${outdir}/ec-cert.pem"
+CERTIFICATE_URL="pkcs11:token=libp11-test;object=stored-cert;pin-value=1234"
+
+./store-cert ${CERTIFICATE} ${CERTIFICATE_URL} ${MODULE} "${outdir}/engines.cnf"
+if test $? != 0;then
+ echo "The certificate storing couldn't be performed"
+ exit 1;
+fi
+
+pkcs11-tool -p 1234 --module ${MODULE} -l -O | grep -q stored-cert
+if test $? != 0;then
+ echo "The certificate was not properly stored"
+ exit 1;
+fi
+
+rm -rf "$outdir"
+
+exit 0
diff -Nru libp11-0.4.11/tests/ec-check-privkey.softhsm libp11-0.4.12/tests/ec-check-privkey.softhsm
--- libp11-0.4.11/tests/ec-check-privkey.softhsm 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/tests/ec-check-privkey.softhsm 2021-10-30 14:20:08.000000000 +0200
@@ -31,13 +31,13 @@
./check-privkey ${CERTIFICATE} ${PRIVATE_KEY} ${MODULE} "${outdir}/engines.cnf"
if test $? != 0;then
- echo "The private key loading couln't get the public key from the certificate"
+ echo "The private key loading couldn't get the public key from the certificate"
exit 1;
fi
./check-privkey ${CERTIFICATE_URL} ${PRIVATE_KEY} ${MODULE} "${outdir}/engines.cnf"
if test $? != 0;then
- echo "The private key loading couln't get the public key from the certificate URL"
+ echo "The private key loading couldn't get the public key from the certificate URL"
exit 1;
fi
diff -Nru libp11-0.4.11/tests/evp-sign.c libp11-0.4.12/tests/evp-sign.c
--- libp11-0.4.11/tests/evp-sign.c 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/tests/evp-sign.c 2021-10-30 14:20:08.000000000 +0200
@@ -88,7 +88,7 @@
case UIT_VERIFY:
{
/* If there is a default PIN, just
- * return without outputing any prompt */
+ * return without outputting any prompt */
const char *password =
((const char *)UI_get0_user_data(ui));
if (password && password[0] != '\0')
diff -Nru libp11-0.4.11/tests/fork-change-slot.c libp11-0.4.12/tests/fork-change-slot.c
--- libp11-0.4.11/tests/fork-change-slot.c 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/tests/fork-change-slot.c 2021-10-30 14:20:08.000000000 +0200
@@ -65,10 +65,6 @@
#define RANDOM_SIZE 20
#define MAX_SIGSIZE 1024
-#if OPENSSL_VERSION_NUMBER < 0x10100003L
-#define EVP_PKEY_get0_RSA(key) ((key)->pkey.rsa)
-#endif
-
static int do_wait(pid_t pids[], int num)
{
int i;
diff -Nru libp11-0.4.11/tests/fork-test.c libp11-0.4.12/tests/fork-test.c
--- libp11-0.4.11/tests/fork-test.c 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/tests/fork-test.c 2021-10-30 14:20:08.000000000 +0200
@@ -52,10 +52,6 @@
#define RANDOM_SIZE 20
#define MAX_SIGSIZE 1024
-#if OPENSSL_VERSION_NUMBER < 0x10100003L
-#define EVP_PKEY_get0_RSA(key) ((key)->pkey.rsa)
-#endif
-
static void do_fork();
static void error_queue(const char *name);
diff -Nru libp11-0.4.11/tests/list-tokens.c libp11-0.4.12/tests/list-tokens.c
--- libp11-0.4.11/tests/list-tokens.c 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/tests/list-tokens.c 2021-02-08 12:17:15.000000000 +0100
@@ -39,7 +39,6 @@
{
PKCS11_CTX *ctx;
PKCS11_SLOT *slots, *slot;
- PKCS11_CERT *certs;
int rc = 0, token_found = 0;
diff -Nru libp11-0.4.11/tests/Makefile.am libp11-0.4.12/tests/Makefile.am
--- libp11-0.4.11/tests/Makefile.am 2020-02-27 06:50:01.000000000 +0100
+++ libp11-0.4.12/tests/Makefile.am 2022-03-15 18:13:43.000000000 +0100
@@ -1,4 +1,4 @@
-EXTRA_DIST = engines.cnf.in rsa-common.sh ec-common.sh ec-no-pubkey.sh
+EXTRA_DIST = engines.cnf.in rsa-common.sh rsa-no-pubkey.sh ec-common.sh ec-no-pubkey.sh
AM_CFLAGS = $(OPENSSL_CFLAGS)
AM_CPPFLAGS = \
@@ -16,7 +16,8 @@
list-tokens \
rsa-pss-sign \
rsa-oaep \
- check-privkey
+ check-privkey \
+ store-cert
dist_check_SCRIPTS = \
rsa-testpkcs11.softhsm \
rsa-testfork.softhsm \
@@ -28,9 +29,11 @@
rsa-pss-sign.softhsm \
rsa-oaep.softhsm \
case-insensitive.softhsm \
+ rsa-check-privkey.softhsm \
ec-check-privkey.softhsm \
pkcs11-uri-without-token.softhsm \
- search-all-matching-tokens.softhsm
+ search-all-matching-tokens.softhsm \
+ ec-cert-store.softhsm
dist_check_DATA = \
rsa-cert.der rsa-prvkey.der rsa-pubkey.der \
ec-cert.der ec-prvkey.der ec-pubkey.der
diff -Nru libp11-0.4.11/tests/Makefile.in libp11-0.4.12/tests/Makefile.in
--- libp11-0.4.11/tests/Makefile.in 2020-10-11 15:46:57.000000000 +0200
+++ libp11-0.4.12/tests/Makefile.in 2022-07-15 21:56:27.000000000 +0200
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.2 from Makefile.am.
+# Makefile.in generated by automake 1.16.4 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -87,13 +87,15 @@
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+target_triplet = @target@
check_PROGRAMS = openssl_version$(EXEEXT) fork-test$(EXEEXT) \
evp-sign$(EXEEXT) fork-change-slot$(EXEEXT) \
list-tokens$(EXEEXT) rsa-pss-sign$(EXEEXT) rsa-oaep$(EXEEXT) \
- check-privkey$(EXEEXT)
+ check-privkey$(EXEEXT) store-cert$(EXEEXT)
subdir = tests
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ld-version-script.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \
+ $(top_srcdir)/m4/ld-version-script.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
@@ -142,6 +144,10 @@
rsa_pss_sign_OBJECTS = rsa-pss-sign.$(OBJEXT)
rsa_pss_sign_LDADD = $(LDADD)
rsa_pss_sign_DEPENDENCIES = ../src/libp11.la $(am__DEPENDENCIES_1)
+store_cert_SOURCES = store-cert.c
+store_cert_OBJECTS = store-cert.$(OBJEXT)
+store_cert_LDADD = $(LDADD)
+store_cert_DEPENDENCIES = ../src/libp11.la $(am__DEPENDENCIES_1)
AM_V_P = $(am__v_P_ at AM_V@)
am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
am__v_P_0 = false
@@ -161,7 +167,7 @@
./$(DEPDIR)/evp-sign.Po ./$(DEPDIR)/fork-change-slot.Po \
./$(DEPDIR)/fork-test.Po ./$(DEPDIR)/list-tokens.Po \
./$(DEPDIR)/openssl_version.Po ./$(DEPDIR)/rsa-oaep.Po \
- ./$(DEPDIR)/rsa-pss-sign.Po
+ ./$(DEPDIR)/rsa-pss-sign.Po ./$(DEPDIR)/store-cert.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -182,10 +188,11 @@
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = check-privkey.c evp-sign.c fork-change-slot.c fork-test.c \
- list-tokens.c openssl_version.c rsa-oaep.c rsa-pss-sign.c
+ list-tokens.c openssl_version.c rsa-oaep.c rsa-pss-sign.c \
+ store-cert.c
DIST_SOURCES = check-privkey.c evp-sign.c fork-change-slot.c \
fork-test.c list-tokens.c openssl_version.c rsa-oaep.c \
- rsa-pss-sign.c
+ rsa-pss-sign.c store-cert.c
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -208,8 +215,6 @@
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
am__tty_colors_dummy = \
mgn= red= grn= lgn= blu= brg= std=; \
am__color_tests=no
@@ -392,6 +397,7 @@
bases='$(TEST_LOGS)'; \
bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
RECHECK_LOGS = $(TEST_LOGS)
AM_RECURSIVE_TARGETS = check recheck
TEST_SUITE_LOG = test-suite.log
@@ -431,6 +437,8 @@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
@@ -442,6 +450,7 @@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
+ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
@@ -488,6 +497,10 @@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_CXX = @PTHREAD_CXX@
+PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
RC = @RC@
SED = @SED@
@@ -510,6 +523,7 @@
am__tar = @am__tar@
am__untar = @am__untar@
apidocdir = @apidocdir@
+ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -549,11 +563,15 @@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
+target = @target@
target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-EXTRA_DIST = engines.cnf.in rsa-common.sh ec-common.sh ec-no-pubkey.sh
+EXTRA_DIST = engines.cnf.in rsa-common.sh rsa-no-pubkey.sh ec-common.sh ec-no-pubkey.sh
AM_CFLAGS = $(OPENSSL_CFLAGS)
AM_CPPFLAGS = \
-I$(top_srcdir) \
@@ -573,9 +591,11 @@
rsa-pss-sign.softhsm \
rsa-oaep.softhsm \
case-insensitive.softhsm \
+ rsa-check-privkey.softhsm \
ec-check-privkey.softhsm \
pkcs11-uri-without-token.softhsm \
- search-all-matching-tokens.softhsm
+ search-all-matching-tokens.softhsm \
+ ec-cert-store.softhsm
dist_check_DATA = \
rsa-cert.der rsa-prvkey.der rsa-pubkey.der \
@@ -663,6 +683,10 @@
@rm -f rsa-pss-sign$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(rsa_pss_sign_OBJECTS) $(rsa_pss_sign_LDADD) $(LIBS)
+store-cert$(EXEEXT): $(store_cert_OBJECTS) $(store_cert_DEPENDENCIES) $(EXTRA_store_cert_DEPENDENCIES)
+ @rm -f store-cert$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(store_cert_OBJECTS) $(store_cert_LDADD) $(LIBS)
+
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -677,6 +701,7 @@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/openssl_version.Po at am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rsa-oaep.Po at am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rsa-pss-sign.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/store-cert.Po at am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@@ -873,7 +898,7 @@
test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
fi; \
echo "$${col}$$br$${std}"; \
- echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
echo "$${col}$$br$${std}"; \
create_testsuite_report --maybe-color; \
echo "$$col$$br$$std"; \
@@ -977,6 +1002,13 @@
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
+rsa-check-privkey.softhsm.log: rsa-check-privkey.softhsm
+ @p='rsa-check-privkey.softhsm'; \
+ b='rsa-check-privkey.softhsm'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
ec-check-privkey.softhsm.log: ec-check-privkey.softhsm
@p='ec-check-privkey.softhsm'; \
b='ec-check-privkey.softhsm'; \
@@ -998,6 +1030,13 @@
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
+ec-cert-store.softhsm.log: ec-cert-store.softhsm
+ @p='ec-cert-store.softhsm'; \
+ b='ec-cert-store.softhsm'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
.test.log:
@p='$<'; \
$(am__set_b); \
@@ -1012,7 +1051,6 @@
@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
-
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -1100,6 +1138,7 @@
-rm -f ./$(DEPDIR)/openssl_version.Po
-rm -f ./$(DEPDIR)/rsa-oaep.Po
-rm -f ./$(DEPDIR)/rsa-pss-sign.Po
+ -rm -f ./$(DEPDIR)/store-cert.Po
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@@ -1153,6 +1192,7 @@
-rm -f ./$(DEPDIR)/openssl_version.Po
-rm -f ./$(DEPDIR)/rsa-oaep.Po
-rm -f ./$(DEPDIR)/rsa-pss-sign.Po
+ -rm -f ./$(DEPDIR)/store-cert.Po
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
diff -Nru libp11-0.4.11/tests/rsa-check-privkey.softhsm libp11-0.4.12/tests/rsa-check-privkey.softhsm
--- libp11-0.4.11/tests/rsa-check-privkey.softhsm 1970-01-01 01:00:00.000000000 +0100
+++ libp11-0.4.12/tests/rsa-check-privkey.softhsm 2021-10-30 14:20:08.000000000 +0200
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+# Copyright (C) 2015 Nikos Mavrogiannopoulos
+# Copyright (C) 2019 Anderson Toshiyuki Sasaki
+# Copyright (C) 2019 Red Hat, Inc.
+# Copyright (C) 2021 Uri Blumenthal, MIT
+#
+# 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}/rsa-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"
+CERTIFICATE="${outdir}/rsa-cert.pem"
+CERTIFICATE_URL="pkcs11:token=libp11-test;id=%01%02%03%04;object=server-key;type=cert;pin-value=1234"
+
+./check-privkey ${CERTIFICATE} ${PRIVATE_KEY} ${MODULE} "${outdir}/engines.cnf"
+if test $? != 0;then
+ echo "The private key loading couldn't get the public key from the certificate"
+ exit 1;
+fi
+
+./check-privkey ${CERTIFICATE_URL} ${PRIVATE_KEY} ${MODULE} "${outdir}/engines.cnf"
+if test $? != 0;then
+ echo "The private key loading couldn't get the public key from the certificate URL"
+ exit 1;
+fi
+
+rm -rf "$outdir"
+
+exit 0
diff -Nru libp11-0.4.11/tests/rsa-no-pubkey.sh libp11-0.4.12/tests/rsa-no-pubkey.sh
--- libp11-0.4.11/tests/rsa-no-pubkey.sh 1970-01-01 01:00:00.000000000 +0100
+++ libp11-0.4.12/tests/rsa-no-pubkey.sh 2021-10-30 14:20:08.000000000 +0200
@@ -0,0 +1,123 @@
+#!/bin/sh
+
+# Copyright (C) 2013 Nikos Mavrogiannopoulos
+# Copyright (C) 2019 Anderson Toshiyuki Sasaki
+# Copyright (C) 2019 Red Hat, Inc.
+# Copyright (C) 2021 Uri Blumenthal, MIT
+#
+# 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/>.
+
+OPENSSL_VERSION=$(./openssl_version | cut -d ' ' -f 2)
+case "${OPENSSL_VERSION}" in
+0.*)
+ echo "EC tests skipped with OpenSSL ${OPENSSL_VERSION}"
+ exit 77
+ ;;
+*)
+ ;;
+esac
+
+echo "Current directory: $(pwd)"
+echo "Source directory: ${srcdir}"
+echo "Output directory: ${outdir}"
+
+mkdir -p $outdir
+
+for i in /usr/lib64/pkcs11 /usr/lib64/softhsm /usr/lib/x86_64-linux-gnu/softhsm /usr/local/lib/softhsm /opt/local/lib/softhsm /usr/lib/softhsm /usr/lib ;do
+ if test -f "$i/libsofthsm2.so"; then
+ MODULE="$i/libsofthsm2.so"
+ break
+ else
+ if test -f "$i/libsofthsm.so";then
+ MODULE="$i/libsofthsm.so"
+ break
+ fi
+ fi
+done
+
+if (! test -x /usr/bin/pkcs11-tool && ! test -x /usr/local/bin/pkcs11-tool);then
+ exit 77
+fi
+
+init_card () {
+ PIN="$1"
+ PUK="$2"
+
+ if test -x "/usr/bin/softhsm"; then
+ export SOFTHSM_CONF="$outdir/softhsm-testpkcs11.config"
+ SOFTHSM_TOOL="/usr/bin/softhsm"
+ fi
+
+ if test -x "/usr/local/bin/softhsm2-util"; then
+ export SOFTHSM2_CONF="$outdir/softhsm-testpkcs11.config"
+ SOFTHSM_TOOL="/usr/local/bin/softhsm2-util"
+ fi
+
+ if test -x "/opt/local/bin/softhsm2-util"; then
+ export SOFTHSM2_CONF="$outdir/softhsm-testpkcs11.config"
+ SOFTHSM_TOOL="/opt/local/bin/softhsm2-util"
+ fi
+
+ if test -x "/usr/bin/softhsm2-util"; then
+ export SOFTHSM2_CONF="$outdir/softhsm-testpkcs11.config"
+ SOFTHSM_TOOL="/usr/bin/softhsm2-util"
+ fi
+
+ if test -z "${SOFTHSM_TOOL}"; then
+ echo "Could not find softhsm(2) tool"
+ exit 77
+ fi
+
+ if test -n "${SOFTHSM2_CONF}"; then
+ rm -rf $outdir/softhsm-testpkcs11.db
+ mkdir -p $outdir/softhsm-testpkcs11.db
+ echo "objectstore.backend = file" > "${SOFTHSM2_CONF}"
+ echo "directories.tokendir = $outdir/softhsm-testpkcs11.db" >> "${SOFTHSM2_CONF}"
+ else
+ rm -rf $outdir/softhsm-testpkcs11.db
+ echo "0:$outdir/softhsm-testpkcs11.db" > "${SOFTHSM_CONF}"
+ fi
+
+
+ echo -n "* Initializing smart card... "
+ ${SOFTHSM_TOOL} --init-token --slot 0 --label "libp11-test" --so-pin "${PUK}" --pin "${PIN}" >/dev/null
+ if test $? = 0; then
+ echo ok
+ else
+ echo failed
+ exit 1
+ fi
+}
+
+PIN=1234
+PUK=1234
+init_card $PIN $PUK
+
+# generate key in token
+pkcs11-tool -p $PIN --module $MODULE -d 01020304 -a server-key -l -w ${srcdir}/rsa-prvkey.der -y privkey >/dev/null
+if test $? != 0;then
+ exit 1;
+fi
+
+pkcs11-tool -p $PIN --module $MODULE -d 01020304 -a server-key -l -w ${srcdir}/rsa-cert.der -y cert >/dev/null
+if test $? != 0;then
+ exit 1;
+fi
+
+openssl x509 -in ${srcdir}/rsa-cert.der -inform DER -out ${outdir}/rsa-cert.pem -outform PEM
+
+echo "***************"
+echo "Listing objects"
+echo "***************"
+pkcs11-tool -p $PIN --module $MODULE -l -O
diff -Nru libp11-0.4.11/tests/rsa-oaep.c libp11-0.4.12/tests/rsa-oaep.c
--- libp11-0.4.11/tests/rsa-oaep.c 2018-08-03 07:57:27.000000000 +0200
+++ libp11-0.4.12/tests/rsa-oaep.c 2021-10-30 14:20:08.000000000 +0200
@@ -230,7 +230,7 @@
/* Compare output */
if (!memcmp(dec, data, data_len)) {
- printf("Sucessfuly decrypted\n");
+ printf("Successfully decrypted\n");
}
else {
printf("Decrypted data does not match original data\n");
diff -Nru libp11-0.4.11/tests/store-cert.c libp11-0.4.12/tests/store-cert.c
--- libp11-0.4.11/tests/store-cert.c 1970-01-01 01:00:00.000000000 +0100
+++ libp11-0.4.12/tests/store-cert.c 2021-02-08 12:17:15.000000000 +0100
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2019 Anderson Toshiyuki Sasaki
+ * Copyright (C) 2019 Red Hat, Inc.
+ * Copyright (C) 2020 Mateusz Kwiatkowski
+ * Copyright (C) 2020 AVSystem
+ *
+ * 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 <libp11.h>
+#include <openssl/conf.h>
+#include <openssl/engine.h>
+#include <openssl/pem.h>
+#include <string.h>
+
+static void
+usage(char* argv[])
+{
+ fprintf(stderr,
+ "%s [source certificate file] [target certificate URL]\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 main.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);
+ }
+}
+
+static int
+extract_url_fields(char* address,
+ char** out_token,
+ char** out_label,
+ char** out_pin)
+{
+ static const char DELIMITERS[] = ":;?&=";
+ char *str, *token;
+ if (strncmp(address, "pkcs11:", strlen("pkcs11:")) != 0) {
+ printf("URL does not look valid: %s\n", address);
+ return -1;
+ }
+ str = address + strlen("pkcs11:");
+ while ((token = strtok(str, DELIMITERS))) {
+ char** out = NULL;
+ str = NULL;
+ if (strcmp(token, "token") == 0) {
+ out = out_token;
+ } else if (strcmp(token, "object") == 0) {
+ out = out_label;
+ } else if (strcmp(token, "pin-value") == 0) {
+ out = out_pin;
+ } else {
+ printf("Unrecognized token: %s\n", token);
+ return -1;
+ }
+ if (out) {
+ if (*out) {
+ return -1;
+ printf("Repeated token: %s\n", token);
+ } else if ((token = strtok(str, DELIMITERS))) {
+ *out = token;
+ }
+ }
+ }
+ if (!*out_token || !*out_label || !*out_pin) {
+ printf("URL incomplete\n");
+ return -1;
+ }
+ return 0;
+}
+
+static PKCS11_CTX* global_pkcs11_ctx;
+static PKCS11_SLOT* global_pkcs11_slots;
+static unsigned int global_pkcs11_slot_num;
+
+static int
+store_certificate(char* address, X509* cert)
+{
+ char *token = NULL, *label = NULL, *pin = NULL;
+ if (extract_url_fields(address, &token, &label, &pin)) {
+ return -1;
+ }
+
+ PKCS11_SLOT* slot = PKCS11_find_token(
+ global_pkcs11_ctx, global_pkcs11_slots, global_pkcs11_slot_num);
+ while (slot) {
+ if (strcmp(token, slot->token->label) == 0) {
+ break;
+ }
+ slot = PKCS11_find_next_token(global_pkcs11_ctx,
+ global_pkcs11_slots,
+ global_pkcs11_slot_num,
+ slot);
+ }
+
+ if (!slot) {
+ printf("Could not find token: %s\n", token);
+ return -1;
+ }
+
+ if (PKCS11_open_session(slot, 1)) {
+ printf("Could not open session\n");
+ return -1;
+ }
+
+ if (PKCS11_login(slot, 0, pin)) {
+ printf("Could not login to slot\n");
+ return -1;
+ }
+
+ if (PKCS11_store_certificate(slot->token,
+ cert,
+ label,
+ (unsigned char*)label,
+ strlen(label),
+ NULL)) {
+ printf("Could not store certificate\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+main(int argc, char* argv[])
+{
+ ENGINE* engine = NULL;
+ X509* cert = NULL;
+ FILE* cert_fp = NULL;
+
+ char *certfile, *target, *module, *efile;
+
+ int ret = 0;
+
+ struct
+ {
+ const char* cert_id;
+ X509* cert;
+ } params = { 0 };
+
+ if (argc < 2) {
+ printf("Too few arguments\n");
+ usage(argv);
+ return 1;
+ }
+
+ certfile = argv[1];
+ target = argv[2];
+ module = argv[3];
+ efile = argv[4];
+
+ 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;
+ }
+
+ if (!strncmp(certfile, "pkcs11:", 7)) {
+ params.cert_id = certfile;
+ if (!ENGINE_ctrl_cmd(
+ engine, "LOAD_CERT_CTRL", 0, ¶ms, NULL, 1)) {
+ fprintf(
+ stderr, "Could not get certificate %s\n", certfile);
+ ret = 1;
+ goto end;
+ }
+ cert = params.cert;
+ } else {
+ cert_fp = fopen(certfile, "rb");
+ if (!cert_fp) {
+ fprintf(stderr, "Could not open file %s\n", certfile);
+ ret = 1;
+ goto end;
+ }
+
+ cert = PEM_read_X509(cert_fp, NULL, NULL, NULL);
+ if (!cert) {
+ fprintf(stderr,
+ "Could not read certificate file"
+ "(must be PEM format)\n");
+ }
+
+ if (cert_fp) {
+ fclose(cert_fp);
+ }
+ }
+
+ if (!(global_pkcs11_ctx = PKCS11_CTX_new())) {
+ printf("Could not initialize libp11 context\n");
+ ret = 1;
+ } else if (PKCS11_CTX_load(global_pkcs11_ctx, module)) {
+ printf("Could not load PKCS11 module\n");
+ ret = 1;
+ } else if (PKCS11_enumerate_slots(global_pkcs11_ctx,
+ &global_pkcs11_slots,
+ &global_pkcs11_slot_num)) {
+ printf("Could not enumerate slots\n");
+ ret = 1;
+ } else if (!(ret = store_certificate(target, cert) ? 1 : 0)) {
+ printf("Certificate stored\n");
+ ret = 0;
+ }
+
+ ENGINE_finish(engine);
+
+ CONF_modules_unload(1);
+end:
+ X509_free(cert);
+
+ return ret;
+}
More information about the pkg-opensc-maint
mailing list