PKCS#11 states for flag CKF_INTERFACE_FORK_SAFE:
"The returned interface will have fork tolerant semantics. When the
application forks, each process will get its own copy of all session
objects, session states, login states, and encryption states. Each
process will also maintain access to token objects with their previously
supplied handles."
This is not how Opencryptoki behaves. The forked child starts as if
cryptoki has never been initialized, it needs to initialize the cryptoki
library freshly with C_Initialize if needed.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Assign apiSessp->slotID and apiSessp->rw_session before adding the new
session to the global session list. Doing so afterwards leaves a small
window where the new session is already added to the global session list,
but these fields are not yet assigned. This could affect closing all
sessions of slot 0, incorrectly closing the newly added session
because the slot ID is not yet set and thus 0.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Implement C_En/DecapsulateKey functions by routing them through to the
tokens. Also add base support for en-/decapsulation in the key manager.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
PKCS#11 v3.2 states: "Any mechanism that supports C_VerifyInit must also
support C_VerifySignatureInit."
Use common code for both variants, C_VerifyInit, C_Verify, C_VerifyUpdate,
C_VerifyFinal, as well as C_VerifySignatureInit, C_VerifySignature,
C_VerifySignatureUpdate, C_VerifySignatureFinal.
The only difference is that for C_VerifySignatureInit the signature to be
verified is passed at the init call, while for C_VerifyInit, it is passed
only at the final call.
C_VerifySignatureInit saves the signature in the context, so that it is
available later when the final verification is performed. That way the
tokens do not need to implement both variants, but can support both
transparently.
It is ensured that the sequence of calls can not be mixed. Otherwise
CKR_OPERATION_NOT_INITIALIZED is returned.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Add support for the new PKCS#11 v3.2 function list and the new functions
(all of them return CKR_FUNCTION_NOT_SUPPORTED as of now), as well as
for the new encapsulate/decvapsulate attributes.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
PKCS#11 v3.0 and later states the following for C_XxxInit() calls:
C_XxxInit can be called with pMechanism set to NULL_PTR to terminate an
active operation. If an operation has been initialized and it cannot be
cancelled, CKR_OPERATION_CANCEL_FAILED must be returned.
Implement this by calling session_mgr_cancel() with the appropriate operation
flag in case pMechanism is NULL. This is the same effect as if
C_SessionCancel() is called with the same operation flag.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Add defines for mechanism CKM_RSA_AES_KEY_WRAP to the header file, the
mechanism table, as well as the policy and statistics code.
Field ulAESKeyBits of the CK_RSA_AES_KEY_WRAP_PARAMS mechanism parameter
may not be set when performing unwrap. For unwrap, the size of the
temporary AES key is a result of unwrapping, and may not be known
by the caller. Field ulAESKeyBits should be set to zero if unknown.
In such cases the policy check can not check if the size of the
temporary AES key is according to the used policy.
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>
Register an atexit handler to gracefully terminate openCryptoki and close all
open sessions during termination. This is also done in the destructor of the
OpenCryptoki library. However, the library destructor is called after the
atexit handlers.
The atexit handler registration must be AFTER OpenSSL initialization, because
OpenSSL also registers its own atexit handler during its initialization.
The atexit handlers are called in the reverse order of their registration.
So if we register our at-exit handler AFTER OpenSSL registered its atexit
handler, we are sure that ours gets called BEFORE the OpenSSL atexit handler.
This is important because we need to use OpenSSL services during our atexit
termination, so this works only before OpenSSL has performed its cleanup in
its atexit handler. This is also the reason why we need our own atexit handler
at all, because the library destructor is called after OpenSSLs atexit handler,
and thus OpenSSL services are no longer available at that point in time.
Note that if the calling application has already initialized OpenSSL before
initializing OpenCryptoki, then above OpenSSL initialization done by
OpenCryptoki is a no-operation, but still OpenSSL has already registered its
atexit handler during an earlier OpenSSL initialization, i.e. before we
register ours.
Further note that when the OpenCryptoki library is unloaded by means of
dlclose(), then the atexit handler (which is located inside the unloaded
library) is unregistered automatically. Otherwise this would cause segfaults
when the no longer existent atexit handler would be called.
Nevertheless, the library destructor is called to perform termination in that
case. Here, OpenSSL services are still available, so it is safe to use them
during the library destructor.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Opencryptoki initializes OpenSSL as part of its own initialization in
C_Initialize. During OpenSSL initialization, the OpenSSL config file is
evaluated, and engines or providers may be loaded and initialized.
An engine or provider may itself use Opencryptoki and thus may call
C_Initialize as part of its initialization. This leads to a recursive
call of C_Initialize and thus to a deadlock because C_Initialize locks
the global mutex while it initializes.
Add special handling to allow recursive calls of C_Initialize coming
from the OpenSSL initialization triggered by Opencryptoki. Move the OpenSSL
initialization to the very beginning of C_Initialize, and release the global
mutex before calling OPENSSL_init_crypto. On return from OPENSSL_init_crypto,
check if Opencryptoki has been initialized recursively, and skip further
initialization if so.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Ensure OpenSSL is initialized and the OpenSSL config is loaded BEFORE creating
OpenCryptoki's own library context. Otherwise the OpenSSL config is loaded
later, which may cause that all configured providers are also loaded into the
library context. We intentionally want to use only the default and legacy
provider for OpenCryptoki's software crypto operations. So loading other
providers into our context may cause that those other providers are used
instead. In worst case this may cause a recursion, e.g. when a PKCS#11 provider
is loaded routing the crypto calls back to OpenCryptoki.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Allow to specify the pkcsslotd user and the pkcs11 group during
configuration.
Use '--with-pkcsslotd-user=USER' and/or '--with-pkcs-group=GROUP'
to specify the user and group name. The defaults are 'pkcsslotd'
and 'pkcs11'.
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>
In case an OpenSSL function failed inside of the API function,
the OpenSSL error stack should show the reasons for the failure.
Please note that an error on the OpenSSL error stack does not necessarily
mean that an error has happened that would cause the API function to fail.
Some error situations are expected and internally handled, and do not lead
to a failure of the API function.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
C_SessionCancel terminates active session based operations.
To identify which operation(s) should be terminated, the flags parameter
should be assigned the logical bitwise OR of one or more of the bit
flags defined in the CK_MECHANISM_INFO structure.
If no flags are set, the session state will not be modified and CKR_OK
will be returned.
If a flag is set for an operation that has not been initialized in the
session, the operation flag will be ignored and C_SessionCancel will
behave as if the operation flag was not set.
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>
Only cleanup OpenSSL library context and providers if we are not in the
library destructor. The library destructor calls C_Finalize if not
already finalized, but this may happen during at-exit handlers when the
program is terminating. At that point in time, the OpenSSL at-exit
handler may already have performed cleanup which will then cause
crashes when trying to cleanup the already freed library context here.
We are leaking the library context and providers if one just unloads
the library without calling C_Finalize. However, OpenSSL cleanup will
clean up the context at program termination anyway
Closes: https://github.com/opencryptoki/opencryptoki/issues/527
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Usually opencryptoki's own library context is freed during C_Finalize().
However, when an application does not call C_Finalize() before it exits,
the cleanup is performed in the library destructor when the library
is unloaded (i.e. during exit handlers).
OpenSSL also performs its own cleanup in exit handlers, and it may happen
that OpenSSL cleanup is performed before the library destructors are
called. This may cause crashes when Opencryptoki's library context has
already been freed by OpenSSL cleanup, but the library destructor tries to
free it a second time. This causes a double free, and very likely a crash.
Register an OpenSSL cleanup handler to clean up the library context before
OpenSSL performs its own cleanup.
Closes: https://github.com/opencryptoki/opencryptoki/issues/527
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>
Also count implicit mechanism usage, such as mechanisms referenced
from within mechanism params, i.e. RSA-PSS or RSA-OAEP hash mechanisms
or mask generation functions (MGFs), and key derivation functions (KDFs)
for ECDH key derivation.
Signed-off-by: Ingo Franzki <ifranzki@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>
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>
The default provider only supports 3DES and 2DES, but not single DES.
The DES routines inside mech_openssl.c also implement single DES, so
the legacy provider is also needed.
Signed-off-by: Ingo Franzki <ifranzki@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>
Internal use of OpenSSL calls may cause additional errors to be pushed
to the current thread's OpenSSL error stack. This may interfere with
the calling application's use of the OpenSSL error stack, and may leak
Opencryptoki internal error information to the application.
On exit of all Opencryptoki API calls, make sure to restore the current
thread's error stack to the state it was on entry to the Opencryptoki
API call.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Create a separate library context for Opencryptoki's use of OpenSSL services
and explicitly load the 'default' provider for this context.
This prevents call-loops when the calling application has configured a PKCS#11
provider that uses Opencryptoki under the covers. This could produce a loop
with the following calling tree:
Application -> Openssl -> PKCS11-provider -> Opencryptoki -> OpenSSL
-> PKCS11-provider -> Opencryptoki -> ...
Explicitly using the 'default' provider only for Opencrypoki's OpenSSL usage
breaks this loop.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Fail if flag CKF_LIBRARY_CANT_CREATE_OS_THREADS is set at C_Initialize,
and event support is enabled (this is the default). We need to use pthreads
for the event thread, so we can't work if CKF_LIBRARY_CANT_CREATE_OS_THREADS
is set. Fail with CKR_NEED_TO_CREATE_THREADS if so.
The event support can be globally disabled using keyword 'disable-event-support'
in opencryptoki.conf. This disables pkcsslots to accept admin connections,
and it does not monitor for AP UDEV events (on s390 platform). No event
thread is started in the opencryptoki processes, thus we can accept if flag
CKF_LIBRARY_CANT_CREATE_OS_THREADS is set in that case.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Calling dlclose() in a atfork handler may cause a deadlock.
dlclose() may itself modify the atfork handler table to remove
any fork handlers that the to be unloaded library has registered.
Since the atfork handler table is currently locked when we are in
an atfork handler, this would produce a deadlock.
Skip the dlclose() if we are in an atfork handler to avoid the deadlock.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
The C_Sign/Verify, C_Sign/VerfyUpdate, C_Sign/VerifyFinal are supposed to
terminate the current operation on a error return. The same is true for
C_Encrypt/Decrypt and friends. To be able to terminate the operation, the
parameter checking must be done by the token DLL, and can not be done by
the API layer. The code in the token DLL already contains these parameter
checks anyway.
Only parameters related to the session must still be checked in the API layer.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Return CKR_TEMPLATE_INCONSISTENT when the template at C_CreateObject
does not contain a sub-class attribute, because this could also be
caused by an unknown object type.
Return CKR_ARGUMENTS_BAD if template is NULL.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>