Software signer backed by a PKCS#12 (.p12 / .pfx) bundle.
Loads the bundle once via load/2 (uses the openssl pkcs12 CLI
for decryption — pure-Erlang PKCS#12 decode is fragile across
vendor encodings) and returns a struct that implements
SignCore.Signer. Sign operations route through
:public_key.sign/3 with the right padding for the requested
algorithm.
Threat model — key material is BEAM-resident
The decoded RSA private key is held as an Erlang RSAPrivateKey
record on the returned %SoftSigner.PKCS12{} struct. It lives
in BEAM heap memory for the entire lifetime of any reference to
the struct — including indirect references via process state,
ETS tables, supervised GenServer state, etc. The BEAM has no
zeroization primitive for managed binaries / integers, and the GC
may retain freed copies well after the explicit reference is gone.
Use this signer only when the threat model accepts that the key:
- is readable by anyone with BEAM-process memory access (other
OS processes with
/proc/<pid>/memrights, core dumps, hibernation snapshots, swapped pages on a memory-pressured host, attached debuggers); - is recoverable from a kernel core dump or crash dump;
- may transiently appear in
:erlang.process_info/2output for processes holding the struct.
For threat models that exclude any of these (regulated tax
certificates, banking integration keys, anything that must never
be software-copyable), use pkcs11ex instead — the key stays
inside the HSM / token across the PKCS#11 boundary and never
enters the BEAM.
This package is named soft_signer precisely to make the
hardware-vs-software distinction part of the dependency graph: a
deployment that omits :soft_signer from its mix.lock cannot
software-sign by package boundary, not just by configuration.
Usage
{:ok, signer} = SoftSigner.PKCS12.load("path/to/bundle.p12", password: "secret")
{:ok, signed_pdf} =
SignCore.PDF.sign(pdf,
signer: signer,
alg: :PS256,
x5c: SoftSigner.PKCS12.cert_chain(signer)
)Cert chain
PKCS#12 bundles carry the leaf cert (and often intermediate
CA certs). cert_chain/1 returns them as a list of DER binaries,
leaf first — drop straight into the :x5c opt of any format
adapter.
Summary
Functions
Returns the bundle's certificate chain as a list of DER binaries,
leaf first. Drop into any format adapter's :x5c opt.
Load a PKCS#12 bundle from path and return a %SoftSigner.PKCS12{}
struct ready for SignCore.Signer.sign/3.
Types
Functions
Returns the bundle's certificate chain as a list of DER binaries,
leaf first. Drop into any format adapter's :x5c opt.
Load a PKCS#12 bundle from path and return a %SoftSigner.PKCS12{}
struct ready for SignCore.Signer.sign/3.
Required opts:
:password— bundle password (string).
Optional:
:openssl— path to theopensslCLI. DefaultSystem.find_executable("openssl").
Returns {:error, {:openssl, message}} if the CLI is missing or
the bundle won't decrypt.