P11ex.Module (p11ex v0.5.0)

Copy Markdown View Source

A module is a GenServer that manages a PKCS#11 module and its loading state. A PKCS#11 module is a shared library that implements a PKCS#11 provider. A module should be loaded only once per application or beam virtual machine. That is, you should only create one instance of P11ex.Module in your application and add it to your supervision tree. Operations on the module should be performed through the GenServer callbacks so that they are serialized.

Loading a module

To load a module, you can use the start_link/1 function. The argument is the path to the module file. The module will be loaded and initialized.

defmodule MyApp.Supervisor do
  use Supervisor

  def start_link(init_arg) do
    Supervisor.start_link(__MODULE__, init_arg, name: __MODULE__)
  end

  def init(init_arg) do
    children = [
      {P11ex.Module, "/usr/lib/softhsm/libsofthsm2.so"}
    ]
    Supervisor.init(children, strategy: :one_for_one)
  end
end

Summary

Functions

Returns a specification to start this module under a supervisor.

Find the slot that contains a token with the given label.

GenServer callback. Loads the PKCS#11 module from the module_path passed to start_link/1.

List all mechanisms supported by the PKCS#11 module for a slot. This function has two variants

List all slots in the module. The token_present? argument is optional and defaults to true. If set to true, only slots with a token present are returned.

Get information about a mechanism for a given slot. The mechanism is specified as an atom or an integer. For example, the mechanism :ckm_aes_cbc can also be specified as the integer 0x00001082

Returns a reference to the handle of the PKCS#11 module. Usually, this is not needed by the application, but it can be useful if you need to perform operations on the module that are not otherwise provided by this library.

Start the P11ex.Module GenServer. The argument is either the path to the PKCS#11 module file (shared library); or a list starting with the path to the PKCS#11 module file, followed by other keyword options.

Get information about a token in a slot. This function has two variants

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

find_slot_by_tokenlabel(server \\ __MODULE__, label)

@spec find_slot_by_tokenlabel(GenServer.server(), binary()) ::
  {:ok, P11ex.Lib.Slot.t()} | {:ok, nil} | {:error, atom()}

Find the slot that contains a token with the given label.

init(module_path)

GenServer callback. Loads the PKCS#11 module from the module_path passed to start_link/1.

list_mechanisms(server \\ __MODULE__, slot)

@spec list_mechanisms(GenServer.server(), non_neg_integer()) ::
  {:ok, [atom() | non_neg_integer()]} | {:error, atom()}
@spec list_mechanisms(GenServer.server(), P11ex.Lib.Slot.t()) ::
  {:ok, [atom() | non_neg_integer()]} | {:error, atom()}

List all mechanisms supported by the PKCS#11 module for a slot. This function has two variants:

  1. list_mechanisms(slot_id) - List mechanisms using a slot ID
  2. list_mechanisms(slot) - List mechanisms using a Slot struct

The mechanisms are returned as a list of atoms. If the mechanism is not known to P11ex (e.g. a vendor specific mechanism), it will be returned as an integer.

list_slots(server \\ __MODULE__, token_present?)

@spec list_slots(GenServer.server(), boolean()) ::
  {:ok, [P11ex.Lib.Slot.t()]} | {:error, P11ex.Lib.nif_error()}

List all slots in the module. The token_present? argument is optional and defaults to true. If set to true, only slots with a token present are returned.

mechanism_info(server \\ __MODULE__, slot, mechanism_type)

@spec mechanism_info(
  GenServer.server(),
  P11ex.Lib.Slot.t(),
  atom() | non_neg_integer()
) ::
  {:ok, map()} | {:error, atom()}

Get information about a mechanism for a given slot. The mechanism is specified as an atom or an integer. For example, the mechanism :ckm_aes_cbc can also be specified as the integer 0x00001082:

{:ok, info} = P11ex.Module.mechanism_info(slot, :ckm_aes_cbc)
{:ok, info} = P11ex.Module.mechanism_info(slot, 0x00001082)

The return value is a map with the following keys:

  • flags - The flags of the mechanism (a list of atoms, see P11ex.Flags). This indicates for what operations the mechanism can be used, e.g. :encrypt, :decrypt, :sign, :verify, etc.
  • min_length - The minimum key length supported by the mechanism (an integer)
  • max_length - The maximum key length supported by the mechanism (an integer)

For example, for :ckm_aes_cbc a typical return value is:

%{flags: MapSet.new([:wrap, :encrypt, :decrypt]), min_length: 16, max_length: 32}

If the mechanism is not known, the return value is {:error, {:C_GetMechanismInfo, :ckr_mechanism_invalid}}.

module_handle(server \\ __MODULE__)

@spec module_handle(GenServer.server()) :: reference()

Returns a reference to the handle of the PKCS#11 module. Usually, this is not needed by the application, but it can be useful if you need to perform operations on the module that are not otherwise provided by this library.

start_link(args)

@spec start_link(binary() | keyword()) :: GenServer.on_start()

Start the P11ex.Module GenServer. The argument is either the path to the PKCS#11 module file (shared library); or a list starting with the path to the PKCS#11 module file, followed by other keyword options.

The keyword options are:

token_info(server \\ __MODULE__, slot)

@spec token_info(GenServer.server(), non_neg_integer()) ::
  {:ok, P11ex.Lib.Slot.token_info()} | {:error, P11ex.Lib.nif_error()}
@spec token_info(GenServer.server(), P11ex.Lib.Slot.t()) ::
  {:ok, P11ex.Lib.Slot.token_info()} | {:error, P11ex.Lib.nif_error()}

Get information about a token in a slot. This function has two variants:

  1. token_info(slot_id) - Get token info using a slot ID
  2. token_info(slot) - Get token info using a Slot struct

See P11ex.Lib.Slot.token_info() for the fields of the returned map.