Hi!
Thank you for your work on the php-pkcs11 extension!
We are planning to deploy it in a FrankenPHP worker-mode setup where PHP threads are long-lived. Our performance requirements make two things necessary: a ZTS-compatible build, and a persistent session pool to avoid repeated C_OpenSession overhead against the HSM on every request.
Before investing more time in testing and polishing, we wanted to check whether you'd be interested in taking this upstream at all.
I've implemented the changes in a fork on the feature/php-zts branch: https://github.com/mroest/php-pkcs11/tree/feature/php-zts
What was added:
-
ZTS support — the extension compiles cleanly with ZTS enabled. C_Initialize is called with CKF_OS_LOCKING_OK in threaded builds and NULL in non-ZTS builds, preserving existing behaviour.
-
Process-wide library registry (pkcs11module.c) — a HashTable keyed by resolved library path, protected by a pthread_mutex, prevents duplicate C_Initialize calls across threads sharing the same HSM library.
-
Per-thread session pool — a ZEND_MODULE_GLOBALS session pool (keyed by realpath:slotID:flags) amortises C_OpenSession cost across requests. Sessions are logged out before being returned to the pool, so every reuse requires a fresh login, avoiding credential leakage between requests.
-
Stale-session resilience — a PKCS11_SESSION_CALL macro transparently evicts an invalid pool entry, opens a fresh session, and retries the operation once on stale-handle errors (CKR_SESSION_HANDLE_INVALID etc.).
-
12 new .phpt tests covering pool reuse, credential rejection, stale eviction, tainted-session cleanup, and shutdown ordering.
All changes are backward-compatible — non-ZTS builds follow the same code paths without the threading overhead.
Current status: tested against SoftHSM2 only. We plan to test against real hardware, but wanted to gauge your interest first before investing further.
Where its used: https://github.com/OpenConext/OpenConext-private-key-agent
Happy to discuss the approach in more detail. Let me know what you think!
Hi!
Thank you for your work on the
php-pkcs11extension!We are planning to deploy it in a FrankenPHP worker-mode setup where PHP threads are long-lived. Our performance requirements make two things necessary: a ZTS-compatible build, and a persistent session pool to avoid repeated
C_OpenSessionoverhead against the HSM on every request.Before investing more time in testing and polishing, we wanted to check whether you'd be interested in taking this upstream at all.
I've implemented the changes in a fork on the
feature/php-ztsbranch: https://github.com/mroest/php-pkcs11/tree/feature/php-ztsWhat was added:
ZTS support — the extension compiles cleanly with
ZTSenabled.C_Initializeis called withCKF_OS_LOCKING_OKin threaded builds andNULLin non-ZTS builds, preserving existing behaviour.Process-wide library registry (
pkcs11module.c) — aHashTablekeyed by resolved library path, protected by apthread_mutex, prevents duplicateC_Initializecalls across threads sharing the same HSM library.Per-thread session pool — a
ZEND_MODULE_GLOBALSsession pool (keyed byrealpath:slotID:flags) amortisesC_OpenSessioncost across requests. Sessions are logged out before being returned to the pool, so every reuse requires a fresh login, avoiding credential leakage between requests.Stale-session resilience — a
PKCS11_SESSION_CALLmacro transparently evicts an invalid pool entry, opens a fresh session, and retries the operation once on stale-handle errors (CKR_SESSION_HANDLE_INVALIDetc.).12 new
.phpttests covering pool reuse, credential rejection, stale eviction, tainted-session cleanup, and shutdown ordering.All changes are backward-compatible — non-ZTS builds follow the same code paths without the threading overhead.
Current status: tested against SoftHSM2 only. We plan to test against real hardware, but wanted to gauge your interest first before investing further.
Where its used: https://github.com/OpenConext/OpenConext-private-key-agent
Happy to discuss the approach in more detail. Let me know what you think!