- Resolves: #1959894, Soft token does not check if an EC key is valid

- Resolves: #1924120, Event Notification Support
This commit is contained in:
Than Ngo 2021-05-17 17:23:09 +02:00
parent fe60ad7512
commit 28bfbcca91
15 changed files with 8055 additions and 1 deletions

View File

@ -0,0 +1,136 @@
commit 19f56d12b302b87e1dacf613cc61a063ad209d15
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri Feb 12 15:57:20 2021 +0100
Fix compile warning when compiling pkcsslotd with -DDEV and/or -DTHREADED
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/sbin/pkcsslotd/garbage_linux.c b/usr/sbin/pkcsslotd/garbage_linux.c
index d4878c3b..a4dd9713 100644
--- a/usr/sbin/pkcsslotd/garbage_linux.c
+++ b/usr/sbin/pkcsslotd/garbage_linux.c
@@ -15,6 +15,7 @@
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
+#include <stdlib.h>
#include "log.h"
#include "slotmgr.h"
@@ -80,8 +81,8 @@ BOOL StartGCThread(Slot_Mgr_Shr_t *MemPtr)
#ifdef DEV
// Only development builds
LogLog("StartGCThread: garbage collection thread started as ID "
- "%d (%#x) by ID %d (%#x)",
- GCThread, GCThread, pthread_self(), pthread_self());
+ "%lu by ID %lu",
+ GCThread, pthread_self());
#endif
return TRUE;
@@ -115,8 +116,8 @@ BOOL StopGCThread(void *Ptr)
return FALSE;
}
- DbgLog(DL0, "StopGCThread: tid %d is stopping the garbage collection "
- "thread (tid %d)",
+ DbgLog(DL0, "StopGCThread: tid %lu is stopping the garbage collection "
+ "thread (tid %lu)",
pthread_self(), GCThread);
/* Cause the GC thread to be cancelled */
@@ -245,7 +246,7 @@ void GCCancel(void *Ptr)
UNUSED(Ptr);
/* Yeah, yeah. Doesn't do anything, but I had plans */
- DbgLog(DL3, "GCCancel: tid: %d running cleanup routine", pthread_self());
+ DbgLog(DL3, "GCCancel: tid: %lu running cleanup routine", pthread_self());
return;
}
@@ -268,7 +269,7 @@ BOOL CheckForGarbage(Slot_Mgr_Shr_t *MemPtr)
ASSERT(MemPtr != NULL_PTR);
#ifdef DEV
- DbgLog(DL5, "Thread %d is checking for garbage", pthread_self());
+ DbgLog(DL5, "Thread %lu is checking for garbage", pthread_self());
#endif /* DEV */
@@ -326,9 +327,9 @@ BOOL CheckForGarbage(Slot_Mgr_Shr_t *MemPtr)
if (*pProcSessions > 0) {
#ifdef DEV
- DbgLog(DL2, "GC: Invalid pid (%d) is holding %d sessions "
+ DbgLog(DL2, "GC: Invalid pid (%d) is holding %u sessions "
"open on slot %d. Global session count for this "
- "slot is %d",
+ "slot is %u",
pProc->proc_id, *pProcSessions, SlotIndex,
*pGlobalSessions);
#endif /* DEV */
@@ -338,9 +339,9 @@ BOOL CheckForGarbage(Slot_Mgr_Shr_t *MemPtr)
WarnLog("Garbage Collection: Illegal values in table "
"for defunct process");
DbgLog(DL0, "Garbage collection: A process "
- "( Index: %d, pid: %d ) showed %d sessions "
- "open on slot %s, but the global count for this "
- "slot is only %d",
+ "( Index: %d, pid: %d ) showed %u sessions "
+ "open on slot %d, but the global count for this "
+ "slot is only %u",
ProcIndex, pProc->proc_id, *pProcSessions,
SlotIndex, *pGlobalSessions);
#endif /* DEV */
@@ -395,14 +396,8 @@ int Stat2Proc(int pid, proc_t *p)
char fbuf[800]; // about 40 fields, 64-bit decimal is about 20 chars
char *tmp;
int fd, num;
- // FILE *fp;
-
- // sprintf(buf, "%s/%d/stat", PROC_BASE, pid);
- // if( (fp = fopen(buf, "r")) == NULL )
- // return FALSE;
sprintf(fbuf, "%s/%d/stat", PROC_BASE, pid);
- printf("Buff = %s \n", fbuf);
fflush(stdout);
if ((fd = open(fbuf, O_RDONLY, 0)) == -1)
return FALSE;
diff --git a/usr/sbin/pkcsslotd/log.c b/usr/sbin/pkcsslotd/log.c
index 0214f952..0394cc7d 100644
--- a/usr/sbin/pkcsslotd/log.c
+++ b/usr/sbin/pkcsslotd/log.c
@@ -463,8 +463,8 @@ BOOL PKCS_Log(pLogHandle phLog, char *fmt, va_list ap)
#endif /* DEV */
if (WriteNow) {
- fprintf(stderr, "%s[%d.%d]: %s\n", pInfo->Descrip, getpid(),
- (int) pthread_self(), buf);
+ fprintf(stderr, "%s[%d.%lu]: %s\n", pInfo->Descrip, getpid(),
+ pthread_self(), buf);
}
}
@@ -482,7 +482,7 @@ BOOL PKCS_Log(pLogHandle phLog, char *fmt, va_list ap)
GetCurrentTimeString(timebuf);
/* Date/Time stamp, descrip, Error message */
- fprintf(fd, "%s %s[%d.%d]: ", timebuf, pInfo->Descrip, getpid(),
+ fprintf(fd, "%s %s[%d.%lu]: ", timebuf, pInfo->Descrip, getpid(),
pthread_self());
fprintf(fd, "%s\n", buf);
fflush(fd);
diff --git a/usr/sbin/pkcsslotd/slotmgr.c b/usr/sbin/pkcsslotd/slotmgr.c
index 94288f13..efbfe8fd 100644
--- a/usr/sbin/pkcsslotd/slotmgr.c
+++ b/usr/sbin/pkcsslotd/slotmgr.c
@@ -660,7 +660,6 @@ int main(int argc, char *argv[], char *envp[])
*/
#if !defined(NOGARBAGE)
- printf("Start garbage \n");
/* start garbage collection thread */
if (!StartGCThread(shmp)) {
term_socket_server();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
commit 4e3b43c3d8844402c04a66b55c6c940f965109f0
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon May 3 10:05:07 2021 +0200
SOFT: Check the EC Key on C_CreateObject and C_DeriveKey
When constructing an OpenSSL EC public or private key from PKCS#11
attributes or ECDH public data, check that the key is valid, i.e. that
the point is on the curve.
This prevents one from creating an EC key object via C_CreateObject with
invalid key data. It also prevents C_DeriveKey to derive a secret using
ECDH with an EC public key (public data) that uses a different curve
or is invalid by other means.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/soft_stdll/soft_specific.c b/usr/lib/soft_stdll/soft_specific.c
index c30be1da..aeff39a9 100644
--- a/usr/lib/soft_stdll/soft_specific.c
+++ b/usr/lib/soft_stdll/soft_specific.c
@@ -4365,6 +4365,12 @@ static CK_RV fill_ec_key_from_pubkey(EC_KEY *ec_key, const CK_BYTE *data,
goto out;
}
+ if (!EC_KEY_check_key(ec_key)) {
+ TRACE_ERROR("EC_KEY_check_key failed\n");
+ rc = CKR_PUBLIC_KEY_INVALID;
+ goto out;
+ }
+
out:
if (allocated && ecpoint != NULL)
free(ecpoint);
@@ -4404,6 +4410,12 @@ static CK_RV fill_ec_key_from_privkey(EC_KEY *ec_key, const CK_BYTE *data,
goto out;
}
+ if (!EC_KEY_check_key(ec_key)) {
+ TRACE_ERROR("EC_KEY_check_key failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
out:
if (point != NULL)
EC_POINT_free(point);

View File

@ -0,0 +1,23 @@
commit 69244a5e0d9dfec3ef534b19b89a541576bb17dc
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue Feb 9 10:47:57 2021 +0100
TRACE: Use gettid() if SYS_gettid is not defined
Also print the thread ID in the trace, if SYS_gettid is not defined.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/common/trace.c b/usr/lib/common/trace.c
index 678c0b96..bdc5256a 100644
--- a/usr/lib/common/trace.c
+++ b/usr/lib/common/trace.c
@@ -33,6 +33,8 @@
#ifdef SYS_gettid
#define __gettid() syscall(SYS_gettid)
+#else
+#define __gettid() gettid()
#endif
pthread_mutex_t tlmtx = PTHREAD_MUTEX_INITIALIZER;

View File

@ -0,0 +1,367 @@
commit 7b7d83c571ceb3050969359817d4145600f14ae8
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri Apr 9 17:07:31 2021 +0200
Check CKF_LIBRARY_CANT_CREATE_OS_THREADS at C_Initialize
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>
diff --git a/man/man5/opencryptoki.conf.5.in b/man/man5/opencryptoki.conf.5.in
index 71218f79..7dc676ab 100644
--- a/man/man5/opencryptoki.conf.5.in
+++ b/man/man5/opencryptoki.conf.5.in
@@ -10,8 +10,16 @@ pkcs#11 slots. At startup, the pkcsslotd daemon parses this file to
determine which slots will be made available.
.SH SYNTAX
-This file is made up of slot descriptions. Each slot description
-is composed of a slot number, brackets and key-value pairs.
+This file is made up of optional global definitions, and slot descriptions.
+
+The following global definitions are valid:
+
+.TP
+.BR disable-event-support
+If this keyword is specified the openCryptoki event support is disabled.
+
+.P
+Each slot description is composed of a slot number, brackets and key-value pairs.
slot number
{
diff --git a/usr/include/slotmgr.h b/usr/include/slotmgr.h
index e37368a5..451a8cf1 100644
--- a/usr/include/slotmgr.h
+++ b/usr/include/slotmgr.h
@@ -99,6 +99,7 @@ typedef struct {
LW_SHM_TYPE *shm_addr; // token specific shm address
} Slot_Info_t;
+#define FLAG_EVENT_SUPPORT_DISABLED 0x01
#ifdef PKCS64
@@ -200,6 +201,7 @@ typedef struct {
typedef struct {
uint8 num_slots;
+ uint8 flags;
CK_INFO_64 ck_info;
Slot_Info_t_64 slot_info[NUMBER_SLOTS_MANAGED];
} Slot_Mgr_Socket_t;
@@ -214,6 +216,7 @@ typedef struct {
typedef struct {
uint8 num_slots;
+ uint8 flags;
CK_INFO ck_info;
Slot_Info_t slot_info[NUMBER_SLOTS_MANAGED];
} Slot_Mgr_Socket_t;
diff --git a/usr/lib/api/api_interface.c b/usr/lib/api/api_interface.c
index 2873a20a..6517ca6c 100644
--- a/usr/lib/api/api_interface.c
+++ b/usr/lib/api/api_interface.c
@@ -308,7 +308,8 @@ void parent_fork_after()
return;
/* Restart the event thread in the parent when fork is complete */
- if (Anchor->event_thread == 0)
+ if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 &&
+ Anchor->event_thread == 0)
start_event_thread();
}
@@ -2752,13 +2753,7 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid)
goto error;
}
}
- // If we EVER need to create threads from this library we must
- // check the Flags for the Can_Create_OS_Threads flag
- // Right now the library DOES NOT create threads and therefore this
- // check is irrelavant.
- if (pArg->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) {
- TRACE_DEVEL("Can't create OS threads...This is OK\n");
- }
+
// Since this is an initialization path, we will be verbose in the
// code rather than efficient.
//
@@ -2848,7 +2843,21 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid)
rc = CKR_FUNCTION_FAILED;
goto error_shm;
}
- // Initialize structure values
+
+ if (pVoid != NULL) {
+ pArg = (CK_C_INITIALIZE_ARGS *) pVoid;
+
+ if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 &&
+ (pArg->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) != 0) {
+ TRACE_ERROR("Flag CKF_LIBRARY_CANT_CREATE_OS_THREADS is set and "
+ "event support is enabled\n");
+ OCK_SYSLOG(LOG_ERR, "C_Initialize: Application specified that "
+ "library can't create OS threads. PKCS11 Module requires "
+ "to create threads when event support is enabled.\n");
+ rc = CKR_NEED_TO_CREATE_THREADS;
+ goto error;
+ }
+ }
//Register with pkcsslotd
if (!API_Register()) {
@@ -2867,7 +2876,8 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid)
}
/* Start event receiver thread */
- if (start_event_thread() != 0) {
+ if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 &&
+ start_event_thread() != 0) {
TRACE_ERROR("Failed to start event thread\n");
// unload all the STDLL's from the application
diff --git a/usr/lib/common/configparser.h b/usr/lib/common/configparser.h
index 13ca648d..b3c32496 100644
--- a/usr/lib/common/configparser.h
+++ b/usr/lib/common/configparser.h
@@ -35,6 +35,7 @@ typedef int (*end_slot_f)(void *private);
typedef int (*key_str_f)(void *private, int tok, const char *val);
typedef int (*key_vers_f)(void *private, int tok, unsigned int vers);
typedef void (*eolcomment_f)(void *private, const char *comment);
+typedef void (*disab_event_supp_f)(void *private);
/*
* Report an error. If the error is not reported by the parser itself
* but via one of the parse functions, \c parsermsg will be \c NULL.
@@ -52,6 +53,7 @@ typedef void (*error_f)(void *private, int line, const char *parsermsg);
*/
struct parsefuncs {
ockversion_f version;
+ disab_event_supp_f disab_event_supp;
eol_f eol;
begin_slot_f begin_slot;
end_slot_f end_slot;
diff --git a/usr/lib/common/lexer.l b/usr/lib/common/lexer.l
index b35a0b72..38cbcb70 100644
--- a/usr/lib/common/lexer.l
+++ b/usr/lib/common/lexer.l
@@ -69,6 +69,7 @@ extern char *configparse_strdup(const char *s);
version return OCKVERSION;
slot return SLOT;
+disable-event-support return DISABLE_EVENT_SUPPORT;
[^\"= \t\n]+ {
yylval.str = configparse_strdup(yytext);
diff --git a/usr/lib/common/parser.y b/usr/lib/common/parser.y
index 86806fcb..40c3994d 100644
--- a/usr/lib/common/parser.y
+++ b/usr/lib/common/parser.y
@@ -65,7 +65,7 @@ int lookup_keyword(const char *key);
int err;
}
-%token EQUAL DOT SLOT EOL OCKVERSION BEGIN_DEF END_DEF
+%token EQUAL DOT SLOT EOL OCKVERSION BEGIN_DEF END_DEF DISABLE_EVENT_SUPPORT
%token <str> STRING
%token <str> KEYWORD
%token <num> INTEGER
@@ -81,6 +81,7 @@ config_file:
sections:
version_def eolcomment
+ | disable_event_support_def eolcomment
| SLOT INTEGER BEGIN_DEF
{
if (parsefuncs->begin_slot && parsefuncs->begin_slot(parsedata, $2, 0)) {
@@ -125,6 +126,13 @@ version_def:
}
configparse_freestringsfrom($2);
}
+
+disable_event_support_def:
+ DISABLE_EVENT_SUPPORT
+ {
+ if (parsefuncs->disab_event_supp)
+ parsefuncs->disab_event_supp(parsedata);
+ }
line_def:
STRING EQUAL TOKVERSION
diff --git a/usr/sbin/pkcsslotd/pkcsslotd.h b/usr/sbin/pkcsslotd/pkcsslotd.h
index d7edcb3c..1dd0bac9 100644
--- a/usr/sbin/pkcsslotd/pkcsslotd.h
+++ b/usr/sbin/pkcsslotd/pkcsslotd.h
@@ -88,7 +88,7 @@ int XProcLock(void);
int XProcUnLock(void);
int CreateXProcLock(void);
-int init_socket_server();
+int init_socket_server(int event_support_disabled);
int term_socket_server();
int init_socket_data(Slot_Mgr_Socket_t *sp);
int socket_connection_handler(int timeout_secs);
diff --git a/usr/sbin/pkcsslotd/slotmgr.c b/usr/sbin/pkcsslotd/slotmgr.c
index efbfe8fd..3b328a6c 100644
--- a/usr/sbin/pkcsslotd/slotmgr.c
+++ b/usr/sbin/pkcsslotd/slotmgr.c
@@ -34,6 +34,7 @@ int shmid;
key_t tok;
Slot_Info_t_64 sinfo[NUMBER_SLOTS_MANAGED];
unsigned int NumberSlotsInDB = 0;
+int event_support_disabled = 0;
Slot_Info_t_64 *psinfo;
@@ -467,6 +468,13 @@ static int slotmgr_key_vers(void *private, int tok, unsigned int vers)
return 1;
}
+static void slotmgr_disab_event_supp(void *private)
+{
+ UNUSED(private);
+
+ event_support_disabled = 1;
+}
+
static void slotmgr_parseerror(void *private, int line, const char *parsermsg)
{
struct parse_data *d = (struct parse_data *)private;
@@ -480,6 +488,7 @@ static struct parsefuncs slotmgr_parsefuncs = {
.end_slot = slotmgr_end_slot,
.key_str = slotmgr_key_str,
.key_vers = slotmgr_key_vers,
+ .disab_event_supp = slotmgr_disab_event_supp,
.parseerror = slotmgr_parseerror
};
@@ -568,7 +577,7 @@ int main(int argc, char *argv[], char *envp[])
if (!XProcUnLock())
return 4;
- if (!init_socket_server()) {
+ if (!init_socket_server(event_support_disabled)) {
DestroyMutexes();
DetachFromSharedMemory();
DestroySharedMemory();
@@ -582,6 +591,8 @@ int main(int argc, char *argv[], char *envp[])
DestroySharedMemory();
return 6;
}
+ if (event_support_disabled)
+ socketData.flags |= FLAG_EVENT_SUPPORT_DISABLED;
/* Create customized token directories */
psinfo = &socketData.slot_info[0];
diff --git a/usr/sbin/pkcsslotd/socket_server.c b/usr/sbin/pkcsslotd/socket_server.c
index 41408670..3aa40267 100644
--- a/usr/sbin/pkcsslotd/socket_server.c
+++ b/usr/sbin/pkcsslotd/socket_server.c
@@ -139,12 +139,12 @@ struct event_info {
};
static int epoll_fd = -1;
-static struct listener_info proc_listener;
+static struct listener_info proc_listener = { .socket = -1 };
static DL_NODE *proc_connections = NULL;
-static struct listener_info admin_listener;
+static struct listener_info admin_listener = { .socket = -1 };
static DL_NODE *admin_connections = NULL;
#ifdef WITH_LIBUDEV
-static struct udev_mon udev_mon;
+static struct udev_mon udev_mon = { .socket = -1 };
#endif
static DL_NODE *pending_events = NULL;
static unsigned long pending_events_count = 0;
@@ -1620,6 +1620,9 @@ static void udev_mon_term(struct udev_mon *udev_mon)
if (udev_mon == NULL)
return;
+ if (udev_mon->socket < 0)
+ return;
+
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, udev_mon->socket, NULL);
if (udev_mon->udev != NULL)
udev_unref(udev_mon->udev);
@@ -1636,6 +1639,7 @@ int init_socket_data(Slot_Mgr_Socket_t *socketData)
{
unsigned int processed = 0;
+ socketData->flags = 0;
PopulateCKInfo(&(socketData->ck_info));
socketData->num_slots = NumberSlotsInDB;
PopulateSlotInfo(socketData->slot_info, &processed);
@@ -1692,7 +1696,7 @@ int socket_connection_handler(int timeout_secs)
return TRUE;
}
-int init_socket_server()
+int init_socket_server(int event_support_disabled)
{
int err;
@@ -1710,18 +1714,20 @@ int init_socket_server()
return FALSE;
}
- if (!listener_create(ADMIN_SOCKET_FILE_PATH, &admin_listener,
- admin_new_conn, NUMBER_ADMINS_ALLOWED)) {
- term_socket_server();
- return FALSE;
- }
+ if (!event_support_disabled) {
+ if (!listener_create(ADMIN_SOCKET_FILE_PATH, &admin_listener,
+ admin_new_conn, NUMBER_ADMINS_ALLOWED)) {
+ term_socket_server();
+ return FALSE;
+ }
#ifdef WITH_LIBUDEV
- if (!udev_mon_init(UDEV_SUBSYSTEM_AP, &udev_mon)) {
- term_socket_server();
- return FALSE;
- }
+ if (!udev_mon_init(UDEV_SUBSYSTEM_AP, &udev_mon)) {
+ term_socket_server();
+ return FALSE;
+ }
#endif
+ }
DbgLog(DL0, "%s: Socket server started", __func__);
diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
index 7c225730..94fd1196 100644
--- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
@@ -2066,6 +2066,13 @@ static int parseupdate_ockversion(void *private, const char *version)
return 0;
}
+static void parseupdate_disab_event_supp(void *private)
+{
+ struct parseupdate *u = (struct parseupdate *)private;
+
+ fprintf(u->f, "disable-event-support");
+}
+
static void parseupdate_eol(void *private)
{
struct parseupdate *u = (struct parseupdate *)private;
@@ -2124,6 +2131,7 @@ static void parseupdate_eolcomment(void *private, const char *comment)
static struct parsefuncs parseupdatefuncs = {
.version = parseupdate_ockversion,
+ .disab_event_supp = parseupdate_disab_event_supp,
.eol = parseupdate_eol,
.begin_slot = parseupdate_begin_slot,
.end_slot = parseupdate_end_slot,

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
commit b07505993dd8b2f367cf3b630f6da186e4e8550d
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed Feb 10 15:12:25 2021 +0100
Avoid deadlock in dlclose() after a fork
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>
diff --git a/usr/lib/api/api_interface.c b/usr/lib/api/api_interface.c
index 3ccb6d41..f1ee9132 100644
--- a/usr/lib/api/api_interface.c
+++ b/usr/lib/api/api_interface.c
@@ -1516,7 +1516,15 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved)
}
}
- DL_UnLoad(sltp, slotID);
+ /*
+ * 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.
+ */
+ if (!in_child_fork_initializer)
+ DL_UnLoad(sltp, slotID);
}
// Un register from Slot D

View File

@ -0,0 +1,21 @@
commit bf812c652c49d7e248b115d121a4f7f6568941a2
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue Apr 6 13:41:55 2021 +0200
Update travis yaml file to install libudev development files
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/.travis.yml b/.travis.yml
index d2907246..fd4092e3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,7 @@ language: c
before_install:
- sudo apt-get -qq update
- - sudo apt-get install -y expect trousers libldap2-dev libtspi-dev wget
+ - sudo apt-get install -y expect trousers libldap2-dev libtspi-dev wget libudev-dev
- sudo wget https://launchpad.net/ubuntu/+archive/primary/+files/libica3_3.4.0-0ubuntu1_s390x.deb
- sudo wget https://launchpad.net/ubuntu/+archive/primary/+files/libica-dev_3.4.0-0ubuntu1_s390x.deb
- sudo dpkg -i libica3_3.4.0-0ubuntu1_s390x.deb || true # icatok needs libica >= 3.3

View File

@ -0,0 +1,462 @@
commit c79e899d77a5724635a9d4451a34a240e2c7e891
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri Apr 16 13:41:41 2021 +0200
Fix potential deadlock situation with double read-locks
Do not get and read-lock an object twice within the same thread via
function object_mgr_find_in_map1(), as this would read-lock the object
twice.
This could cause a deadlock situation, when in-between the first
and the second call to object_mgr_find_in_map1() the token object is
modified by another process. The second object_mgr_find_in_map1() would
detect that the object has been modified (object_mgr_check_shm()), and
would try to re-load the object from the disk. For re-loading, the
object is unlocked once, and a write-lock is acquired instead.
However, if the current thread has read-locked the object twice, but
releases only one read-lock, then it will never get the write lock,
because it still owns the read lock itself.
To avoid this situation, release the read-lock before calling another
function that also acquires the read lock of the object. That way, only
one read-lock is held by the current thread, and re-loading the object
will not cause a deadlock.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/common/decr_mgr.c b/usr/lib/common/decr_mgr.c
index 317ef995..9842302b 100644
--- a/usr/lib/common/decr_mgr.c
+++ b/usr/lib/common/decr_mgr.c
@@ -540,6 +540,10 @@ CK_RV decr_mgr_init(STDLL_TokData_t *tokdata,
}
memset(ctx->context, 0x0, sizeof(AES_GCM_CONTEXT));
+ /* Release obj lock, token specific aes-gcm may re-acquire the lock */
+ object_put(tokdata, key_obj, TRUE);
+ key_obj = NULL;
+
rc = aes_gcm_init(tokdata, sess, ctx, mech, key_handle, 0);
if (rc) {
TRACE_ERROR("Could not initialize AES_GCM parms.\n");
diff --git a/usr/lib/common/encr_mgr.c b/usr/lib/common/encr_mgr.c
index d3ecdeee..3e85ceab 100644
--- a/usr/lib/common/encr_mgr.c
+++ b/usr/lib/common/encr_mgr.c
@@ -537,6 +537,10 @@ CK_RV encr_mgr_init(STDLL_TokData_t *tokdata,
}
memset(ctx->context, 0x0, sizeof(AES_GCM_CONTEXT));
+ /* Release obj lock, token specific aes-gcm may re-acquire the lock */
+ object_put(tokdata, key_obj, TRUE);
+ key_obj = NULL;
+
rc = aes_gcm_init(tokdata, sess, ctx, mech, key_handle, 1);
if (rc != CKR_OK) {
TRACE_ERROR("Could not initialize AES_GCM parms.\n");
diff --git a/usr/lib/common/mech_rsa.c b/usr/lib/common/mech_rsa.c
index 1652f90a..e35b383c 100644
--- a/usr/lib/common/mech_rsa.c
+++ b/usr/lib/common/mech_rsa.c
@@ -602,6 +602,10 @@ CK_RV rsa_oaep_crypt(STDLL_TokData_t *tokdata, SESSION *sess,
goto done;
}
+ /* Release obj lock, token specific rsa-oaep may re-acquire the lock */
+ object_put(tokdata, key_obj, TRUE);
+ key_obj = NULL;
+
rc = token_specific.t_rsa_oaep_encrypt(tokdata, ctx, in_data,
in_data_len, out_data,
out_data_len, hash, hlen);
@@ -625,6 +629,10 @@ CK_RV rsa_oaep_crypt(STDLL_TokData_t *tokdata, SESSION *sess,
goto done;
}
+ /* Release obj lock, token specific rsa-oaep may re-acquire the lock */
+ object_put(tokdata, key_obj, TRUE);
+ key_obj = NULL;
+
rc = token_specific.t_rsa_oaep_decrypt(tokdata, ctx, in_data,
in_data_len, out_data,
out_data_len, hash, hlen);
@@ -1331,6 +1339,10 @@ CK_RV rsa_pss_sign(STDLL_TokData_t *tokdata, SESSION *sess,
goto done;
}
+ /* Release obj lock, token specific rsa_pss may re-acquire the lock */
+ object_put(tokdata, key_obj, TRUE);
+ key_obj = NULL;
+
rc = token_specific.t_rsa_pss_sign(tokdata, sess, ctx, in_data, in_data_len,
out_data, out_data_len);
if (rc != CKR_OK)
@@ -1389,6 +1401,10 @@ CK_RV rsa_pss_verify(STDLL_TokData_t *tokdata, SESSION *sess,
goto done;
}
+ /* Release obj lock, token specific rsa_pss may re-acquire the lock */
+ object_put(tokdata, key_obj, TRUE);
+ key_obj = NULL;
+
rc = token_specific.t_rsa_pss_verify(tokdata, sess, ctx, in_data,
in_data_len, signature, sig_len);
if (rc != CKR_OK)
diff --git a/usr/lib/common/sign_mgr.c b/usr/lib/common/sign_mgr.c
index 937a371a..c7268e01 100644
--- a/usr/lib/common/sign_mgr.c
+++ b/usr/lib/common/sign_mgr.c
@@ -424,6 +424,10 @@ CK_RV sign_mgr_init(STDLL_TokData_t *tokdata,
ctx->context_len = 0;
ctx->context = NULL;
+ /* Release obj lock, token specific hmac-sign may re-acquire the lock */
+ object_put(tokdata, key_obj, TRUE);
+ key_obj = NULL;
+
rc = hmac_sign_init(tokdata, sess, mech, key);
if (rc != CKR_OK) {
TRACE_ERROR("Failed to initialize hmac.\n");
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 3ac3768a..52f95d7a 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -6948,6 +6948,13 @@ CK_RV ep11tok_sign_init(STDLL_TokData_t * tokdata, SESSION * session,
rc = ep11tok_pkey_check(tokdata, session, key_obj, mech);
switch (rc) {
case CKR_OK:
+ /*
+ * Release obj lock, sign_mgr_init or ep11tok_sign_verify_init_ibm_ed
+ * may re-acquire the lock
+ */
+ object_put(tokdata, key_obj, TRUE);
+ key_obj = NULL;
+
/* Note that Edwards curves in general are not yet supported in
* opencryptoki. These two special IBM specific ED mechs are only
* supported by the ep11token, so let's keep them local here. */
@@ -7029,11 +7036,16 @@ CK_RV ep11tok_sign(STDLL_TokData_t * tokdata, SESSION * session,
* opencryptoki. These two special IBM specific ED mechs are only
* supported by the ep11token, so let's keep them local here. */
if (ctx->mech.mechanism == CKM_IBM_ED25519_SHA512 ||
- ctx->mech.mechanism == CKM_IBM_ED448_SHA3)
+ ctx->mech.mechanism == CKM_IBM_ED448_SHA3) {
rc = pkey_ibm_ed_sign(key_obj, in_data, in_data_len, signature, sig_len);
- else
+ } else {
+ /* Release obj lock, sign_mgr_sign may re-acquire the lock */
+ object_put(tokdata, key_obj, TRUE);
+ key_obj = NULL;
+
rc = sign_mgr_sign(tokdata, session, length_only, ctx, in_data,
in_data_len, signature, sig_len);
+ }
goto done; /* no ep11 fallback possible */
}
@@ -7071,6 +7083,11 @@ CK_RV ep11tok_sign_update(STDLL_TokData_t * tokdata, SESSION * session,
if (!in_data || !in_data_len)
return CKR_OK;
+ if (ctx->pkey_active) {
+ rc = sign_mgr_sign_update(tokdata, session, ctx, in_data, in_data_len);
+ goto done; /* no ep11 fallback possible */
+ }
+
rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
READ_LOCK);
if (rc != CKR_OK) {
@@ -7078,11 +7095,6 @@ CK_RV ep11tok_sign_update(STDLL_TokData_t * tokdata, SESSION * session,
return rc;
}
- if (ctx->pkey_active) {
- rc = sign_mgr_sign_update(tokdata, session, ctx, in_data, in_data_len);
- goto done; /* no ep11 fallback possible */
- }
-
RETRY_START
rc = dll_m_SignUpdate(ctx->context, ctx->context_len, in_data,
in_data_len, ep11_data->target);
@@ -7115,6 +7127,11 @@ CK_RV ep11tok_sign_final(STDLL_TokData_t * tokdata, SESSION * session,
CK_BYTE *keyblob;
OBJECT *key_obj = NULL;
+ if (ctx->pkey_active) {
+ rc = sign_mgr_sign_final(tokdata, session, length_only, ctx, signature, sig_len);
+ goto done; /* no ep11 fallback possible */
+ }
+
rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
READ_LOCK);
if (rc != CKR_OK) {
@@ -7122,11 +7139,6 @@ CK_RV ep11tok_sign_final(STDLL_TokData_t * tokdata, SESSION * session,
return rc;
}
- if (ctx->pkey_active) {
- rc = sign_mgr_sign_final(tokdata, session, length_only, ctx, signature, sig_len);
- goto done; /* no ep11 fallback possible */
- }
-
RETRY_START
rc = dll_m_SignFinal(ctx->context, ctx->context_len, signature, sig_len,
ep11_data->target);
@@ -7241,6 +7253,13 @@ CK_RV ep11tok_verify_init(STDLL_TokData_t * tokdata, SESSION * session,
rc = ep11tok_pkey_check(tokdata, session, key_obj, mech);
switch (rc) {
case CKR_OK:
+ /*
+ * Release obj lock, verify_mgr_init or ep11tok_sign_verify_init_ibm_ed
+ * may re-acquire the lock
+ */
+ object_put(tokdata, key_obj, TRUE);
+ key_obj = NULL;
+
/* Note that Edwards curves in general are not yet supported in
* opencryptoki. These two special IBM specific ED mechs are only
* supported by the ep11token, so let's keep them local here. */
@@ -7320,12 +7339,17 @@ CK_RV ep11tok_verify(STDLL_TokData_t * tokdata, SESSION * session,
* opencryptoki. These two special IBM specific ED mechs are only
* supported by the ep11token, so let's keep them local here. */
if (ctx->mech.mechanism == CKM_IBM_ED25519_SHA512 ||
- ctx->mech.mechanism == CKM_IBM_ED448_SHA3)
+ ctx->mech.mechanism == CKM_IBM_ED448_SHA3) {
rc = pkey_ibm_ed_verify(key_obj, in_data, in_data_len,
signature, sig_len);
- else
+ } else {
+ /* Release obj lock, verify_mgr_verify may re-acquire the lock */
+ object_put(tokdata, key_obj, TRUE);
+ key_obj = NULL;
+
rc = verify_mgr_verify(tokdata, session, ctx, in_data,
in_data_len, signature, sig_len);
+ }
goto done; /* no ep11 fallback possible */
}
@@ -7363,6 +7387,11 @@ CK_RV ep11tok_verify_update(STDLL_TokData_t * tokdata, SESSION * session,
if (!in_data || !in_data_len)
return CKR_OK;
+ if (ctx->pkey_active) {
+ rc = verify_mgr_verify_update(tokdata, session, ctx, in_data, in_data_len);
+ goto done; /* no ep11 fallback possible */
+ }
+
rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
READ_LOCK);
if (rc != CKR_OK) {
@@ -7370,11 +7399,6 @@ CK_RV ep11tok_verify_update(STDLL_TokData_t * tokdata, SESSION * session,
return rc;
}
- if (ctx->pkey_active) {
- rc = verify_mgr_verify_update(tokdata, session, ctx, in_data, in_data_len);
- goto done; /* no ep11 fallback possible */
- }
-
RETRY_START
rc = dll_m_VerifyUpdate(ctx->context, ctx->context_len, in_data,
in_data_len, ep11_data->target);
@@ -7406,6 +7430,11 @@ CK_RV ep11tok_verify_final(STDLL_TokData_t * tokdata, SESSION * session,
CK_BYTE *keyblob;
OBJECT *key_obj = NULL;
+ if (ctx->pkey_active) {
+ rc = verify_mgr_verify_final(tokdata, session, ctx, signature, sig_len);
+ goto done; /* no ep11 fallback possible */
+ }
+
rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
READ_LOCK);
if (rc != CKR_OK) {
@@ -7413,11 +7442,6 @@ CK_RV ep11tok_verify_final(STDLL_TokData_t * tokdata, SESSION * session,
return rc;
}
- if (ctx->pkey_active) {
- rc = verify_mgr_verify_final(tokdata, session, ctx, signature, sig_len);
- goto done; /* no ep11 fallback possible */
- }
-
RETRY_START
rc = dll_m_VerifyFinal(ctx->context, ctx->context_len, signature,
sig_len, ep11_data->target);
@@ -7501,6 +7525,12 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session,
CK_BYTE *keyblob;
OBJECT *key_obj = NULL;
+ if (ctx->pkey_active) {
+ rc = decr_mgr_decrypt_final(tokdata, session, length_only,
+ ctx, output_part, p_output_part_len);
+ goto done; /* no ep11 fallback possible */
+ }
+
rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
READ_LOCK);
if (rc != CKR_OK) {
@@ -7508,12 +7538,6 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session,
return rc;
}
- if (ctx->pkey_active) {
- rc = decr_mgr_decrypt_final(tokdata, session, length_only,
- ctx, output_part, p_output_part_len);
- goto done; /* no ep11 fallback possible */
- }
-
RETRY_START
rc = dll_m_DecryptFinal(ctx->context, ctx->context_len,
output_part, p_output_part_len,
@@ -7548,13 +7572,6 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session,
CK_BYTE *keyblob;
OBJECT *key_obj = NULL;
- rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
- READ_LOCK);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
- return rc;
- }
-
if (ctx->pkey_active) {
rc = decr_mgr_decrypt(tokdata, session, length_only, ctx,
input_data, input_data_len, output_data,
@@ -7562,6 +7579,13 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session,
goto done; /* no ep11 fallback possible */
}
+ rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
+ READ_LOCK);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
+ return rc;
+ }
+
RETRY_START
rc = dll_m_Decrypt(ctx->context, ctx->context_len, input_data,
input_data_len, output_data, p_output_data_len,
@@ -7602,13 +7626,6 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session,
return CKR_OK; /* nothing to update, keep context */
}
- rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
- READ_LOCK);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
- return rc;
- }
-
if (ctx->pkey_active) {
rc = decr_mgr_decrypt_update(tokdata, session, length_only,
ctx, input_part, input_part_len,
@@ -7616,6 +7633,13 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session,
goto done; /* no ep11 fallback possible */
}
+ rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
+ READ_LOCK);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
+ return rc;
+ }
+
RETRY_START
rc = dll_m_DecryptUpdate(ctx->context, ctx->context_len,
input_part, input_part_len, output_part,
@@ -7695,6 +7719,12 @@ CK_RV ep11tok_encrypt_final(STDLL_TokData_t * tokdata, SESSION * session,
CK_BYTE *keyblob;
OBJECT *key_obj = NULL;
+ if (ctx->pkey_active) {
+ rc = encr_mgr_encrypt_final(tokdata, session, length_only,
+ ctx, output_part, p_output_part_len);
+ goto done; /* no ep11 fallback possible */
+ }
+
rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
READ_LOCK);
if (rc != CKR_OK) {
@@ -7702,12 +7732,6 @@ CK_RV ep11tok_encrypt_final(STDLL_TokData_t * tokdata, SESSION * session,
return rc;
}
- if (ctx->pkey_active) {
- rc = encr_mgr_encrypt_final(tokdata, session, length_only,
- ctx, output_part, p_output_part_len);
- goto done; /* no ep11 fallback possible */
- }
-
RETRY_START
rc = dll_m_EncryptFinal(ctx->context, ctx->context_len,
output_part, p_output_part_len,
@@ -7742,13 +7766,6 @@ CK_RV ep11tok_encrypt(STDLL_TokData_t * tokdata, SESSION * session,
CK_BYTE *keyblob;
OBJECT *key_obj = NULL;
- rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
- READ_LOCK);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
- return rc;
- }
-
if (ctx->pkey_active) {
rc = encr_mgr_encrypt(tokdata, session, length_only, ctx,
input_data, input_data_len, output_data,
@@ -7756,6 +7773,13 @@ CK_RV ep11tok_encrypt(STDLL_TokData_t * tokdata, SESSION * session,
goto done; /* no ep11 fallback possible */
}
+ rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
+ READ_LOCK);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
+ return rc;
+ }
+
RETRY_START
rc = dll_m_Encrypt(ctx->context, ctx->context_len, input_data,
input_data_len, output_data, p_output_data_len,
@@ -7796,13 +7820,6 @@ CK_RV ep11tok_encrypt_update(STDLL_TokData_t * tokdata, SESSION * session,
return CKR_OK; /* nothing to update, keep context */
}
- rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
- READ_LOCK);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
- return rc;
- }
-
if (ctx->pkey_active) {
rc = encr_mgr_encrypt_update(tokdata, session, length_only, ctx,
input_part, input_part_len, output_part,
@@ -7810,6 +7827,13 @@ CK_RV ep11tok_encrypt_update(STDLL_TokData_t * tokdata, SESSION * session,
goto done; /* no ep11 fallback possible */
}
+ rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
+ READ_LOCK);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
+ return rc;
+ }
+
RETRY_START
rc = dll_m_EncryptUpdate(ctx->context, ctx->context_len,
input_part, input_part_len, output_part,
@@ -7921,6 +7945,10 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session,
rc = ep11tok_pkey_check(tokdata, session, key_obj, mech);
switch (rc) {
case CKR_OK:
+ /* Release obj lock, encr/decr_mgr_init may re-acquire the lock */
+ object_put(tokdata, key_obj, TRUE);
+ key_obj = NULL;
+
if (op == DECRYPT) {
rc = decr_mgr_init(tokdata, session, &session->decr_ctx,
OP_DECRYPT_INIT, mech, key);

View File

@ -0,0 +1,239 @@
commit d7de5092247a0efc2c397f12977a7c9925420143
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue Feb 16 17:15:20 2021 +0100
TESTCASES: Add event support tests
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/testcases/misc_tests/events.c b/testcases/misc_tests/events.c
new file mode 100644
index 00000000..fecc7bfe
--- /dev/null
+++ b/testcases/misc_tests/events.c
@@ -0,0 +1,190 @@
+/*
+ * COPYRIGHT (c) International Business Machines Corp. 2021
+ *
+ * This program is provided under the terms of the Common Public License,
+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be
+ * found in the file LICENSE file or at
+ * https://opensource.org/licenses/cpl1.0.php
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "event_client.h"
+#include "regress.h"
+#include "defs.h"
+
+const char payload[20] = "12345678901234567890";
+
+static inline void init_event_destination(struct event_destination *dest,
+ unsigned int token_type,
+ const char *label,
+ pid_t process_id)
+{
+ size_t len;
+
+ dest->token_type = token_type;
+ dest->process_id = process_id;
+
+ memset(dest->token_label, ' ', sizeof(dest->token_label));
+ if (label != NULL) {
+ len = strlen(label);
+ memcpy(dest->token_label, label, len > sizeof(dest->token_label) ?
+ sizeof(dest->token_label) : len);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ CK_C_INITIALIZE_ARGS cinit_args;
+ int rc, fd = -1, ret = 1;
+ struct event_destination dest;
+ struct event_reply reply;
+
+ UNUSED(argc);
+ UNUSED(argv);
+
+ rc = do_GetFunctionList();
+ if (!rc) {
+ testcase_error("do_getFunctionList(), rc=%s", p11_get_ckr(rc));
+ return rc;
+ }
+
+ /*
+ * Initialize Opencryptoki in this process, so that at least one
+ * process is receiving the events.
+ */
+ memset(&cinit_args, 0x0, sizeof(cinit_args));
+ cinit_args.flags = CKF_OS_LOCKING_OK;
+ funcs->C_Initialize(&cinit_args);
+
+ testcase_setup(0);
+ testcase_begin("Starting event tests");
+
+ // Test fork before C_Initialize
+ testcase_new_assertion();
+
+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, 0, NULL, NULL, NULL);
+ if (rc != 0) {
+ testcase_fail("send_event (simple, one-shot) rc = %d (%s)", rc,
+ strerror(-rc));
+ goto out;
+ }
+ testcase_pass("send_event (simple, one-shot)");
+
+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, sizeof(payload), payload,
+ NULL, NULL);
+ if (rc != 0) {
+ testcase_fail("send_event (payload, one-shot) rc = %d (%s)", rc,
+ strerror(-rc));
+ goto out;
+ }
+ testcase_pass("send_event (payload, one-shot)");
+
+ init_event_destination(&dest, EVENT_TOK_TYPE_CCA, NULL, 0);
+
+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, 0, NULL, &dest, NULL);
+ if (rc != 0) {
+ testcase_fail("send_event (token-type, one-shot) rc = %d (%s)", rc,
+ strerror(-rc));
+ goto out;
+ }
+ testcase_pass("send_event (token-type, one-shot)");
+
+ init_event_destination(&dest, EVENT_TOK_TYPE_ALL, "cca", 0);
+
+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, 0, NULL, &dest, NULL);
+ if (rc != 0) {
+ testcase_fail("send_event (token-label, one-shot) rc = %d (%s)", rc,
+ strerror(-rc));
+ goto out;
+ }
+ testcase_pass("send_event (token-label, one-shot)");
+
+ init_event_destination(&dest, EVENT_TOK_TYPE_ALL, NULL, 12345);
+
+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, 0, NULL, &dest, NULL);
+ if (rc != 0) {
+ testcase_fail("send_event (pid, one-shot) rc = %d (%s)", rc,
+ strerror(-rc));
+ goto out;
+ }
+ testcase_pass("send_event (pid, one-shot)");
+
+ memset(&reply, 0, sizeof(reply));
+
+ rc = send_event(-1, 0x12345, EVENT_FLAGS_REPLY_REQ, 0, NULL, NULL, &reply);
+ if (rc != 0) {
+ testcase_fail("send_event (reply, one-shot) rc = %d (%s)", rc,
+ strerror(-rc));
+ goto out;
+ }
+ printf("Reply: positive_replies: %lu\n", reply.positive_replies);
+ printf(" negative_replies: %lu\n", reply.negative_replies);
+ printf(" nothandled_replies: %lu\n", reply.nothandled_replies);
+ if (reply.positive_replies + reply.negative_replies +
+ reply.nothandled_replies == 0) {
+ testcase_fail("send_event (reply, one-shot) replies all zero");
+ goto out;
+ }
+ testcase_pass("send_event (reply, one-shot)");
+
+
+ fd = init_event_client();
+ if (fd < 0) {
+ testcase_fail("init_event_client rc = %d (%s)", fd, strerror(-fd));
+ goto out;
+ }
+ testcase_pass("init_event_client()");
+
+ rc = send_event(fd, 0x12345, EVENT_FLAGS_NONE, 0, NULL, NULL, NULL);
+ if (rc != 0) {
+ testcase_fail("send_event (simple) rc = %d (%s)", rc, strerror(-rc));
+ goto out;
+ }
+ testcase_pass("send_event (simple)");
+
+ rc = send_event(fd, 0x12345, EVENT_FLAGS_NONE, sizeof(payload), payload,
+ NULL, NULL);
+ if (rc != 0) {
+ testcase_fail("send_event (payload) rc = %d (%s)", rc,
+ strerror(-rc));
+ goto out;
+ }
+ testcase_pass("send_event (payload)");
+
+ memset(&reply, 0, sizeof(reply));
+
+ rc = send_event(-1, 0x12345, EVENT_FLAGS_REPLY_REQ, 0, NULL, NULL, &reply);
+ if (rc != 0) {
+ testcase_fail("send_event (reply) rc = %d (%s)", rc,
+ strerror(-rc));
+ goto out;
+ }
+ printf("Reply: positive_replies: %lu\n", reply.positive_replies);
+ printf(" negative_replies: %lu\n", reply.negative_replies);
+ printf(" nothandled_replies: %lu\n", reply.nothandled_replies);
+ if (reply.positive_replies + reply.negative_replies +
+ reply.nothandled_replies == 0) {
+ testcase_fail("send_event (reply) replies all zero");
+ goto out;
+ }
+ testcase_pass("send_event (reply)");
+
+ term_event_client(fd);
+ fd = -1;
+
+ ret = 0;
+
+out:
+ if (fd >= 0)
+ term_event_client(fd);
+
+ funcs->C_Finalize(NULL);
+
+ testcase_print_result();
+ return ret;
+}
diff --git a/testcases/misc_tests/misc_tests.mk b/testcases/misc_tests/misc_tests.mk
index 3de11ebe..fb7cc0a1 100644
--- a/testcases/misc_tests/misc_tests.mk
+++ b/testcases/misc_tests/misc_tests.mk
@@ -7,7 +7,8 @@ noinst_PROGRAMS += \
testcases/misc_tests/fork testcases/misc_tests/multi_instance \
testcases/misc_tests/obj_lock testcases/misc_tests/tok2tok_transport \
testcases/misc_tests/obj_lock testcases/misc_tests/reencrypt \
- testcases/misc_tests/cca_export_import_test
+ testcases/misc_tests/cca_export_import_test \
+ testcases/misc_tests/events
testcases_misc_tests_obj_mgmt_tests_CFLAGS = ${testcases_inc}
testcases_misc_tests_obj_mgmt_tests_LDADD = \
@@ -73,3 +74,8 @@ testcases_misc_tests_cca_export_import_test_LDADD = \
testcases/common/libcommon.la
testcases_misc_tests_cca_export_import_test_SOURCES = \
testcases/misc_tests/cca_export_import_test.c
+
+testcases_misc_tests_events_CFLAGS = ${testcases_inc}
+testcases_misc_tests_events_LDADD = testcases/common/libcommon.la
+testcases_misc_tests_events_SOURCES = testcases/misc_tests/events.c \
+ usr/lib/common/event_client.c
diff --git a/testcases/ock_tests.sh.in b/testcases/ock_tests.sh.in
index 64c77a7d..6558b031 100755
--- a/testcases/ock_tests.sh.in
+++ b/testcases/ock_tests.sh.in
@@ -53,6 +53,7 @@ OCK_TESTS+=" pkcs11/findobjects pkcs11/generate_keypair"
OCK_TESTS+=" pkcs11/get_interface pkcs11/getobjectsize pkcs11/sess_opstate"
OCK_TESTS+=" misc_tests/fork misc_tests/obj_mgmt_tests"
OCK_TESTS+=" misc_tests/obj_mgmt_lock_tests misc_tests/reencrypt"
+OCK_TESTS+=" misc_tests/events"
OCK_TEST=""
OCK_BENCHS="pkcs11/*bench"

View File

@ -0,0 +1,619 @@
commit d929fe8470e99f4dcbbd889e7aa87e147d0d5b48
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri Feb 12 11:25:21 2021 +0100
Externalize linked list functions
Externalize the linked list functions (dlist_xxx), so that they
can also be used on pkcsslotd.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/cca_stdll/cca_stdll.mk b/usr/lib/cca_stdll/cca_stdll.mk
index bd230b9f..c5e86fa7 100644
--- a/usr/lib/cca_stdll/cca_stdll.mk
+++ b/usr/lib/cca_stdll/cca_stdll.mk
@@ -35,7 +35,8 @@ opencryptoki_stdll_libpkcs11_cca_la_SOURCES = \
usr/lib/common/mech_ssl3.c usr/lib/common/verify_mgr.c \
usr/lib/common/p11util.c usr/lib/common/sw_crypt.c \
usr/lib/common/shared_memory.c usr/lib/common/profile_obj.c \
- usr/lib/cca_stdll/cca_specific.c usr/lib/common/attributes.c
+ usr/lib/cca_stdll/cca_specific.c usr/lib/common/attributes.c \
+ usr/lib/common/dlist.c
if ENABLE_LOCKS
opencryptoki_stdll_libpkcs11_cca_la_SOURCES += \
diff --git a/usr/lib/common/dlist.c b/usr/lib/common/dlist.c
new file mode 100644
index 00000000..1fee1ea9
--- /dev/null
+++ b/usr/lib/common/dlist.c
@@ -0,0 +1,218 @@
+/*
+ * COPYRIGHT (c) International Business Machines Corp. 2021
+ *
+ * This program is provided under the terms of the Common Public License,
+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be
+ * found in the file LICENSE file or at
+ * https://opensource.org/licenses/cpl1.0.php
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#include "dlist.h"
+#include "host_defs.h"
+#include "h_extern.h"
+
+
+// Function: dlist_add_as_first()
+//
+// Adds the specified node to the start of the list
+//
+// Returns: pointer to the start of the list
+//
+DL_NODE *dlist_add_as_first(DL_NODE *list, void *data)
+{
+ DL_NODE *node = NULL;
+
+ if (!data)
+ return list;
+
+ node = (DL_NODE *) malloc(sizeof(DL_NODE));
+ if (!node)
+ return NULL;
+
+ node->data = data;
+ node->prev = NULL;
+ node->next = list;
+ if (list)
+ list->prev = node;
+
+ return node;
+}
+
+// Function: dlist_add_as_last()
+//
+// Adds the specified node to the end of the list
+//
+// Returns: pointer to the start of the list
+//
+DL_NODE *dlist_add_as_last(DL_NODE *list, void *data)
+{
+ DL_NODE *node = NULL;
+
+ if (!data)
+ return list;
+
+ node = (DL_NODE *) malloc(sizeof(DL_NODE));
+ if (!node)
+ return NULL;
+
+ node->data = data;
+ node->next = NULL;
+
+ if (!list) {
+ node->prev = NULL;
+ return node;
+ } else {
+ DL_NODE *temp = dlist_get_last(list);
+ temp->next = node;
+ node->prev = temp;
+
+ return list;
+ }
+}
+
+// Function: dlist_find()
+//
+DL_NODE *dlist_find(DL_NODE *list, void *data)
+{
+ DL_NODE *node = list;
+
+ while (node && node->data != data)
+ node = node->next;
+
+ return node;
+}
+
+// Function: dlist_get_first()
+//
+// Returns the last node in the list or NULL if list is empty
+//
+DL_NODE *dlist_get_first(DL_NODE *list)
+{
+ DL_NODE *temp = list;
+
+ if (!list)
+ return NULL;
+
+ while (temp->prev != NULL)
+ temp = temp->prev;
+
+ return temp;
+}
+
+// Function: dlist_get_last()
+//
+// Returns the last node in the list or NULL if list is empty
+//
+DL_NODE *dlist_get_last(DL_NODE *list)
+{
+ DL_NODE *temp = list;
+
+ if (!list)
+ return NULL;
+
+ while (temp->next != NULL)
+ temp = temp->next;
+
+ return temp;
+}
+
+//
+//
+CK_ULONG dlist_length(DL_NODE *list)
+{
+ DL_NODE *temp = list;
+ CK_ULONG len = 0;
+
+ while (temp) {
+ len++;
+ temp = temp->next;
+ }
+
+ return len;
+}
+
+//
+//
+DL_NODE *dlist_next(DL_NODE *node)
+{
+ if (!node)
+ return NULL;
+
+ return node->next;
+}
+
+//
+//
+DL_NODE *dlist_prev(DL_NODE *node)
+{
+ if (!node)
+ return NULL;
+
+ return node->prev;
+}
+
+//
+//
+void dlist_purge(DL_NODE *list)
+{
+ DL_NODE *node;
+
+ if (!list)
+ return;
+
+ do {
+ node = list->next;
+ free(list);
+ list = node;
+ } while (list);
+}
+
+// Function: dlist_remove_node()
+//
+// Attempts to remove the specified node from the list. The caller is
+// responsible for freeing the data associated with the node prior to
+// calling this routine
+//
+DL_NODE *dlist_remove_node(DL_NODE *list, DL_NODE *node)
+{
+ DL_NODE *temp = list;
+
+ if (!list || !node)
+ return NULL;
+
+ // special case: removing head of the list
+ //
+ if (list == node) {
+ temp = list->next;
+ if (temp)
+ temp->prev = NULL;
+
+ free(list);
+ return temp;
+ }
+ // we have no guarantee that the node is in the list
+ // so search through the list to find it
+ //
+ while ((temp != NULL) && (temp->next != node))
+ temp = temp->next;
+
+ if (temp != NULL) {
+ DL_NODE *next = node->next;
+
+ temp->next = next;
+ if (next)
+ next->prev = temp;
+
+ free(node);
+ }
+
+ return list;
+}
diff --git a/usr/lib/common/dlist.h b/usr/lib/common/dlist.h
new file mode 100644
index 00000000..eda4af9c
--- /dev/null
+++ b/usr/lib/common/dlist.h
@@ -0,0 +1,32 @@
+/*
+ * COPYRIGHT (c) International Business Machines Corp. 2021
+ *
+ * This program is provided under the terms of the Common Public License,
+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be
+ * found in the file LICENSE file or at
+ * https://opensource.org/licenses/cpl1.0.php
+ */
+
+
+
+#ifndef _DLIST_H_
+#define _DLIST_H_
+
+#include "pkcs11types.h"
+#include "defs.h"
+
+// linked-list routines
+//
+DL_NODE *dlist_add_as_first(DL_NODE *list, void *data);
+DL_NODE *dlist_add_as_last(DL_NODE *list, void *data);
+DL_NODE *dlist_find(DL_NODE *list, void *data);
+DL_NODE *dlist_get_first(DL_NODE *list);
+DL_NODE *dlist_get_last(DL_NODE *list);
+CK_ULONG dlist_length(DL_NODE *list);
+DL_NODE *dlist_next(DL_NODE *list);
+DL_NODE *dlist_prev(DL_NODE *list);
+void dlist_purge(DL_NODE *list);
+DL_NODE *dlist_remove_node(DL_NODE *list, DL_NODE *node);
+
+#endif
diff --git a/usr/lib/common/h_extern.h b/usr/lib/common/h_extern.h
index 63aff79f..5e251d95 100644
--- a/usr/lib/common/h_extern.h
+++ b/usr/lib/common/h_extern.h
@@ -24,6 +24,7 @@
#define _H_EXTERN_H
#include <stdio.h>
+#include "dlist.h"
// global variables
//
@@ -1759,19 +1760,6 @@ int ec_point_from_public_data(const CK_BYTE *data, CK_ULONG data_len,
CK_BBOOL *allocated, CK_BYTE **ec_point,
CK_ULONG *ec_point_len);
-// linked-list routines
-//
-DL_NODE *dlist_add_as_first(DL_NODE *list, void *data);
-DL_NODE *dlist_add_as_last(DL_NODE *list, void *data);
-DL_NODE *dlist_find(DL_NODE *list, void *data);
-DL_NODE *dlist_get_first(DL_NODE *list);
-DL_NODE *dlist_get_last(DL_NODE *list);
-CK_ULONG dlist_length(DL_NODE *list);
-DL_NODE *dlist_next(DL_NODE *list);
-DL_NODE *dlist_prev(DL_NODE *list);
-void dlist_purge(DL_NODE *list);
-DL_NODE *dlist_remove_node(DL_NODE *list, DL_NODE *node);
-
CK_RV attach_shm(STDLL_TokData_t *tokdata, CK_SLOT_ID slot_id);
CK_RV detach_shm(STDLL_TokData_t *tokdata, CK_BBOOL ignore_ref_count);
diff --git a/usr/lib/common/utility.c b/usr/lib/common/utility.c
index 38d8d959..b2c6ee50 100644
--- a/usr/lib/common/utility.c
+++ b/usr/lib/common/utility.c
@@ -40,203 +40,6 @@
#include <sys/file.h>
#include <syslog.h>
-// Function: dlist_add_as_first()
-//
-// Adds the specified node to the start of the list
-//
-// Returns: pointer to the start of the list
-//
-DL_NODE *dlist_add_as_first(DL_NODE *list, void *data)
-{
- DL_NODE *node = NULL;
-
- if (!data)
- return list;
-
- node = (DL_NODE *) malloc(sizeof(DL_NODE));
- if (!node)
- return NULL;
-
- node->data = data;
- node->prev = NULL;
- node->next = list;
- if (list)
- list->prev = node;
-
- return node;
-}
-
-// Function: dlist_add_as_last()
-//
-// Adds the specified node to the end of the list
-//
-// Returns: pointer to the start of the list
-//
-DL_NODE *dlist_add_as_last(DL_NODE *list, void *data)
-{
- DL_NODE *node = NULL;
-
- if (!data)
- return list;
-
- node = (DL_NODE *) malloc(sizeof(DL_NODE));
- if (!node)
- return NULL;
-
- node->data = data;
- node->next = NULL;
-
- if (!list) {
- node->prev = NULL;
- return node;
- } else {
- DL_NODE *temp = dlist_get_last(list);
- temp->next = node;
- node->prev = temp;
-
- return list;
- }
-}
-
-// Function: dlist_find()
-//
-DL_NODE *dlist_find(DL_NODE *list, void *data)
-{
- DL_NODE *node = list;
-
- while (node && node->data != data)
- node = node->next;
-
- return node;
-}
-
-// Function: dlist_get_first()
-//
-// Returns the last node in the list or NULL if list is empty
-//
-DL_NODE *dlist_get_first(DL_NODE *list)
-{
- DL_NODE *temp = list;
-
- if (!list)
- return NULL;
-
- while (temp->prev != NULL)
- temp = temp->prev;
-
- return temp;
-}
-
-// Function: dlist_get_last()
-//
-// Returns the last node in the list or NULL if list is empty
-//
-DL_NODE *dlist_get_last(DL_NODE *list)
-{
- DL_NODE *temp = list;
-
- if (!list)
- return NULL;
-
- while (temp->next != NULL)
- temp = temp->next;
-
- return temp;
-}
-
-//
-//
-CK_ULONG dlist_length(DL_NODE *list)
-{
- DL_NODE *temp = list;
- CK_ULONG len = 0;
-
- while (temp) {
- len++;
- temp = temp->next;
- }
-
- return len;
-}
-
-//
-//
-DL_NODE *dlist_next(DL_NODE *node)
-{
- if (!node)
- return NULL;
-
- return node->next;
-}
-
-//
-//
-DL_NODE *dlist_prev(DL_NODE *node)
-{
- if (!node)
- return NULL;
-
- return node->prev;
-}
-
-//
-//
-void dlist_purge(DL_NODE *list)
-{
- DL_NODE *node;
-
- if (!list)
- return;
-
- do {
- node = list->next;
- free(list);
- list = node;
- } while (list);
-}
-
-// Function: dlist_remove_node()
-//
-// Attempts to remove the specified node from the list. The caller is
-// responsible for freeing the data associated with the node prior to
-// calling this routine
-//
-DL_NODE *dlist_remove_node(DL_NODE *list, DL_NODE *node)
-{
- DL_NODE *temp = list;
-
- if (!list || !node)
- return NULL;
-
- // special case: removing head of the list
- //
- if (list == node) {
- temp = list->next;
- if (temp)
- temp->prev = NULL;
-
- free(list);
- return temp;
- }
- // we have no guarantee that the node is in the list
- // so search through the list to find it
- //
- while ((temp != NULL) && (temp->next != node))
- temp = temp->next;
-
- if (temp != NULL) {
- DL_NODE *next = node->next;
-
- temp->next = next;
- if (next)
- next->prev = temp;
-
- free(node);
- }
-
- return list;
-}
-
CK_RV CreateXProcLock(char *tokname, STDLL_TokData_t *tokdata)
{
char lockfile[PATH_MAX];
diff --git a/usr/lib/ep11_stdll/ep11_stdll.mk b/usr/lib/ep11_stdll/ep11_stdll.mk
index bc617124..b5574d9e 100644
--- a/usr/lib/ep11_stdll/ep11_stdll.mk
+++ b/usr/lib/ep11_stdll/ep11_stdll.mk
@@ -36,7 +36,7 @@ opencryptoki_stdll_libpkcs11_ep11_la_SOURCES = \
usr/lib/common/utility.c usr/lib/common/trace.c \
usr/lib/common/mech_list.c usr/lib/common/shared_memory.c \
usr/lib/common/attributes.c usr/lib/common/sw_crypt.c \
- usr/lib/common/profile_obj.c \
+ usr/lib/common/profile_obj.c usr/lib/common/dlist.c \
usr/lib/common/pkey_utils.c \
usr/lib/ep11_stdll/new_host.c usr/lib/ep11_stdll/ep11_specific.c
diff --git a/usr/lib/ica_s390_stdll/ica_s390_stdll.mk b/usr/lib/ica_s390_stdll/ica_s390_stdll.mk
index d8448486..8f467e11 100644
--- a/usr/lib/ica_s390_stdll/ica_s390_stdll.mk
+++ b/usr/lib/ica_s390_stdll/ica_s390_stdll.mk
@@ -34,7 +34,7 @@ opencryptoki_stdll_libpkcs11_ica_la_SOURCES = \
usr/lib/common/verify_mgr.c usr/lib/common/trace.c \
usr/lib/common/mech_list.c usr/lib/common/shared_memory.c \
usr/lib/common/profile_obj.c usr/lib/common/attributes.c \
- usr/lib/ica_s390_stdll/ica_specific.c
+ usr/lib/ica_s390_stdll/ica_specific.c usr/lib/common/dlist.c
if ENABLE_LOCKS
opencryptoki_stdll_libpkcs11_ica_la_SOURCES += \
diff --git a/usr/lib/icsf_stdll/icsf_stdll.mk b/usr/lib/icsf_stdll/icsf_stdll.mk
index 788478c2..21c64f9a 100644
--- a/usr/lib/icsf_stdll/icsf_stdll.mk
+++ b/usr/lib/icsf_stdll/icsf_stdll.mk
@@ -43,7 +43,7 @@ opencryptoki_stdll_libpkcs11_icsf_la_SOURCES = \
usr/lib/common/mech_ssl3.c usr/lib/common/verify_mgr.c \
usr/lib/common/mech_list.c usr/lib/common/shared_memory.c \
usr/lib/common/attributes.c usr/lib/icsf_stdll/new_host.c \
- usr/lib/common/profile_obj.c \
+ usr/lib/common/profile_obj.c usr/lib/common/dlist.c \
usr/lib/icsf_stdll/pbkdf.c usr/lib/icsf_stdll/icsf_specific.c \
usr/lib/icsf_stdll/icsf_config_parse.y \
usr/lib/icsf_stdll/icsf_config_lexer.l \
diff --git a/usr/lib/soft_stdll/soft_stdll.mk b/usr/lib/soft_stdll/soft_stdll.mk
index cea802b5..ac401539 100644
--- a/usr/lib/soft_stdll/soft_stdll.mk
+++ b/usr/lib/soft_stdll/soft_stdll.mk
@@ -32,7 +32,8 @@ opencryptoki_stdll_libpkcs11_sw_la_SOURCES = \
usr/lib/common/utility.c usr/lib/common/verify_mgr.c \
usr/lib/common/trace.c usr/lib/common/mech_list.c \
usr/lib/common/shared_memory.c usr/lib/common/profile_obj.c \
- usr/lib/soft_stdll/soft_specific.c usr/lib/common/attributes.c
+ usr/lib/soft_stdll/soft_specific.c usr/lib/common/attributes.c \
+ usr/lib/common/dlist.c
if ENABLE_LOCKS
opencryptoki_stdll_libpkcs11_sw_la_SOURCES += \
diff --git a/usr/lib/tpm_stdll/tpm_stdll.mk b/usr/lib/tpm_stdll/tpm_stdll.mk
index f199a103..0e0eb024 100644
--- a/usr/lib/tpm_stdll/tpm_stdll.mk
+++ b/usr/lib/tpm_stdll/tpm_stdll.mk
@@ -34,7 +34,8 @@ opencryptoki_stdll_libpkcs11_tpm_la_SOURCES = \
usr/lib/common/verify_mgr.c usr/lib/common/mech_list.c \
usr/lib/common/shared_memory.c usr/lib/common/profile_obj.c \
usr/lib/tpm_stdll/tpm_specific.c usr/lib/common/attributes.c \
- usr/lib/tpm_stdll/tpm_openssl.c usr/lib/tpm_stdll/tpm_util.c
+ usr/lib/tpm_stdll/tpm_openssl.c usr/lib/tpm_stdll/tpm_util.c \
+ usr/lib/common/dlist.c
if ENABLE_LOCKS
opencryptoki_stdll_libpkcs11_tpm_la_SOURCES += \
diff --git a/usr/sbin/pkcscca/pkcscca.mk b/usr/sbin/pkcscca/pkcscca.mk
index a223265f..cc40f819 100644
--- a/usr/sbin/pkcscca/pkcscca.mk
+++ b/usr/sbin/pkcscca/pkcscca.mk
@@ -36,7 +36,7 @@ usr_sbin_pkcscca_pkcscca_SOURCES = \
usr/lib/common/p11util.c usr/lib/common/sw_crypt.c \
usr/lib/common/shared_memory.c usr/lib/common/profile_obj.c \
usr/lib/common/attributes.c usr/lib/common/mech_rng.c \
- usr/lib/common/pkcs_utils.c \
+ usr/lib/common/pkcs_utils.c usr/lib/common/dlist.c \
usr/sbin/pkcscca/pkcscca.c
diff --git a/usr/sbin/pkcsslotd/pkcsslotd.mk b/usr/sbin/pkcsslotd/pkcsslotd.mk
index 4f0e3c56..2d36b4a9 100644
--- a/usr/sbin/pkcsslotd/pkcsslotd.mk
+++ b/usr/sbin/pkcsslotd/pkcsslotd.mk
@@ -21,5 +21,6 @@ usr_sbin_pkcsslotd_pkcsslotd_SOURCES = \
usr/sbin/pkcsslotd/socket_server.c
nodist_usr_sbin_pkcsslotd_pkcsslotd_SOURCES = \
- usr/lib/common/parser.h usr/lib/common/parser.c usr/lib/common/lexer.c
+ usr/lib/common/parser.h usr/lib/common/parser.c usr/lib/common/lexer.c \
+ usr/lib/common/dlist.c
usr/sbin/pkcsslotd/slotmgr.$(OBJEXT): usr/lib/common/parser.h

View File

@ -0,0 +1,310 @@
commit e9548127edae313da7840bcb87fd0afd04549c2e
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon Feb 8 15:26:23 2021 +0100
pkcsslotd: Refactoring in preparation for event support
No functional change so far, just making things a bit bore clearer.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/include/slotmgr.h b/usr/include/slotmgr.h
index 3950a9a3..4d038435 100644
--- a/usr/include/slotmgr.h
+++ b/usr/include/slotmgr.h
@@ -30,7 +30,7 @@
#define TOK_PATH SBIN_PATH "/pkcsslotd"
#define OCK_API_LOCK_FILE LOCKDIR_PATH "/LCK..APIlock"
-#define SOCKET_FILE_PATH "/var/run/pkcsslotd.socket"
+#define PROC_SOCKET_FILE_PATH "/var/run/pkcsslotd.socket"
#define PID_FILE_PATH "/var/run/pkcsslotd.pid"
#define OCK_CONFIG OCK_CONFDIR "/opencryptoki.conf"
diff --git a/usr/lib/api/api_interface.c b/usr/lib/api/api_interface.c
index b74b763f..2873a20a 100644
--- a/usr/lib/api/api_interface.c
+++ b/usr/lib/api/api_interface.c
@@ -2831,7 +2831,7 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid)
TRACE_DEBUG("Shared memory %p \n", Anchor->SharedMemP);
/* Connect to slot daemon and retrieve slot infos */
- Anchor->socketfd = connect_socket(SOCKET_FILE_PATH);
+ Anchor->socketfd = connect_socket(PROC_SOCKET_FILE_PATH);
if (Anchor->socketfd < 0) {
OCK_SYSLOG(LOG_ERR, "C_Initialize: Module failed to create a "
"socket. Verify that the slot management daemon is "
diff --git a/usr/sbin/pkcsslotd/pkcsslotd.h b/usr/sbin/pkcsslotd/pkcsslotd.h
index 813db9f4..69eb59f3 100644
--- a/usr/sbin/pkcsslotd/pkcsslotd.h
+++ b/usr/sbin/pkcsslotd/pkcsslotd.h
@@ -61,7 +61,6 @@ extern key_t tok;
extern Slot_Info_t_64 sinfo[NUMBER_SLOTS_MANAGED];
extern unsigned int NumberSlotsInDB;
-extern int socketfd;
extern Slot_Mgr_Socket_t socketData;
@@ -89,9 +88,9 @@ int XProcLock(void);
int XProcUnLock(void);
int CreateXProcLock(void);
-int CreateListenerSocket(void);
-int InitSocketData(Slot_Mgr_Socket_t *sp);
-int SocketConnectionHandler(int socketfd, int timeout_secs);
-void DetachSocketListener(int socketfd);
+int init_socket_server();
+int term_socket_server();
+int init_socket_data(Slot_Mgr_Socket_t *sp);
+int socket_connection_handler(int timeout_secs);
#endif /* _SLOTMGR_H */
diff --git a/usr/sbin/pkcsslotd/signal.c b/usr/sbin/pkcsslotd/signal.c
index cf7b9087..49482a2f 100644
--- a/usr/sbin/pkcsslotd/signal.c
+++ b/usr/sbin/pkcsslotd/signal.c
@@ -101,7 +101,7 @@ void slotdGenericSignalHandler(int Signal)
InfoLog("Exiting on %s (%d; %#x)", SignalConst(Signal), Signal, Signal);
- DetachSocketListener(socketfd);
+ term_socket_server();
DestroyMutexes();
DetachFromSharedMemory();
DestroySharedMemory();
diff --git a/usr/sbin/pkcsslotd/slotmgr.c b/usr/sbin/pkcsslotd/slotmgr.c
index ea5c86f5..94288f13 100644
--- a/usr/sbin/pkcsslotd/slotmgr.c
+++ b/usr/sbin/pkcsslotd/slotmgr.c
@@ -37,7 +37,6 @@ unsigned int NumberSlotsInDB = 0;
Slot_Info_t_64 *psinfo;
-int socketfd;
Slot_Mgr_Socket_t socketData;
struct dircheckinfo_s {
@@ -569,15 +568,15 @@ int main(int argc, char *argv[], char *envp[])
if (!XProcUnLock())
return 4;
- if ((socketfd = CreateListenerSocket()) < 0) {
+ if (!init_socket_server()) {
DestroyMutexes();
DetachFromSharedMemory();
DestroySharedMemory();
return 5;
}
- if (!InitSocketData(&socketData)) {
- DetachSocketListener(socketfd);
+ if (!init_socket_data(&socketData)) {
+ term_socket_server();
DestroyMutexes();
DetachFromSharedMemory();
DestroySharedMemory();
@@ -598,7 +597,7 @@ int main(int argc, char *argv[], char *envp[])
if (Daemon) {
pid_t pid;
if ((pid = fork()) < 0) {
- DetachSocketListener(socketfd);
+ term_socket_server();
DestroyMutexes();
DetachFromSharedMemory();
DestroySharedMemory();
@@ -643,7 +642,7 @@ int main(int argc, char *argv[], char *envp[])
* the daemonization process redefines our handler for (at least) SIGTERM
*/
if (!SetupSignalHandlers()) {
- DetachSocketListener(socketfd);
+ term_socket_server();
DestroyMutexes();
DetachFromSharedMemory();
DestroySharedMemory();
@@ -664,7 +663,7 @@ int main(int argc, char *argv[], char *envp[])
printf("Start garbage \n");
/* start garbage collection thread */
if (!StartGCThread(shmp)) {
- DetachSocketListener(socketfd);
+ term_socket_server();
DestroyMutexes();
DetachFromSharedMemory();
DestroySharedMemory();
@@ -684,7 +683,7 @@ int main(int argc, char *argv[], char *envp[])
#if !(THREADED) && !(NOGARBAGE)
CheckForGarbage(shmp);
#endif
- SocketConnectionHandler(socketfd, 10);
+ socket_connection_handler(10);
}
/*************************************************************
diff --git a/usr/sbin/pkcsslotd/socket_server.c b/usr/sbin/pkcsslotd/socket_server.c
index ae0eff92..1fae0b95 100644
--- a/usr/sbin/pkcsslotd/socket_server.c
+++ b/usr/sbin/pkcsslotd/socket_server.c
@@ -25,10 +25,14 @@
#include "pkcsslotd.h"
#include "apictl.h"
+int proc_listener_socket = -1;
+
+static void close_listener_socket(int socketfd, const char *file_path);
+
// Creates the daemon's listener socket, to which clients will connect and
// retrieve slot information through. Returns the file descriptor of the
// created socket.
-int CreateListenerSocket(void)
+static int create_listener_socket(const char *file_path)
{
struct sockaddr_un address;
struct group *grp;
@@ -39,53 +43,60 @@ int CreateListenerSocket(void)
ErrLog("Failed to create listener socket, errno 0x%X.", errno);
return -1;
}
- if (unlink(SOCKET_FILE_PATH) && errno != ENOENT) {
+ if (unlink(file_path) && errno != ENOENT) {
ErrLog("Failed to unlink socket file, errno 0x%X.", errno);
- close(socketfd);
- return -1;
+ goto error;
}
memset(&address, 0, sizeof(struct sockaddr_un));
address.sun_family = AF_UNIX;
- strcpy(address.sun_path, SOCKET_FILE_PATH);
+ strcpy(address.sun_path, file_path);
if (bind(socketfd,
(struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) {
ErrLog("Failed to bind to socket, errno 0x%X.", errno);
- close(socketfd);
- return -1;
+ goto error;
}
// make socket file part of the pkcs11 group, and write accessable
// for that group
grp = getgrnam("pkcs11");
if (!grp) {
ErrLog("Group PKCS#11 does not exist");
- DetachSocketListener(socketfd);
- return -1;
+ goto error;
}
- if (chown(SOCKET_FILE_PATH, 0, grp->gr_gid)) {
+ if (chown(file_path, 0, grp->gr_gid)) {
ErrLog("Could not change file group on socket, errno 0x%X.", errno);
- DetachSocketListener(socketfd);
- return -1;
+ goto error;
}
- if (chmod(SOCKET_FILE_PATH,
+ if (chmod(file_path,
S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP | S_IXUSR | S_IXGRP)) {
ErrLog("Could not change file permissions on socket, errno 0x%X.",
errno);
- DetachSocketListener(socketfd);
- return -1;
+ goto error;
}
if (listen(socketfd, 20) != 0) {
ErrLog("Failed to listen to socket, errno 0x%X.", errno);
- DetachSocketListener(socketfd);
- return -1;
+ goto error;
}
return socketfd;
+
+error:
+ if (socketfd >= 0)
+ close_listener_socket(socketfd, file_path);
+
+ return -1;
+}
+
+
+static void close_listener_socket(int socketfd, const char *file_path)
+{
+ close(socketfd);
+ unlink(file_path);
}
-int InitSocketData(Slot_Mgr_Socket_t *socketData)
+int init_socket_data(Slot_Mgr_Socket_t *socketData)
{
unsigned int processed = 0;
@@ -102,19 +113,19 @@ int InitSocketData(Slot_Mgr_Socket_t *socketData)
return TRUE;
}
-int SocketConnectionHandler(int socketfd, int timeout_secs)
+int socket_connection_handler(int timeout_secs)
{
int returnVal;
fd_set set;
struct timeval timeout;
FD_ZERO(&set);
- FD_SET(socketfd, &set);
+ FD_SET(proc_listener_socket, &set);
timeout.tv_sec = timeout_secs;
timeout.tv_usec = 0;
- returnVal = select(socketfd + 1, &set, NULL, NULL, &timeout);
+ returnVal = select(proc_listener_socket + 1, &set, NULL, NULL, &timeout);
if (returnVal == -1) {
ErrLog("select failed on socket connection, errno 0x%X.", errno);
return FALSE;
@@ -125,7 +136,7 @@ int SocketConnectionHandler(int socketfd, int timeout_secs)
struct sockaddr_un address;
socklen_t address_length = sizeof(address);
- int connectionfd = accept(socketfd,
+ int connectionfd = accept(proc_listener_socket,
(struct sockaddr *) &address,
&address_length);
if (connectionfd < 0) {
@@ -138,6 +149,10 @@ int SocketConnectionHandler(int socketfd, int timeout_secs)
}
return FALSE;
}
+
+ DbgLog(DL0, "Accepted connection from process: socket: %d",
+ connectionfd);
+
if (write(connectionfd, &socketData, sizeof(socketData)) !=
sizeof(socketData)) {
ErrLog("Failed to write socket data, errno 0x%X.", errno);
@@ -149,8 +164,23 @@ int SocketConnectionHandler(int socketfd, int timeout_secs)
}
}
-void DetachSocketListener(int socketfd)
+int init_socket_server()
{
- close(socketfd);
- unlink(SOCKET_FILE_PATH);
+ proc_listener_socket = create_listener_socket(PROC_SOCKET_FILE_PATH);
+ if (proc_listener_socket < 0)
+ return FALSE;
+
+ DbgLog(DL0, "Socket server started");
+
+ return TRUE;
+}
+
+int term_socket_server()
+{
+ if (proc_listener_socket >= 0)
+ close_listener_socket(proc_listener_socket, PROC_SOCKET_FILE_PATH);
+
+ DbgLog(DL0, "Socket server stopped");
+
+ return TRUE;
}

View File

@ -0,0 +1,287 @@
commit fa94a16116d8382a987ddf9e8cdd88027dd1f647
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue Feb 16 17:13:34 2021 +0100
Event support: Add event client
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/common/common.mk b/usr/lib/common/common.mk
index 2178ad45..882c84f4 100644
--- a/usr/lib/common/common.mk
+++ b/usr/lib/common/common.mk
@@ -4,7 +4,7 @@ noinst_HEADERS += \
usr/lib/common/shared_memory.h usr/lib/common/tok_spec_struct.h \
usr/lib/common/trace.h usr/lib/common/h_extern.h \
usr/lib/common/sw_crypt.h usr/lib/common/defs.h \
- usr/lib/common/p11util.h \
+ usr/lib/common/p11util.h usr/lib/common/event_client.h \
usr/lib/common/list.h usr/lib/common/tok_specific.h
usr/lib/common/lexer.c: usr/lib/common/parser.h
diff --git a/usr/lib/common/event_client.c b/usr/lib/common/event_client.c
new file mode 100644
index 00000000..86117b84
--- /dev/null
+++ b/usr/lib/common/event_client.c
@@ -0,0 +1,215 @@
+/*
+ * COPYRIGHT (c) International Business Machines Corp. 2021
+ *
+ * This program is provided under the terms of the Common Public License,
+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be
+ * found in the file LICENSE file or at
+ * https://opensource.org/licenses/cpl1.0.php
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/un.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <grp.h>
+
+#include "slotmgr.h"
+#include "event_client.h"
+
+static int connect_socket(const char *file_path)
+{
+ int socketfd;
+ struct sockaddr_un daemon_address;
+ struct stat file_info;
+ struct group *grp;
+ int rc;
+
+ if (stat(file_path, &file_info))
+ return -errno;
+
+ grp = getgrnam("pkcs11");
+ if (!grp)
+ return -errno;
+
+ if (file_info.st_uid != 0 || file_info.st_gid != grp->gr_gid)
+ return -EPERM;
+
+ if ((socketfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ return -errno;
+
+ memset(&daemon_address, 0, sizeof(struct sockaddr_un));
+ daemon_address.sun_family = AF_UNIX;
+ strcpy(daemon_address.sun_path, file_path);
+
+ if (connect(socketfd, (struct sockaddr *) &daemon_address,
+ sizeof(struct sockaddr_un)) != 0) {
+ rc = -errno;
+ goto error;
+ }
+
+ return socketfd;
+
+error:
+ close(socketfd);
+ return rc;
+}
+
+static ssize_t read_all(int socketfd, char *buffer, size_t size)
+{
+ size_t bytes_received = 0;
+ ssize_t n;
+
+ while (bytes_received < size) {
+ n = read(socketfd, buffer + bytes_received, size - bytes_received);
+ if (n < 0) {
+ // read error
+ if (errno == EINTR)
+ continue;
+ return -errno;
+ }
+ if (n == 0)
+ break;
+
+ bytes_received += n;
+ }
+
+ return bytes_received;
+}
+
+static ssize_t send_all(int socketfd, char *buffer, size_t size)
+{
+ size_t bytes_sent = 0;
+ ssize_t n;
+
+ while (bytes_sent < size) {
+ n = send(socketfd, buffer + bytes_sent, size - bytes_sent, 0);
+ if (n < 0) {
+ // send error
+ if (errno == EINTR)
+ continue;
+ return -errno;
+ }
+ if (n == 0)
+ break;
+
+ bytes_sent += n;
+ }
+
+ return bytes_sent;
+}
+
+/*
+ * Initialize an admin connection to the pkcsslotd.
+ * Returns a file descriptor representing the connection, or a negative errno
+ * in case of an error.
+ */
+int init_event_client()
+{
+ int fd;
+
+ fd = connect_socket(ADMIN_SOCKET_FILE_PATH);
+
+ return fd;
+}
+
+/*
+ * Send an event though the admin connection to the pkcsslotd, and thus to
+ * all active token instances.
+ * If parameter fd is < 0, then a connection to pkcsslotd is established
+ * inside the function and closed before return. This is for a one shot event.
+ * Otherwise, pass a file descriptor received from init_event_client(). This
+ * is to send multiple events.
+ * Event type is mandatory, flags can be zero.
+ * The event payload is optional, if payload_len is non-zero, then payload must
+ * point to a buffer containing the payload to send with the event.
+ * The event destination can be used to selectively send the event to certain
+ * token instances only. If destination is NULL, it is sent to all token
+ * instances.
+ * If flag EVENT_FLAGS_REPLY_REQ is on in the flags parameter, then it is waited
+ * until all active token instances have replied. The combined result of the
+ * replies from the token instances is returned in the reply structure.
+ * Parameter reply must be non-NULL if flag EVENT_FLAGS_REPLY_REQ is set.
+ * Returns zero for success, or a negative errno in case of an error. In most
+ * error cases the connection to the pkcsslotd is out of sequence and can no
+ * longer be used to send further events.
+ */
+int send_event(int fd, unsigned int type, unsigned int flags,
+ unsigned int payload_len, const char *payload,
+ const struct event_destination *destination,
+ struct event_reply *reply)
+{
+ event_msg_t event_msg;
+ event_reply_t event_reply;
+ int rc, term = 0;
+
+ if (payload_len > 0 && payload == NULL)
+ return -EINVAL;
+ if ((flags & EVENT_FLAGS_REPLY_REQ) && reply == NULL)
+ return -EINVAL;
+ if (payload_len > EVENT_MAX_PAYLOAD_LENGTH)
+ return -EMSGSIZE;
+
+ if (fd < 0) {
+ fd = init_event_client();
+ if (fd < 0)
+ return fd;
+ term = 1;
+ }
+
+ memset(&event_msg, 0, sizeof(event_msg));
+ event_msg.version = EVENT_VERSION_1;
+ event_msg.type = type;
+ event_msg.flags = flags;
+ if (destination != NULL) {
+ event_msg.token_type = destination->token_type;
+ memcpy(event_msg.token_label, destination->token_label,
+ sizeof(event_msg.token_label));
+ event_msg.process_id = destination->process_id;
+ } else {
+ memset(event_msg.token_label, ' ', sizeof(event_msg.token_label));
+ }
+ event_msg.payload_len = payload_len;
+
+ rc = send_all(fd, (char *)&event_msg, sizeof(event_msg));
+ if (rc < 0)
+ goto out;
+
+ if (payload_len > 0) {
+ rc = send_all(fd, (char *)payload, payload_len);
+ if (rc < 0)
+ goto out;
+ }
+
+ if (flags & EVENT_FLAGS_REPLY_REQ) {
+ rc = read_all(fd, (char *)&event_reply, sizeof(event_reply));
+ if (rc < 0)
+ goto out;
+
+ reply->positive_replies = event_reply.positive_replies;
+ reply->negative_replies = event_reply.negative_replies;
+ reply->nothandled_replies = event_reply.nothandled_replies;
+ }
+
+ rc = 0;
+
+out:
+ if (term)
+ term_event_client(fd);
+
+ return rc;
+}
+
+/*
+ * Terminate the admin connection to the pkcsslotd.
+ */
+void term_event_client(int fd)
+{
+ if (fd >= 0)
+ close(fd);
+}
+
diff --git a/usr/lib/common/event_client.h b/usr/lib/common/event_client.h
new file mode 100644
index 00000000..2e4917b0
--- /dev/null
+++ b/usr/lib/common/event_client.h
@@ -0,0 +1,39 @@
+/*
+ * COPYRIGHT (c) International Business Machines Corp. 2021
+ *
+ * This program is provided under the terms of the Common Public License,
+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be
+ * found in the file LICENSE file or at
+ * https://opensource.org/licenses/cpl1.0.php
+ */
+
+
+#ifndef _EVENT_CLIENT_H_
+#define _EVENT_CLIENT_H_
+
+#include "events.h"
+
+struct event_destination {
+ unsigned int token_type; /* Destination token type: EVENT_TOK_TYPE_xxx */
+ char token_label[member_size(event_msg_t, token_label)];
+ /* Label of destination token (or blanks) */
+ pid_t process_id; /* Process ID of destination process (or 0) */
+};
+
+struct event_reply {
+ unsigned long positive_replies;
+ unsigned long negative_replies;
+ unsigned long nothandled_replies;
+};
+
+int init_event_client();
+
+int send_event(int fd, unsigned int type, unsigned int flags,
+ unsigned int payload_len, const char *payload,
+ const struct event_destination *destination,
+ struct event_reply *reply);
+
+void term_event_client(int fd);
+
+#endif

View File

@ -1,7 +1,7 @@
Name: opencryptoki
Summary: Implementation of the PKCS#11 (Cryptoki) specification v2.11
Version: 3.16.0
Release: 2%{?dist}
Release: 3%{?dist}
License: CPL
URL: https://github.com/opencryptoki/opencryptoki
Source0: https://github.com/opencryptoki/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz
@ -15,6 +15,22 @@ Patch1: opencryptoki-3.11.0-lockdir.patch
# Use --no-undefined to debug missing symbols
#Patch100: %%{name}-3.2-no-undefined.patch
# upstream patches
Patch200: opencryptoki-3.16.0-4e3b43c3d8844402c04a66b55c6c940f965109f0.patch
Patch201: opencryptoki-3.16.0-c79e899d77a5724635a9d4451a34a240e2c7e891.patch
Patch202: opencryptoki-3.16.0-69244a5e0d9dfec3ef534b19b89a541576bb17dc.patch
Patch203: opencryptoki-3.16.0-b07505993dd8b2f367cf3b630f6da186e4e8550d.patch
Patch204: opencryptoki-3.16.0-b048be548508dd1958bb7271568f388d0f6cbcf8.patch
Patch205: opencryptoki-3.16.0-e9548127edae313da7840bcb87fd0afd04549c2e.patch
Patch206: opencryptoki-3.16.0-d929fe8470e99f4dcbbd889e7aa87e147d0d5b48.patch
Patch207: opencryptoki-3.16.0-19f56d12b302b87e1dacf613cc61a063ad209d15.patch
Patch208: opencryptoki-3.16.0-342dfbeb8275f5ea6ed52dd3f30126614ec1d037.patch
Patch209: opencryptoki-3.16.0-fa94a16116d8382a987ddf9e8cdd88027dd1f647.patch
Patch210: opencryptoki-3.16.0-d7de5092247a0efc2c397f12977a7c9925420143.patch
Patch211: opencryptoki-3.16.0-1fdd0e4497b0078e73e0004e3492db647c7c458b.patch
Patch212: opencryptoki-3.16.0-bf812c652c49d7e248b115d121a4f7f6568941a2.patch
Patch213: opencryptoki-3.16.0-7b7d83c571ceb3050969359817d4145600f14ae8.patch
Requires(pre): coreutils
BuildRequires: gcc
BuildRequires: gcc-c++
@ -320,6 +336,10 @@ fi
%changelog
* Mon May 17 2021 Than Ngo <than@redhat.com> - 3.16.0-3
- Resolves: #1959894, Soft token does not check if an EC key is valid
- Resolves: #1924120, Event Notification Support
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 3.16.0-2
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937