Create the lock files using O_NOFOLLOW to prevent symlink-following.
Lock files are just opened but no data is written to it or read from it.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Use strcmp(), not strncmp() for checking if a user is a member of a group.
Using strncmp() with the length of the user name might match to a longer
group member that has the same prefix as the user.
Note that this user-space checking is just to report inconsistencies with
a user friendly error message. The real security relies on the file
permissions based on user and group checked by the kernel. So incorrectly
matching a user does not cause a security hole.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Add '--enable-sanitizer' option to easily enable a build with sanitizer.
This requires that libasan and libubsan are available.
When running with sanitizer, disable unloading of the Opencryptoki
shared libraries, to produce useful stack traces.
For the same reason 'export LSAN_OPTIONS=fast_unwind_on_malloc=false'
might be required when running the built executable.
Attention: This may make it very slow!
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
When using the pkcshsm_mk_change tool to initiate a concurrent master
key change, it is important that all affected tokens are available and
that the user using the pkcshsm_mk_change tool has permissions to use all
tokens, i.e. the user should be part of all token groups.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
A new optional key value pair named 'usergroup' can be specified within a
slot structure to specify the user group name that is set as the owner of
the token directory. Only users that are members of this group have access
to the token and its objects. Users that are not a member of this group
will not see the token as being available (e.g. via 'pkcsconf -t' or via
'C_GetTokenInfo').
If no token group is specified, then the token is owned by the 'pkcs11' group
like before this change.
If a token user group is specified, then the pkcsslotd checks if that group
exists, and if all members of that group are also members of the 'pkcs11'
group. This is required to be able to access the pkcsslotd socket at all.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
There are implementation-defined behaviours that need to be handled for various
UNIX platforms. For instance, the file locking featureset from BSD (`flock`)
requires the file to be opened in write mode on AIX, but Linux does not care
about the mode in which the file is opened. To preserve backward compatibility,
however, Linux retains its existing file mode; otherwise previous/leftover
daemon runs will cause future daemon startup failures - the lock can never be
obtained in the new file mode, because it will attempt to open a file with mode
bits `-r--` in write mode, which will never succeed (always returns `EPERM`).
There will be no difference to AIX because the open mode is still decided at
compile time, depending on the platform.
Dynamic token loading has also been changed, such that the symbols from all
token libraries are not visible in the process namespace anymore. This is
important because global symbol visibility affects the functionality that is
loaded - because each token exposes the same set of symbols, which have
differing behaviours based on the type of the token. The order in which the
tokens are specified in the configuration also makes a difference here, since
the token that was loaded first overrides the symbols that any later token
load provides. This basically means that all tokens that are not loaded first
do not have their symbols visible to the loading process, which means their
functions are never executed. Restricting the symbol visibility to the library
itself (`RTLD_LOCAL`) solves this issue.
IBM's xlc requires the `init` and `fini` functions to be specified on the
command-line, in addition to being specified as `pragma`s within the source
code. Furthermore, the format of the symbol export definition file differs
from that of gcc. xlc does not have semver support for shared libraries, and
therefore the export format file necessitates being different. This file is
therefore now generated dynamically during the configuration phase by an
(admittedly) hacky string manipulation within configure.ac. But it works(tm),
so it stays in until it breaks.
Signed-off-by: Akash Kulhalli <akash.kulhalli@ibm.com>
Similar to the global session and R/W session counters in pkcsslotds shared
memory segment, add another counter field that a token can use for counting
token specific things.
The pkcsslotd also tracks this counter, and ensures that if a process dies
without decreasing its counter properly, then pkcsslotd adjusts the global
counter automatically during garbage collection to maintain a consistent
counter value across all processes.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
The use of transactional memory has never really worked for openCryptoki.
Also, many code places use locks, even with '--disable-locks'.
Option '--enable-locks' has been the default so far.
To retain backward compatibility, continue to accept the '--disable-locks'
option during configuration, but ignore it if it is specified. A warning
message is issued if --disable-locks' is still used.
With this change, there is no longer a need to maintain 2 copies of the
btree.c and sess_mgr.c source (btree.c and lock_btree.c, sess_mgr.c and
lock_sess_mgr.c), which contained the same code except the differences for
supporting transactional memory versus locks. Now only the version with
locks is retained, but it is renamed to not contain the 'lock_' prefix any
more.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Check errors for all RW-lock or mutex initialization calls, and perform
proper error handling and cleanup if it fails.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Avoid race conditions between an API function being called in a
thread, and any HSM master key state changes being done in the event
thread. Each API function that involves objects or sessions state
acquire a read lock on the per-slot HSM MK change R/W lock. Anyone
that changes the HSM MK change state acquires a write lock. That
way the API functions can run concurrently unless a HSM MK change
state changing operation is performed.
This is implemented in the API layer so that tokens do not have to
care about this themselves. Tokens that support HSM MK changes,
initialize the R/W lock and thus tell the API layer to perform locking
on each API call. Tokens that do not support HSM MK changes, are
not affected, and do not use an R/W lock.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Currently only CK_TOKEN_INFO.ulSessionCount is maintained with the
total number of sessions open by a token, but ulRwSessionCount is
set to CK_UNAVAILABLE_INFORMATION.
Besides the total number of sessions also maintain the number of R/W
sessions, so that ulRwSessionCount can be returned with accurate
information.
Similar as for the total number of sessions, the counter is kept in
the shared memory segment of the pkcsslotd. It exists once as global
counter, and once per process. When a process dies without unregistering
from pkcsslotd, the garbage collector of pkcsslotd decrements the global
counter by the amount of the per-process counter to keep the global
counter consistent.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
When running within a pid and/or user namespace, make sure to register
the process in pkcsslotd's shared memory segment using the pid from the
root namespace (the one pkcsslotd is running in), and not the applications
namespace. The application pid may be different to its pid in the root
namespace, and may especially be not unique within the root name space.
Since the pid is used as unique identifier in pkcsslotd's shared memory
segment we must use the applications pid in the root namespace.
Also use the uid from root namespace to create the shared memory segment
for user statistics. The uid in the applications namesapce may be different
to its uid in the root namespace, and may especially be not unique within
the root name space, and thus could cause that statistics of other users are
updated instead of the current user's one.
Trace files are still named using the pid of the applications namespace.
At the time the trace file is opened, the pid from the root namespace is
not yet know. There is a is a slight chance that two processes running in
different namespaces use the same pid, and thus use the same trace file.
In this case existing trace files may get overwritten or tracing is
disabled for a process. Re-opening the trace file once the process's pid
from the root namespace is known does not make much sense, since the
initial part of the trace has been written to the 'wrong' trace file
already at that time.
Since the initial data sent via socket is changed anyway, fix the following
issue right away:
Closes: https://github.com/opencryptoki/opencryptoki/issues/469
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Make use of mechanism table to translate between string and numeric format of
mechanisms. Remove duplicated code dealing with mechanism translations.
Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
Implement strength and policy parsing and enforce policies in all tokens. The
main object of the policy is the struct objstrength which carries the strength
of a key along with a flag specifying if the EC is allowed, and a (maximal)
signature length if this key is used to sign or verify and the length of the
signature depends on the key.
A valid strength configuration has to be found. If no policy configuration is
found, policies are simply deactivated and keys are only classified according
to the strength definition, but can be used without restrictions. If both, a
strength and a policy configuration, are available, both have to be valid for
OpenCryptoki to start. If either of these two configurations fails to parse
or validate, OpenCryptoki will fail with a general error since the system is
not in a valid state.
The configuration files have to be owned by root:pkcs11 and have to have modes
0640. This is done for security reasons to prevent anybody except root from
altering the policy or strength definitions.
Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
C_GetSlotList with tokenPresent=false is supposed to list all
configured slots, not only those with a token present. Also
let 'pkcsconf -t' and 'pkcsconf -l' list all configured slots,
not only those with a token present
Closes: https://github.com/opencryptoki/opencryptoki/issues/480
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Since we did not set TokData to NULL after freeing it, we double freed it
under certain circumstances.
Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
Make sure the TokData member is always freed. Special care has to be taken
for the fork situation. In that case, we have to free TokData but block all
paths to a dlclose.
Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
Do not check user/group permissions in every token on token initialization.
The check can easily be done in API library once for all tokens.
Also allocate the TokData structure in the API library. This allows the API
library to pass other objects to the tokens without changing the signature of
the initialization function.
Signed-off-by: Juergen Christ <jchrist@linux.ibm.com>
When a process is forked while it has open sessions with the ICSF
token, then the fork initializer running in the client process should
_NOT_ close the LDAP connections associated with the sessions during
C_Finalize inside the fork initializer.
Closing the LDAP connection in the client would also close the connection
for the parent process, since client and parent share the same socket
after the fork. However, the parent still wants to continue working with
its LDAP connection after the fork.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Now that the code uses reference counts and is made thread save,
the global API lock is no longer needed.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
This ensures that an object can not be freed while it is still used
by another thread. The object might still be removed from a btree while another
thread is using it, but the object is not freed until its ref count is zero.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
At bt_init() the delete callback function is registered, and is
stored inside struct btree. On bt_node_free() and bt_destroy() the
registered callback function is used. No need to specify the callback
function on every bt_node_free() or bt_destroy().
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
To fully support using multiple token instances of the same type in
one process, there can not be any global variables that contain token
state. All state must be hold in the struct _STDLL_TokData_t on a per
token instance basis. Also remove some useless globals.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Lock C_Initialize and C_Finalize with the GlobalMutex, to prevent
multiple threads to initialize or terminate concurrently. No
further locking needed in ST_Initialize, thus remove global native_mutex.
When a child process is forked off, terminate all tokens and let them
clean up their stuff. The forked client process needs to call C_Initialize
again as per PKCS#11 standard (see PKCS #11 Cryptographic Token Interface
Usage Guide Version 2.40 section 2.5.2 Applications and Processes).
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Use a recursive mutex in the API-slot to lock the API calls
against concurrent use by other threads of the same process.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
The cross-process locks use an flock to lock against other processes.
However, this does not protect against other threads within the same
process. Add a pthread recursive mutex to also protect against threads.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
A stat() before open() is not required and can cause timing
ralted errors. The code can directly react on the result of
open(). Flag O_CREAT will create the file only if it is not
existent, so we don't need to know upfront if the file exists
already or not.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>