
p11ex --- PKCS#11 bindings for Elixir
p11ex is an Elixir library that provides access to the PKCS#11 interface for cryptographic tokens such as Hardware Security Modules and smartcards. The library exposes most PKCS#11 functionality to Elixir, though it is not yet feature complete. Available functions include:
C_GetSlotList: List tokensC_GetTokenInfo: Retrieve information about a tokenC_OpenSession: Open a new PKCS#11 sessionC_CloseSession: Close a PKCS#11 sessionC_CloseAllSession: Close all open sessions for a tokenC_GetSessionInfo: Retrieve status information about a sessionC_Login: Authenticate an open sessionC_Logout: Deauthenticate an open sessionC_GenerateKey: Generate a symmetric keyC_FindObjects: Search for objects stored in the tokenC_GetAttributeValue: Retrieve attributes of an objectC_EncryptInit,C_Encrypt,C_EncryptUpdate, andC_EncryptFinal: Encryption in chunks and as a complete blockC_DecryptInit,C_Decrypt,C_DecryptUpdate, andC_DecryptFinal: Decryption in chunks and as a complete blockC_GenerateRandom: Generate random bytes using the tokenC_DestroyObject: Delete objects in the token or sessionC_GetMechanismList: List cryptographic mechanisms supported by tokenC_GetMechanismInfo: Retrieve information about a mechanismC_SignInit,C_Sign,C_SignUpdate,C_SignFinal: Sign data in chunks and as a complete blockC_VerifyInit,C_Verify: Verify a signatureC_DigestInit,C_Digest,C_DigestUpdate,C_DigestFinal: Compute a hash digest in the tokenC_GenKeyPair: Generate asymmetric key pairC_WrapKey: Encrypt an extractable key and make it exportableC_UnwrapKey: Decrypt an exported key into the token
Some PKCS#11 functions require mechanism parameters as arguments. Common parameter types are supported and documented in the Elixir documentation.
The implementation is automatically tested with SoftHSM on Linux (AMD64 and ARM64) and macOS (ARM64). Additional tests are available for the Yubikey PKCS#11 module, though these do not run automatically as part of the build.
Build Prerequisite: PKCS#11 Headers
The NIF build expects PKCS#11 C headers in c_src/.
In CI these files are downloaded before compilation; for local builds, do the same manually:
cd c_src
curl -fL -O https://raw.githubusercontent.com/oasis-tcs/pkcs11/master/published/3-01/pkcs11.h
curl -fL -O https://raw.githubusercontent.com/oasis-tcs/pkcs11/master/published/3-01/pkcs11t.h
curl -fL -O https://raw.githubusercontent.com/oasis-tcs/pkcs11/master/published/3-01/pkcs11f.h
cd ..
mix deps.compile p11ex --force
Do not commit downloaded header files accidentally if your workflow stores them outside the source tree.
p11ex_cli --- CLI program to use PKCS#11 tokens
The project also includes a CLI program named p11ex_cli for working with cryptographic tokens. This program provides access to key p11ex functions.
Available Commands
slot-list: List available PKCS#11 slots/tokensobject-list: List objects (keys, certificates) on a tokenkey-gen-aes: Generate AES symmetric keysexport-pubk: Export public keys (RSA, EC, EdDSA)sign: Sign data with RSA, EC, or EdDSA algorithmskey-wrap/key-unwrap: Wrap/unwrap keys for secure transportkcv-gen: Compute Key Check Value (fingerprint) of secret keysbench-aes-encrypt-block: Benchmark AES encryption performance
For detailed documentation on each command, run p11ex_cli <command> --help.
EdDSA Support
p11ex_cli supports EdDSA signatures (Ed25519, Ed448). Use the sign command with the appropriate mechanism:
p11ex_cli sign --mechanism Ed25519 --key-label my-ed25519-key --data-file input.txt --signature-file output.sig
Release Process
The release process is semi-automated using three GitHub Actions workflows. Before creating a release, ensure the CHANGELOG.md is updated with the changes to be released.
Prerequisites
- Commits must follow Conventional Commits format
CHANGELOG.mdshould have an "Unreleased" section with pending changes- Required secrets must be configured in repository settings (see RELEASE.md for details)
Three Workflows Involved
The release process uses three separate workflows that should be triggered in order:
1. Release Library to Hex.pm (.github/workflows/release-lib-hexpm.yml)
This workflow:
- Calculates the next version based on conventional commits
- Updates
mix.exswith the new version - Creates a git tag (e.g.,
v0.4.0) - Builds documentation and Hex package
- Performs a dry-run build test to verify the package structure (Makefile, required files)
- Publishes the package to Hex.pm
- Triggered manually via Actions UI
Run this first - it creates the git tag needed by the other workflows. The dry-run test ensures the package can be compiled correctly before publishing.
2. Release CLI Binaries (.github/workflows/release-cli.yml)
This workflow:
- Builds
p11ex_clibinaries for Linux (amd64, arm64) and macOS (arm64) - Creates tar.gz archives of the binaries
- Generates SHA256 checksums
- Uploads release artifacts
- Requires a version tag as input (must match a git tag from step 1)
- Triggered manually via Actions UI
Run this second - after the git tag exists from step 1.
3. Create Codeberg Release (.github/workflows/release-lib-codeberg.yml)
This workflow:
- Creates a release on Codeberg (Forgejo) using the Forgejo API
- Uses the git tag created in step 1
- Generates release notes referencing CHANGELOG.md
- Provides installation instructions in the release description
- Requires tag name and version as inputs
- Triggered manually via Actions UI
Run this third - after the git tag exists from step 1.
Release Steps
Update CHANGELOG.md
- Move items from "Unreleased" section to a new version section
- Follow the Keep a Changelog format
- Commit and push the changelog update
Trigger Library Release
- Go to Actions → "Release p11ex library to Hex.pm"
- Click "Run workflow"
- The workflow will calculate version, update files, and publish
Trigger CLI Release
- Wait for library release to complete and tag to be created
- Go to Actions → "Release p11ex-cli binaries"
- Click "Run workflow"
- Enter the version tag (e.g.,
0.4.0) - Download the release artifacts from the workflow run
Create GitHub/Codeberg Release (if applicable)
- Create a release on the repository using the git tag
- Upload the CLI binaries from the workflow artifacts
- Add release notes from CHANGELOG.md
For detailed information about the release process, troubleshooting, and manual release procedures, see RELEASE.md.
Quick Reference
| Workflow | Trigger | Input | Output |
|---|---|---|---|
release-lib-hexpm.yml | Manual | None | Hex.pm package, git tag |
release-cli.yml | Manual | Version tag | CLI binaries, checksums |
release-lib-codeberg.yml | Manual | Tag name, version | Codeberg release |
Note: The Docker workflows (.github/workflows/docker-base.yml and .github/workflows/docker-build.yml) build and maintain the test infrastructure images used by the release workflows. They run automatically on a schedule (twice weekly) or can be triggered manually if needed.