CLI-first PKCS#11 test suite with segfault survival, interface forcing, and pytest plugin
Project description
pkcs11-check
CLI-first PKCS#11 test suite with segfault survival, interface forcing, and pytest plugin.
What it does
pkcs11-check runs comprehensive tests against PKCS#11 modules (hardware HSMs, software tokens, smart cards). It catches:
- Crashes and segfaults — per-file subprocess isolation recovers from SIGSEGV
- CKR return code violations — different spec conditions checked against OASIS PKCS#11 standard
- CVE regressions — tests for known CVEs across NSS, SoftHSM2, TPM2, OpenCryptoki
- Security policy violations — Tookan paper vectors, attribute fuzzing, padding oracle detection
- Interface negotiation bugs — v2.40/v3.0/v3.1/v3.2 with automatic fallback
Quick start
# Install
git clone https://github.com/mingulov/pkcs11-check
cd pkcs11-check
uv sync
# Run against any PKCS#11 module you provide
uv run pkcs11-check test --p11-module /path/to/module.so --p11-pin 1234
(See "First run in 60 seconds" below for a complete SoftHSM2 example. Provider build recipes and the Docker test matrix live in the development workspace.)
First run in 60 seconds (from PyPI)
pip install pkcs11-check
# 1. Make a token (one-time; SoftHSM2 is the easiest provider)
export SOFTHSM2_CONF="$HOME/softhsm2.conf"
mkdir -p "$HOME/softhsm2-tokens"
echo "directories.tokendir = $HOME/softhsm2-tokens" > "$SOFTHSM2_CONF"
softhsm2-util --init-token --slot 0 --label demo --pin 1234 --so-pin 5678
# 2. Diagnose the setup (module loads? slot / PIN / token OK?)
pkcs11-check doctor --module /usr/lib/softhsm/libsofthsm2.so --slot 0 --pin 1234
# 3. Fast first run (~2s)
pkcs11-check test --module /usr/lib/softhsm/libsofthsm2.so --pin 1234 --slot 0 --marker smoke
# 4. Optional: full coverage (downloads ~800 MB of vectors, then runs the suite)
pkcs11-check fetch-data all
pkcs11-check test --module /usr/lib/softhsm/libsofthsm2.so --pin 1234 --slot 0
Two non-obvious rules:
--slotis a 0-based index into the token-present slots, not the provider's slot ID. Runpkcs11-check info --module <lib>(orpkcs11-check doctor) to list them. (NSS, for example, uses index 1.)fetch-datais optional — only the KAT / Wycheproof / ACVP suites need it; without it those are skipped and the rest still runs.
If anything fails, run pkcs11-check doctor first — it checks the module,
slot, PIN, token, and data, and prints the exact next step for each problem.
New to this? docs/getting-started-softhsm2.md is a complete copy-pasteable walkthrough — install, create a SoftHSM2 config and token from scratch, run the suite, and read the results.
Saving a report
By default pkcs11-check test prints a human-readable summary and keeps no
report file. The generated report log file: /tmp/pkcs11-check-…jsonl lines you
may notice are internal per-process logs that the isolated runner aggregates and
then deletes — they are not meant to be read directly.
To save a machine-readable report, add --output json and --output-file. The
files are written next to the path you give:
pkcs11-check test --module /usr/lib/softhsm/libsofthsm2.so --pin 1234 --slot 0 \
--output json --output-file ./reports/results.json
That writes into ./reports/:
report.jsonl— one JSON record per test (outcome, return code, notes)results.json— the consolidated run summary (counts, crashes, environment)coverage.json,quality.json— mechanism coverage and the per-outcome classification report
Use --output junit --output-file ./reports/results.xml for JUnit XML instead
(for CI). The output directory is taken from the --output-file path, so point it
wherever you want the files created.
Test suite
Test categories:
| Category | Description |
|---|---|
| Core crypto | AES, RSA, ECDSA, EdDSA, HMAC, digest |
| Wycheproof | Edge-case vectors from C2SP |
| PQC (v3.2) | ML-KEM, ML-DSA, SLH-DSA |
| CKR compliance | Return code verification per OASIS spec |
| CVE regression | Known vulnerability tests |
| Security | Attribute fuzz, Tookan, handle reuse |
| Stress | Threading, resource exhaustion |
Supported modules
| Module | Version | Status |
|---|---|---|
| SoftHSM2 | 2.7.0 | Full support |
| Kryoptic | 1.5.1+PQC | Full support (v3.2) |
| NSS softokn | system | Crypto services (slot 0) |
| OpenCryptoki | 3.27.0 | Docker only |
| pkcs11-mock | 2.0.0 | Stub testing |
| tpm2-pkcs11 | 1.10.0 | Hardware TPM |
| BouncyHSM | 2.1.1 | Docker only |
| wolfPKCS11 | 2.0.0-stable / master | Docker only |
| corePKCS11 | 3.6.4 | Docker only |
Known limitations in v0.1.0
- SO login is not implemented yet, so trusted-certificate import with
CKA_TRUSTED=Trueis not fully covered throughCKU_SOworkflows. - CloudHSM/Thales in-band IV profiles, proxy/loader mutable-parameter preservation checks, and broader mutable-output simulator targets are tracked as post-v0.1.0 interop work.
Architecture
src/pkcs11_check/
raw/ — pure ctypes PKCS#11 binding (v2.40-v3.2, PQC)
cli/ — typer CLI (test, doctor, info, version, … commands)
core/ — module loader, isolation runner, preflight
testcases/ — test files (the product)
ckr/ — CKR return code compliance tests
plugin.py — pytest plugin (markers, fixtures, collection)
fixtures.py — p11_session, p11_module, p11_config
config.py — four-layer config (CLI > env > TOML > defaults)
Key features
pkcs11_check.raw— pure Python ctypes binding with v2.40/v3.0/v3.1/v3.2 interface negotiation, 50+ PQC mechanisms, all 68 standard functions--isolation filemode runs each test file in its own subprocess — crashes don't kill the suite--ckr-strictmode enforces exact OASIS spec CKR codes (not just "any error")- Wycheproof + ACVP vectors — cross-verification against C2SP and NIST test vectors
Documentation
docs/architecture.md— codebase structure and test writing guidedocs/commands.md— build, test, and Docker commandsdocs/module-issues.md— per-module bugs and quirksdocs/test-universe.md— collected product-test counts by groupdocs/mechanism-output-parameters.md— generated IV/nonce/tag output-parameter coveragedocs/cve-regression.md— CVE coverage trackerdocs/file-isolation.md— isolation runner design
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Third-party attributions
pkcs11-check bundles the public-domain PKCS#11 v3.2 header from
latchset/pkcs11-headers, and its fetch-data command downloads test
vectors from C2SP and NIST. See
THIRD_PARTY_LICENSES.md for the full list and
per-source license terms.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pkcs11_check-0.1.6.tar.gz.
File metadata
- Download URL: pkcs11_check-0.1.6.tar.gz
- Upload date:
- Size: 1.8 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25441d9784d0bef99ac8c181cc9521de224ff01268bf725aadf9cf16ba376aca
|
|
| MD5 |
bfe7e32a1d4ce84a4247003e731a4246
|
|
| BLAKE2b-256 |
7517f631282566c42974755cc3673d03d728b25a17b04a7a87f194315d2fa423
|
Provenance
The following attestation bundles were made for pkcs11_check-0.1.6.tar.gz:
Publisher:
publish.yml on mingulov/pkcs11-check
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pkcs11_check-0.1.6.tar.gz -
Subject digest:
25441d9784d0bef99ac8c181cc9521de224ff01268bf725aadf9cf16ba376aca - Sigstore transparency entry: 1955313394
- Sigstore integration time:
-
Permalink:
mingulov/pkcs11-check@1bdad43f8dddcad8496157b2ac55dc6444bad106 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/mingulov
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1bdad43f8dddcad8496157b2ac55dc6444bad106 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pkcs11_check-0.1.6-py3-none-any.whl.
File metadata
- Download URL: pkcs11_check-0.1.6-py3-none-any.whl
- Upload date:
- Size: 1.5 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
111efdccfc0abccf8b6ef945697d77c0b281bce56cf077090e7aabb14c7a9603
|
|
| MD5 |
d1030875ab1f18c8502f4b8de1ea7f9a
|
|
| BLAKE2b-256 |
1d78d8ca5d3b7b6d56e14b7521f963284c0a472dcb9875c087eaa2327f0488e3
|
Provenance
The following attestation bundles were made for pkcs11_check-0.1.6-py3-none-any.whl:
Publisher:
publish.yml on mingulov/pkcs11-check
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pkcs11_check-0.1.6-py3-none-any.whl -
Subject digest:
111efdccfc0abccf8b6ef945697d77c0b281bce56cf077090e7aabb14c7a9603 - Sigstore transparency entry: 1955313505
- Sigstore integration time:
-
Permalink:
mingulov/pkcs11-check@1bdad43f8dddcad8496157b2ac55dc6444bad106 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/mingulov
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1bdad43f8dddcad8496157b2ac55dc6444bad106 -
Trigger Event:
workflow_dispatch
-
Statement type: