Compare commits

..

4 Commits
a8 ... c8

Author SHA1 Message Date
AlmaLinux RelEng Bot
0eee3ed2f8 import Oracle_OSS opencryptoki-3.22.0-3.el8_10.3 2026-06-17 01:45:37 -04:00
AlmaLinux RelEng Bot
b42b826cd0 import Oracle_OSS opencryptoki-3.22.0-3.el8_10.2 2026-03-24 21:27:22 -04:00
4076cc5987 import OL opencryptoki-3.22.0-3.el8_10.1 2025-08-27 11:32:41 +00:00
11405685c9 Import from AlmaLinux stable repository 2024-05-31 17:58:26 +00:00
11 changed files with 2321 additions and 320 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/opencryptoki-3.21.0.tar.gz
SOURCES/opencryptoki-3.22.0.tar.gz

View File

@ -1 +1 @@
4a0f2ed8f965a948057ab833f1fafabf58929d3f SOURCES/opencryptoki-3.21.0.tar.gz
4618b82afde56a8177e888c26d336c6f521bed8a SOURCES/opencryptoki-3.22.0.tar.gz

View File

@ -0,0 +1,55 @@
From 742463a3c5a25313ab7ceb578d81b9998db65f67 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed, 2 Apr 2025 16:36:45 +0200
Subject: [PATCH] CCA: Adjust CCA host library version detection for newer CCA
versions
Newer CCA versions might report the version string with CSUACFV or CSUACFQ
with keyword STATCCA using a different indicator character after the version
information. Ignore the indication character and the remaining data entirely.
Only the version information as such is of interest.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/cca_stdll/cca_specific.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/usr/lib/cca_stdll/cca_specific.c b/usr/lib/cca_stdll/cca_specific.c
index 80369248..08e794d0 100644
--- a/usr/lib/cca_stdll/cca_specific.c
+++ b/usr/lib/cca_stdll/cca_specific.c
@@ -751,7 +751,6 @@ static CK_RV cca_get_version(STDLL_TokData_t *tokdata)
long return_code, reason_code;
long version_data_length;
long exit_data_len = 0;
- char date[20];
/* Get CCA host library version */
version_data_length = sizeof(version_data);
@@ -767,10 +766,10 @@ static CK_RV cca_get_version(STDLL_TokData_t *tokdata)
version_data[sizeof(version_data) - 1] = '\0';
TRACE_DEVEL("CCA Version string: %s\n", version_data);
- if (sscanf((char *)version_data, "%u.%u.%uz%s",
+ if (sscanf((char *)version_data, "%u.%u.%u",
&cca_private->cca_lib_version.ver,
&cca_private->cca_lib_version.rel,
- &cca_private->cca_lib_version.mod, date) != 4) {
+ &cca_private->cca_lib_version.mod) != 3) {
TRACE_ERROR("CCA library version is invalid: %s\n", version_data);
return CKR_FUNCTION_FAILED;
}
@@ -3431,8 +3430,8 @@ static CK_RV cca_get_adapter_version(cca_min_card_version_t *data)
memcpy(ccaversion, &rule_array[CCA_STATCCA_CCA_VERSION_OFFSET],
CCA_STATCCA_CCA_VERSION_LENGTH);
- if (sscanf(ccaversion, "%d.%d.%02d*", (int *)&adapter_version.ver,
- (int *)&adapter_version.rel, (int *)&adapter_version.mod) != 3) {
+ if (sscanf(ccaversion, "%u.%u.%u", &adapter_version.ver,
+ &adapter_version.rel, &adapter_version.mod) != 3) {
TRACE_ERROR("sscanf of string %s failed, cannot determine CCA card version\n",
ccaversion);
return CKR_FUNCTION_FAILED;
--
2.16.2.windows.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,499 @@
commit b3392430af1fe260386d609c967f514679d218a4
Author: Pavel Kohout <pavel@aisle.com>
Date: Tue Jan 13 00:00:00 2026 +0000
Fix symlink-following vulnerabilities (CWE-59)
Multiple symlink-following vulnerabilities exist in OpenCryptoki that run
in privileged contexts. These allow a token-group user to redirect file
operations to arbitrary filesystem targets by planting symlinks in
group-writable token directories, resulting in privilege escalation or
data exposure.
Affected components:
1. pkcstok_migrate: fopen() follows symlinks, then set_perm() modifies the
target permissions.
2. loadsave.c: Multiple wrapper functions use fopen() followed by set_perm().
3. hsm_mk_change.c: hsm_mk_change_op_open() uses fopen() followed by
hsm_mk_change_op_set_perm().
4. pbkdf.c: fopen() followed by set_perms() in two locations.
This fix:
- Introduces fopen_nofollow() helper in platform.h
- Checks for O_NOFOLLOW at compile time (not hardcoded per-platform)
- On platforms with O_NOFOLLOW: uses open(O_NOFOLLOW) + fdopen() for atomic
symlink rejection (race-condition free)
- On platforms without O_NOFOLLOW: falls back to lstat() + fopen() and emits
a compiler warning so the unsafe fallback doesn't go unnoticed
- Updates all affected wrapper functions to use fopen_nofollow()
Reported-by: Pavel Kohout, Aisle Research, www.aisle.com
Signed-off-by: Pavel Kohout <pavel@aisle.com>
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/common/loadsave.c b/usr/lib/common/loadsave.c
index 09553b51..352a71dc 100644
--- a/usr/lib/common/loadsave.c
+++ b/usr/lib/common/loadsave.c
@@ -42,6 +42,7 @@
#include "trace.h"
#include "ock_syslog.h"
#include "slotmgr.h" // for ock_snprintf
+#include "platform.h"
extern void set_perm(int);
@@ -67,9 +68,17 @@ static FILE *open_token_object_path(char *buf, size_t buflen,
STDLL_TokData_t *tokdata, char *path,
char *mode)
{
+ FILE *fp;
+
if (get_token_object_path(buf, buflen, tokdata, path) < 0)
return NULL;
- return fopen(buf, mode);
+
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
+ fp = fopen_nofollow(buf, mode);
+ if (fp == NULL && errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", buf);
+
+ return fp;
}
static int get_token_data_store_path(char *buf, size_t buflen,
@@ -86,9 +95,17 @@ static FILE *open_token_data_store_path(char *buf, size_t buflen,
STDLL_TokData_t *tokdata, char *path,
char *mode)
{
+ FILE *fp;
+
if (get_token_data_store_path(buf, buflen, tokdata, path) < 0)
return NULL;
- return fopen(buf, mode);
+
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
+ fp = fopen_nofollow(buf, mode);
+ if (fp == NULL && errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", buf);
+
+ return fp;
}
static FILE *open_token_object_index(char *buf, size_t buflen,
@@ -100,11 +117,19 @@ static FILE *open_token_object_index(char *buf, size_t buflen,
static FILE *open_token_nvdat(char *buf, size_t buflen,
STDLL_TokData_t *tokdata, char *mode)
{
+ FILE *fp;
+
if (ock_snprintf(buf, buflen, "%s/" PK_LITE_NV, tokdata->data_store)) {
TRACE_ERROR("NVDAT.TOK file name buffer overflow\n");
return NULL;
}
- return fopen(buf, mode);
+
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
+ fp = fopen_nofollow(buf, mode);
+ if (fp == NULL && errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", buf);
+
+ return fp;
}
char *get_pk_dir(STDLL_TokData_t *tokdata, char *fname, size_t len)
@@ -185,9 +210,12 @@ CK_RV save_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
// we didn't find it...either the index file doesn't exist or this
// is a new object...
//
- fp = fopen(fname, "a");
+ fp = fopen_nofollow(fname, "a");
if (!fp) {
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
return CKR_FUNCTION_FAILED;
}
@@ -237,8 +265,12 @@ CK_RV delete_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
fclose(fp1);
fclose(fp2);
- fp2 = fopen(objidx, "w");
- fp1 = fopen(idxtmp, "r");
+ fp2 = fopen_nofollow(objidx, "w");
+ if (fp1 == NULL && errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", objidx);
+ fp1 = fopen_nofollow(idxtmp, "r");
+ if (fp2 == NULL && errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", idxtmp);
if (!fp1 || !fp2) {
if (fp1)
fclose(fp1);
@@ -526,11 +558,14 @@ CK_RV load_token_data_old(STDLL_TokData_t *tokdata, CK_SLOT_ID slot_id)
if (errno == ENOENT) {
init_token_data(tokdata, slot_id);
- fp = fopen(fname, "r");
+ fp = fopen_nofollow(fname, "r");
if (!fp) {
// were really hosed here since the created
// did not occur
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
rc = CKR_FUNCTION_FAILED;
goto out_unlock;
}
@@ -730,9 +765,12 @@ static CK_RV save_private_token_object_old(STDLL_TokData_t *tokdata, OBJECT *obj
rc = CKR_FUNCTION_FAILED;
goto error;
}
- fp = fopen(fname, "w");
+ fp = fopen_nofollow(fname, "w");
if (!fp) {
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
rc = CKR_FUNCTION_FAILED;
goto error;
}
@@ -1483,9 +1521,12 @@ CK_RV reload_token_object_old(STDLL_TokData_t *tokdata, OBJECT *obj)
rc = CKR_FUNCTION_FAILED;
goto done;
}
- fp = fopen(fname, "r");
+ fp = fopen_nofollow(fname, "r");
if (!fp) {
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
rc = CKR_FUNCTION_FAILED;
goto done;
}
@@ -1572,9 +1613,12 @@ CK_RV save_public_token_object_old(STDLL_TokData_t *tokdata, OBJECT * obj)
rc = CKR_FUNCTION_FAILED;
goto error;
}
- fp = fopen(fname, "w");
+ fp = fopen_nofollow(fname, "w");
if (!fp) {
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
rc = CKR_FUNCTION_FAILED;
goto error;
}
@@ -2179,11 +2223,14 @@ CK_RV load_token_data(STDLL_TokData_t *tokdata, CK_SLOT_ID slot_id)
if (errno == ENOENT) {
init_token_data(tokdata, slot_id);
- fp = fopen(fname, "r");
+ fp = fopen_nofollow(fname, "r");
if (!fp) {
// were really hosed here since the created
// did not occur
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
rc = CKR_FUNCTION_FAILED;
goto out_unlock;
}
@@ -2355,7 +2402,7 @@ CK_RV save_private_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
goto done;
}
- fp = fopen(fname, "r");
+ fp = fopen_nofollow(fname, "r");
if (fp == NULL) {
/* create new token object */
new = 1;
@@ -2453,9 +2500,12 @@ do_work:
if (rc != CKR_OK)
goto done;
- fp = fopen(fname, "w");
+ fp = fopen_nofollow(fname, "w");
if (!fp) {
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
rc = CKR_FUNCTION_FAILED;
goto done;
}
@@ -2650,9 +2700,12 @@ CK_RV reload_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
sprintf(fname, "%s/%s/", tokdata->data_store, PK_LITE_OBJ_DIR);
strncat(fname, (char *) obj->name, 8);
- fp = fopen(fname, "r");
+ fp = fopen_nofollow(fname, "r");
if (!fp) {
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
rc = CKR_FUNCTION_FAILED;
goto done;
}
@@ -2763,9 +2816,12 @@ CK_RV save_public_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
sprintf(fname, "%s/%s/", tokdata->data_store, PK_LITE_OBJ_DIR);
strncat(fname, (char *) obj->name, 8);
- fp = fopen(fname, "w");
+ fp = fopen_nofollow(fname, "w");
if (!fp) {
- TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
rc = CKR_FUNCTION_FAILED;
goto done;
}
@@ -2823,9 +2879,12 @@ CK_RV load_public_token_objects(STDLL_TokData_t *tokdata)
sprintf(fname, "%s/%s/", tokdata->data_store, PK_LITE_OBJ_DIR);
strcat(fname, tmp);
- fp2 = fopen(fname, "r");
- if (!fp2)
+ fp2 = fopen_nofollow(fname, "r");
+ if (!fp2) {
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
continue;
+ }
if (fread(header, PUB_HEADER_LEN, 1, fp2) != 1) {
fclose(fp2);
diff --git a/usr/lib/common/platform.h b/usr/lib/common/platform.h
new file mode 100644
index 00000000..b3e5473b
--- /dev/null
+++ b/usr/lib/common/platform.h
@@ -0,0 +1,91 @@
+/*
+ * COPYRIGHT (c) International Business Machines Corp. 2024
+ *
+ * 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 PLATFORM_H
+#define PLATFORM_H
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+/*
+ * Check for O_NOFOLLOW support at compile time.
+ * If not available, fall back to lstat() + fopen() (has TOCTOU race).
+ */
+#ifndef O_NOFOLLOW
+#define OCK_NO_O_NOFOLLOW 1
+#warning "O_NOFOLLOW not supported, symlink protection uses racy lstat() fallback!"
+#endif
+
+/*
+ * CWE-59 fix: Open file without following symlinks.
+ *
+ * On platforms with O_NOFOLLOW support:
+ * Uses open(O_NOFOLLOW) + fdopen() for atomic symlink rejection.
+ *
+ * On platforms without O_NOFOLLOW (e.g., older AIX):
+ * Falls back to lstat() + fopen(). This has a TOCTOU race condition,
+ * but still catches pre-planted symlinks which is the common attack
+ * scenario. Better than no protection at all.
+ *
+ * Returns NULL with errno=ELOOP if path is a symlink.
+ */
+static inline FILE *fopen_nofollow(const char *path, const char *mode)
+{
+#ifdef OCK_NO_O_NOFOLLOW
+ /*
+ * Fallback for platforms without O_NOFOLLOW: use lstat() check.
+ * This has a TOCTOU race but catches pre-planted symlinks.
+ */
+ struct stat sb;
+
+ if (lstat(path, &sb) == 0) {
+ if (S_ISLNK(sb.st_mode)) {
+ errno = ELOOP;
+ return NULL;
+ }
+ }
+ /* Note: if lstat fails (e.g., file doesn't exist for "w" mode),
+ * we proceed with fopen() which will handle the error appropriately */
+ return fopen(path, mode);
+#else
+ /* Preferred: atomic symlink rejection via O_NOFOLLOW */
+ int flags = O_NOFOLLOW;
+ int fd;
+ FILE *fp;
+
+ /* Determine flags based on mode */
+ if (mode[0] == 'r') {
+ flags |= (mode[1] == '+') ? O_RDWR : O_RDONLY;
+ } else if (mode[0] == 'w') {
+ flags |= O_CREAT | O_TRUNC | ((mode[1] == '+') ? O_RDWR : O_WRONLY);
+ } else if (mode[0] == 'a') {
+ flags |= O_CREAT | O_APPEND | ((mode[1] == '+') ? O_RDWR : O_WRONLY);
+ } else {
+ return NULL;
+ }
+
+ fd = open(path, flags, 0600);
+ if (fd < 0)
+ return NULL;
+
+ fp = fdopen(fd, mode);
+ if (fp == NULL) {
+ close(fd);
+ return NULL;
+ }
+ return fp;
+#endif
+}
+
+#endif /* PLATFORM_H */
diff --git a/usr/lib/hsm_mk_change/hsm_mk_change.c b/usr/lib/hsm_mk_change/hsm_mk_change.c
index 6c032965..bbdd94c2 100644
--- a/usr/lib/hsm_mk_change/hsm_mk_change.c
+++ b/usr/lib/hsm_mk_change/hsm_mk_change.c
@@ -29,6 +29,7 @@
#endif
#include "hsm_mk_change.h"
#include "pkcs32.h"
+#include "platform.h"
struct hsm_mk_change_op_hdr {
char id[6];
@@ -611,9 +612,13 @@ static FILE* hsm_mk_change_op_open(const char *id, CK_SLOT_ID slot_id,
TRACE_DEVEL("file to open: %s mode: %s\n", hsm_mk_change_file, mode);
- fp = fopen(hsm_mk_change_file, mode);
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
+ fp = fopen_nofollow(hsm_mk_change_file, mode);
if (fp == NULL) {
- TRACE_ERROR("%s fopen(%s, %s): %s\n", __func__,
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", hsm_mk_change_file);
+ else
+ TRACE_ERROR("%s fopen(%s, %s): %s\n", __func__,
hsm_mk_change_file, mode, strerror(errno));
}
diff --git a/usr/lib/icsf_stdll/pbkdf.c b/usr/lib/icsf_stdll/pbkdf.c
index abf9ff13..e50fe4e2 100644
--- a/usr/lib/icsf_stdll/pbkdf.c
+++ b/usr/lib/icsf_stdll/pbkdf.c
@@ -27,6 +27,7 @@
#include "h_extern.h"
#include "pbkdf.h"
#include "trace.h"
+#include "platform.h"
CK_RV get_randombytes(unsigned char *output, int bytes)
@@ -527,9 +528,13 @@ CK_RV secure_racf(STDLL_TokData_t *tokdata,
/* get the total length */
totallen = outputlen + AES_INIT_VECTOR_SIZE;
- fp = fopen(RACFFILE, "w");
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
+ fp = fopen_nofollow(RACFFILE, "w");
if (!fp) {
- TRACE_ERROR("fopen failed: %s\n", strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", RACFFILE);
+ else
+ TRACE_ERROR("fopen failed: %s\n", strerror(errno));
return CKR_FUNCTION_FAILED;
}
@@ -600,9 +605,13 @@ CK_RV secure_masterkey(STDLL_TokData_t *tokdata,
/* get the total length */
totallen = outputlen + SALTSIZE;
- fp = fopen(fname, "w");
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
+ fp = fopen_nofollow(fname, "w");
if (!fp) {
- TRACE_ERROR("fopen failed: %s\n", strerror(errno));
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+ else
+ TRACE_ERROR("fopen failed: %s\n", strerror(errno));
return CKR_FUNCTION_FAILED;
}
diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
index a9777a3c..84988b2c 100644
--- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
@@ -41,6 +41,7 @@
#include "local_types.h"
#include "h_extern.h"
#include "slotmgr.h" // for ock_snprintf
+#include "platform.h"
#define OCK_TOOL
#include "pkcs_utils.h"
@@ -70,9 +71,14 @@ static FILE *open_datastore_file(char *buf, size_t buflen,
TRACE_ERROR("Path overflow for datastore file %s\n", file);
return NULL;
}
- res = fopen(buf, mode);
- if (!res)
- TRACE_ERROR("fopen(%s) failed, errno=%s\n", buf, strerror(errno));
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
+ res = fopen_nofollow(buf, mode);
+ if (!res) {
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", buf);
+ else
+ TRACE_ERROR("fopen(%s) failed, errno=%s\n", buf, strerror(errno));
+ }
return res;
}
@@ -87,9 +93,14 @@ static FILE *open_tokenobject(char *buf, size_t buflen,
file, tokenobj);
return NULL;
}
- res = fopen(buf, mode);
- if (!res)
- TRACE_ERROR("fopen(%s) failed, errno=%s\n", buf, strerror(errno));
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
+ res = fopen_nofollow(buf, mode);
+ if (!res) {
+ if (errno == ELOOP)
+ TRACE_ERROR("Refusing to follow symlink: %s\n", buf);
+ else
+ TRACE_ERROR("fopen(%s) failed, errno=%s\n", buf, strerror(errno));
+ }
return res;
}

View File

@ -1,34 +0,0 @@
commit 2ba0f41ef5e14d4b509c8854e27cf98e3ee89445
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon Jul 10 13:22:48 2023 +0200
p11sak: Fix parsing of slot number 0
Running command 'p11sak list-key aes --slot 0' may result in
'p11sak: Invalid argument '0' for option '-s/--slot''
This is because of the error checking after strtoul() within function
process_number_argument(). In case errno is not zero, it treats a
parsed value of zero as an error.
Under certain circumstances, errno is non-zero already before calling
strtoul(), and stays non-zero in case of strtoul() succeeds. This leads to
an incorrect error checking, and it is treated as error.
Initialize errno to zero before calling strtoul() to avoid such false error
detection.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/sbin/p11sak/p11sak.c b/usr/sbin/p11sak/p11sak.c
index 6e11cb41..38665bbd 100644
--- a/usr/sbin/p11sak/p11sak.c
+++ b/usr/sbin/p11sak/p11sak.c
@@ -1712,6 +1712,7 @@ static CK_RV process_number_argument(const struct p11sak_arg *arg, char *val)
{
char *endptr;
+ errno = 0;
*arg->value.number = strtoul(val, &endptr, 0);
if ((errno == ERANGE && *arg->value.number == ULONG_MAX) ||

View File

@ -1,52 +0,0 @@
commit 4ff774568e334a719fc8de16fe2309e2070f0da8
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon May 22 11:40:01 2023 +0200
p11sak: Fix user confirmation prompt behavior when stdin is closed
Treat any error during user confirmation prompt as 'cancel' and skip all
operations.
One can for example close stdin during a user prompt via CTRL+D. This was
erroneously treated as positive confirmation and therefore caused the
operation to be performed on the current key object and all further objects
matching the filter as well, instead of canceling the operation entirely.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/sbin/p11sak/p11sak.c b/usr/sbin/p11sak/p11sak.c
index d75d8343..5b54b538 100644
--- a/usr/sbin/p11sak/p11sak.c
+++ b/usr/sbin/p11sak/p11sak.c
@@ -4736,6 +4736,7 @@ static CK_RV handle_key_remove(CK_OBJECT_HANDLE key, CK_OBJECT_CLASS class,
data->num_skipped++;
return CKR_OK;
case 'c':
+ case '\0':
data->skip_all = true;
data->num_skipped++;
return CKR_OK;
@@ -4825,6 +4826,7 @@ static CK_RV handle_key_set_attr(CK_OBJECT_HANDLE key, CK_OBJECT_CLASS class,
data->num_skipped++;
return CKR_OK;
case 'c':
+ case '\0':
data->skip_all = true;
data->num_skipped++;
return CKR_OK;
@@ -4974,6 +4976,7 @@ static CK_RV handle_key_copy(CK_OBJECT_HANDLE key, CK_OBJECT_CLASS class,
data->num_skipped++;
return CKR_OK;
case 'c':
+ case '\0':
data->skip_all = true;
data->num_skipped++;
return CKR_OK;
@@ -6983,6 +6986,7 @@ static CK_RV handle_key_export(CK_OBJECT_HANDLE key, CK_OBJECT_CLASS class,
data->num_skipped++;
return CKR_OK;
case 'c':
+ case '\0':
data->skip_all = true;
data->num_skipped++;
return CKR_OK;

View File

@ -1,96 +0,0 @@
commit 92999f344a3ad99a67a1bcfd9ad28f28c33e51bc
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon Jul 10 10:19:13 2023 +0200
p11sak: Fix listing of key objects when other object types are present
A command like 'p11sak list-key all --slot N ...' fails with
p11sak: Attribute CKA_KEY_TYPE is not available in key object
p11sak: Failed to iterate over key objects for key type All: 0xD0: CKR_TEMPLATE_INCOMPLETE
p11sak: Failed to perform the 'list-key' command: CKR_TEMPLATE_INCOMPLETE
when the object repository contains other, non-key objects, e.g. certificates.
When 'all' is used as key type, then no filter for CKA_KEY_TYPE is used
with C_FindObjects(), and thus other non-key objects also match the filter.
When a specific key type is specified, then only such objects match that
have the desired CKA_KEY_TYPE attribute value.
Fix this by checking the object class in get_key_infos() and skip the object,
if it is not a key object.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/sbin/p11sak/p11sak.c b/usr/sbin/p11sak/p11sak.c
index a6213720..6e11cb41 100644
--- a/usr/sbin/p11sak/p11sak.c
+++ b/usr/sbin/p11sak/p11sak.c
@@ -3403,6 +3403,16 @@ static CK_RV get_key_infos(CK_OBJECT_HANDLE key, CK_OBJECT_CLASS *class,
}
}
+ switch (class_val) {
+ case CKO_PUBLIC_KEY:
+ case CKO_PRIVATE_KEY:
+ case CKO_SECRET_KEY:
+ break;
+ default:
+ free(attrs[0].pValue);
+ return CKR_KEY_NEEDED;
+ }
+
for (i = 0; i < num_attrs; i++) {
if (attrs[i].ulValueLen == CK_UNAVAILABLE_INFORMATION) {
warnx("Attribute %s is not available in key object",
@@ -3614,6 +3624,10 @@ static CK_RV iterate_key_objects(const struct p11sak_keytype *keytype,
if (manual_filtering) {
rc = get_key_infos(keys[i], NULL, NULL, NULL, &label,
NULL, NULL);
+ if (rc == CKR_KEY_NEEDED) {
+ rc = CKR_OK;
+ goto next;
+ }
if (rc != CKR_OK)
break;
@@ -3672,6 +3686,10 @@ done_find:
for (i = 0; i < num_matched_keys; i++) {
rc = get_key_infos(matched_keys[i], &class, &ktype, &keysize,
&label, &typestr, &type);
+ if (rc == CKR_KEY_NEEDED) {
+ rc = CKR_OK;
+ goto next2;
+ }
if (rc != CKR_OK)
break;
@@ -3680,6 +3698,7 @@ done_find:
if (rc != CKR_OK)
break;
+next2:
if (label != NULL)
free(label);
label = NULL;
@@ -4480,10 +4499,20 @@ static CK_RV p11sak_list_key_compare(CK_OBJECT_HANDLE key1,
*result = 0;
rc = get_key_infos(key1, &class1, &ktype1, &keysize1, &label1, NULL, NULL);
+ if (rc == CKR_KEY_NEEDED) {
+ rc = CKR_OK;
+ *result = 1; /* non-key objects are always greater than key objects */
+ goto done;
+ }
if (rc != CKR_OK)
goto done;
rc = get_key_infos(key2, &class2, &ktype2, &keysize2, &label2, NULL, NULL);
+ if (rc == CKR_KEY_NEEDED) {
+ rc = CKR_OK;
+ *result = -1; /* key objects are always smaller than non-key objects */
+ goto done;
+ }
if (rc != CKR_OK)
goto done;

View File

@ -1,84 +0,0 @@
commit f4166214552a92d8d66de8011ab11c9c2c6bb0a4
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon May 22 13:31:21 2023 +0200
pkcsstats: Fix handling of user name
The struct passwd returned by getpwuid() is a pointer to a static area, that
may get overwritten by subsequent calls to getpwuid() or similar.
Actually, C_Initialize() itself is using getpwuid() internally, and thus will
interfere with the getpwuid() usage in pkcsstats.
Make a copy of the returned user name before calling C_Initialize() in
init_ock() to ensure to work with the desired user name, and not with anything
left over from previous calls.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/sbin/pkcsstats/pkcsstats.c b/usr/sbin/pkcsstats/pkcsstats.c
index c2444cf5..a842a295 100644
--- a/usr/sbin/pkcsstats/pkcsstats.c
+++ b/usr/sbin/pkcsstats/pkcsstats.c
@@ -783,6 +783,7 @@ int main(int argc, char **argv)
int opt = 0;
struct passwd *pswd = NULL;
int user_id = -1;
+ char *user_name = NULL;
bool summary = false, all_users = false, all_mechs = false;
bool reset = false, reset_all = false;
bool delete = false, delete_all = false;
@@ -903,19 +904,27 @@ int main(int argc, char **argv)
}
}
+ user_name = strdup(pswd->pw_name);
+ if (user_name == NULL) {
+ warnx("Failed to get current user name");
+ exit(EXIT_FAILURE);
+ }
+
if (delete) {
if (slot_id_specified) {
warnx("Options -s/--slot and -d/--delete can not be specified together");
+ free(user_name);
exit(EXIT_FAILURE);
}
- rc = delete_shm(user_id, pswd->pw_name);
+ rc = delete_shm(user_id, user_name);
goto done;
}
if (delete_all) {
if (slot_id_specified) {
warnx("Options -s/--slot and -D/--delete-all can not be specified together");
+ free(user_name);
exit(EXIT_FAILURE);
}
@@ -932,7 +941,7 @@ int main(int argc, char **argv)
goto done;
if (reset) {
- rc = reset_shm(user_id, pswd->pw_name, num_slots, slots,
+ rc = reset_shm(user_id, user_name, num_slots, slots,
slot_id_specified, slot_id);
goto done;
}
@@ -968,7 +977,7 @@ int main(int argc, char **argv)
rc = display_summary(&dd);
goto done;
} else {
- rc = display_stats(user_id, pswd->pw_name, &dd);
+ rc = display_stats(user_id, user_name, &dd);
goto done;
}
@@ -984,5 +993,7 @@ done:
dlclose(dll);
}
+ free(user_name);
+
return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@ -1,37 +0,0 @@
commit f8ddcd5ba7e5b0bab00dedc89021147ec55b41b3
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue May 23 15:07:02 2023 +0200
p11sak: Fix segfault in PEM_write_bio() on OpenSSL 1.1.1
On OpenSSL version before 1.1.1r function PEM_write_bio() segfaults when the
'header' argument is NULL. This was fixed in OpenSSL 1.1.1r with commit
https://github.com/openssl/openssl/commit/3b9082c844913d3a0efada9fac0bd2924ce1a8f2
As a workaround, specify an empty string instead of NULL, which results in the
same output.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/sbin/p11sak/p11sak.c b/usr/sbin/p11sak/p11sak.c
index 5b54b538..3baae560 100644
--- a/usr/sbin/p11sak/p11sak.c
+++ b/usr/sbin/p11sak/p11sak.c
@@ -6794,7 +6794,7 @@ static CK_RV p11sak_export_spki(const struct p11sak_keytype *keytype,
return rc;
}
- ret = PEM_write_bio(bio, PEM_STRING_PUBLIC, NULL,
+ ret = PEM_write_bio(bio, PEM_STRING_PUBLIC, "",
attr.pValue, attr.ulValueLen);
if (ret <= 0) {
warnx("Failed to write SPKI of %s key object \"%s\" to PEM file '%s'.",
@@ -6888,7 +6888,7 @@ static CK_RV p11sak_export_asym_key(const struct p11sak_keytype *keytype,
ret = PEM_write_bio(bio, private ?
keytype->pem_name_private :
keytype->pem_name_public,
- NULL, data, data_len);
+ "", data, data_len);
if (ret <= 0) {
warnx("Failed to write %s key object \"%s\" to PEM file '%s'.",
typestr, label, opt_file);

View File

@ -1,7 +1,7 @@
Name: opencryptoki
Summary: Implementation of the PKCS#11 (Cryptoki) specification v3.0
Version: 3.21.0
Release: 10%{?dist}.alma.1
Version: 3.22.0
Release: 3%{?dist}.3
License: CPL
Group: System Environment/Base
URL: https://github.com/opencryptoki/opencryptoki
@ -15,23 +15,18 @@ Patch2: opencryptoki-3.21.0-p11sak.patch
Patch3: opencryptoki-3.21-sandboxing.patch
# upstream patches
# pkcsstats: Fix handling of user name
Patch100: opencryptoki-3.21.0-f4166214552a92d8d66de8011ab11c9c2c6bb0a4.patch
# p11sak: Fix user confirmation prompt behavior when stdin is closed
Patch101: opencryptoki-3.21.0-4ff774568e334a719fc8de16fe2309e2070f0da8.patch
# p11sak: Fix segfault in PEM_write_bio() on OpenSSL 1.1.1
Patch102: opencryptoki-3.21.0-f8ddcd5ba7e5b0bab00dedc89021147ec55b41b3.patch
# p11sak fails as soon as there reside non-key objects
Patch103: opencryptoki-3.21.0-92999f344a3ad99a67a1bcfd9ad28f28c33e51bc.patch
# opencryptoki p11sak tool: slot option does not accept argument 0 for slot index 0
Patch104: opencryptoki-3.21.0-2ba0f41ef5e14d4b509c8854e27cf98e3ee89445.patch
# CVE-2024-0914 opencryptoki: timing side-channel in handling of RSA PKCS#1 v1.5 padded ciphertexts
Patch20: opencryptoki-CVE-2024-0914-part1.patch
Patch21: opencryptoki-CVE-2024-0914-part2.patch
Patch22: opencryptoki-CVE-2024-0914-part3.patch
Patch23: opencryptoki-CVE-2024-0914-part4.patch
Patch24: opencryptoki-CVE-2024-0914-part5.patch
# supporting CCA 8.4
Patch25: 3.22-CCA-Adjust-CCA-host-library-version-detection-for-ne.patch
# CVE-3-2026-23893, symlink-following vulnerabilities
Patch26: opencryptoki-3.20.0-CVE-3-2026-23893.patch
# CVE-2026-40253, possible out-of-bounds access in BER decode functions
Patch27: opencryptoki-3.20.0-CVE-2026-40253.patch
Requires(pre): coreutils diffutils
Requires: (selinux-policy >= 3.14.3-121 if selinux-policy-targeted)
@ -392,8 +387,25 @@ fi
%changelog
* Wed Apr 03 2024 Andrew Lukoshko <alukoshko@almalinux.org> - 3.21.0-10.alma.1
- timing side-channel in handling of RSA PKCS#1 v1.5 padded ciphertexts (Marvin) (CVE-2024-0914)
* Tue May 19 2026 Than Ngo <than@redhat.com> - 3.22.0-3.3
- Resolves: RHEL-171558, Fix possible out-of-bounds access in BER decode functions
* Mon Mar 02 2026 Than Ngo <than@redhat.com> - 3.22.0-3.2
- Resolves: RHEL-144817, CVE-2026-23893 Privilege Escalation or Data Exposure via Symlink Following
* Mon Aug 11 2025 Than Ngo <than@redhat.com> - 3.22.0-3.1
- Resolves: RHEL-105918, fix for supporting CCA 8.4
* Fri Feb 16 2024 Than Ngo <than@redhat.com> - 3.22.0-3
- Fix implicit rejection with RSA keys with empty CKA_PRIVATE_EXPONENT
Related: RHEL-22791
* Thu Feb 08 2024 Than Ngo <than@redhat.com> - 3.22.0-2
- timing side-channel in handling of RSA PKCS#1 v1.5 padded ciphertexts (Marvin)
Resolves: RHEL-22791
* Thu Nov 23 2023 Than Ngo <than@redhat.com> - 3.22.0-1
- Resolves: RHEL-11413, update to 3.22.0
* Tue Jul 18 2023 Than Ngo <than@redhat.com> - 3.21.0-9
- Resolves: #2223588, FTBFS