Skip to content

grisp/grisp_pkcs11

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

grisp_pkcs11

grisp_pkcs11 is a generic PKCS#11 client together with the grisp_keychain_pkcs11 adapter.

This checkout contains an end-to-end Common Test suite that exercises the public Erlang API against a real software token instead of mocks.

Using grisp_pkcs11 with grisp_keychain

grisp_pkcs11 ships the grisp_keychain_pkcs11 backend for grisp_keychain.

At runtime there are two separate responsibilities:

  • grisp_pkcs11 starts and owns the managed PKCS#11 client process
  • grisp_keychain delegates TLS certificate reads and signing to grisp_keychain_pkcs11

In practice this means:

  • your system must start the grisp_pkcs11 application with a valid PKCS#11 module path
  • grisp_keychain must be configured with {api_module, grisp_keychain_pkcs11}
  • PKCS#11 token and object selection is configured under the grisp_pkcs11 application environment
  • generic TLS trust configuration stays under the grisp_keychain application environment

Example sys.config:

[
    {grisp_keychain, [
        {api_module, grisp_keychain_pkcs11},
        {tls_verify, verify_peer},
        {tls_server_trusted_certs, <<"/etc/my_app/certificates/servers">>},
        {tls_server_trusted_certs_cb, {grisp_keychain_utils, system_ca_certs}}
    ]},

    {grisp_pkcs11, [
        {token_label, "OPTEE"},
        {pin, "1234"},
        {key_label, "device-key"},
        {cert_label, "device-cert"}
    ]}
].

The grisp_pkcs11 application must itself be started with the PKCS#11 module path. In this checkout, grisp_pkcs11:start_link/1 and grisp_pkcs11:child_spec/1 take that path explicitly, for example:

grisp_pkcs11:child_spec("/usr/lib/libckteec.so").

The backend currently reads these PKCS#11 settings from the grisp_pkcs11 application environment:

  • slot_id or token_label to select the token
  • pin or pin_file to authenticate when required
  • cert_label and cert_id to find the client certificate
  • key_label and key_id to find the private key
  • sign_mechanism to select the signing mechanism, currently ecdsa

Once configured, callers use the normal grisp_keychain API. For example:

TlsOpts = grisp_keychain:tls_options("example.com"),
CertDer = grisp_keychain:read_cert(primary, der).

This allows applications such as grisp_connect to use PKCS#11-backed client identities without depending directly on the lower-level grisp_pkcs11 API.

Test requirements

The test suite expects these tools to be available on the host:

  • pkcs11-tool
  • softhsm2-util
  • openssl

On Ubuntu, install them with:

sudo apt install opensc softhsm2 openssl

The SoftHSM PKCS#11 module shared object must also be available. On Ubuntu it is typically installed as one of:

  • /usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so
  • /usr/lib/aarch64-linux-gnu/softhsm/libsofthsm2.so
  • /usr/lib/softhsm/libsofthsm2.so

If your system uses a different path, export SOFTHSM2_MODULE before running the tests.

What the suite covers

The test suites intentionally validate the real cross-tool workflows developers care about:

  • OpenSSL-generated EC key and certificate imported with pkcs11-tool
  • token-generated EC keypair created with pkcs11-tool
  • object discovery through grisp_pkcs11:list_slots/0 and grisp_pkcs11:list_objects/2
  • certificate reads through grisp_pkcs11:read_certificate/2
  • digest signing through grisp_pkcs11:sign/3
  • adapter behavior through grisp_keychain_pkcs11 and grisp_keychain
  • OpenSSL verification of signatures produced through Erlang
  • OpenSSL verification of signatures produced directly by pkcs11-tool
  • validation failures, missing PIN behavior, object lookup failures, slot-id selection, client recovery, and concurrent sign requests

The suites create a temporary SoftHSM token store under the system temp directory. They do not touch persistent system tokens.

Build commands

The supported developer entrypoints are exposed through the root Makefile:

make
make build
make nif
make test
  • make or make build runs rebar3 compile
  • make nif builds only priv/grisp_pkcs11_nif.so
  • make test runs the full Common Test suite with an isolated SoftHSM setup

Running the tests

Run the full Common Test suite:

make test

Run one suite at a time:

make test CT_ARGS="--suite=test/grisp_pkcs11_SUITE.erl"
make test CT_ARGS="--suite=test/grisp_keychain_pkcs11_SUITE.erl"

make test creates an isolated temporary SOFTHSM2_CONF before Erlang starts, which is required for SoftHSM-backed Common Test runs to behave reliably.

If you prefer to invoke rebar3 directly, you must export SOFTHSM2_CONF yourself before starting the Erlang VM:

export SOFTHSM2_CONF="$(mktemp -d)/softhsm2.conf"
rebar3 ct

You can also override tool paths individually:

OPENSSL=/custom/bin/openssl \
PKCS11_TOOL=/custom/bin/pkcs11-tool \
SOFTHSM2_UTIL=/custom/bin/softhsm2-util \
make test

Notes for developers

  • The support module lives in test/grisp_pkcs11_test_utils.erl.
  • The helper module owns all external command execution and fixture creation so the suites stay declarative and easy to read.
  • If a requirement is missing, suite initialization fails early with a clear error describing which executable, module path, or environment variable could not be found.

About

Grisp PKCS#11 library, backend for grisp_keychain

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors