# `mix pkcs11ex.import_p12`
[🔗](https://github.com/utaladriz/pkcs11ex/blob/v0.1.0/lib/mix/tasks/pkcs11ex.import_p12.ex#L1)

Imports the private key + leaf certificate from a PKCS#12 (`.p12` / `.pfx`)
bundle into a configured PKCS#11 slot.

Intended for: SoftHSM provisioning in dev/CI, one-shot loading of taxpayer
/ legal-proxy certificates into write-permitted file-backed tokens, fixture
setup in test suites. **Not** suitable for production HSMs (most reject
software-key import by design; cloud HSMs do so categorically).

See `docs/specs/api.md` §5.1 for the canonical contract.

## Usage

    mix pkcs11ex.import_p12 \
      --in legal_proxy.p12 \
      --slot legal_proxy \
      --label proxy-signing-key \
      [--cert-label proxy-cert] \
      [--id 0x01]

## Required flags

  * `--in PATH` — path to the `.p12` / `.pfx` bundle.
  * `--slot SLOT_REF` — atom of a configured slot (must exist in
    `:pkcs11ex` `:slots` config, must be write-permitted).
  * `--label LABEL` — `CKA_LABEL` for the imported private key.

## Optional flags

  * `--cert-label LABEL` — `CKA_LABEL` for the certificate. Defaults to `--label`.
  * `--id HEX` — `CKA_ID` (hex-encoded). Auto-generated if omitted.
  * `--password-from-env VAR` — read P12 password from env var (CI).
  * `--pin-from-env VAR` — read user PIN from env var (CI).

## Prompts

When `--password-from-env` / `--pin-from-env` are not used, the task
prompts for the bundle password and the slot's user PIN with terminal
echo disabled.

## Threat model — plaintext key in BEAM heap

This task is the only path in `pkcs11ex` that handles a software
RSA private key in cleartext. The key flows through BEAM-managed
binaries:

  1. `openssl pkcs12 -in <bundle> -nocerts -nodes` extracts the key
     as a PEM blob into the task's stdout (captured by `System.cmd`
     into a binary).
  2. `:public_key.pem_decode/1` and `pem_entry_decode/1` produce an
     Erlang `RSAPrivateKey` record — modulus, private exponent, the
     five CRT parameters, all as integers / binaries on the BEAM heap.
  3. The components are marshaled across the NIF as binaries, then
     the NIF zeroizes its Rust-side copies (cryptoki + `Zeroizing`).

  Step 1 and step 2 BEAM heap memory cannot be wiped — the BEAM has
  no zeroization primitive for managed binaries / integers, and the
  GC may keep them around well past the task's nominal lifetime.

**The only mitigations are:**

  * Run the task in a short-lived process; let the BEAM exit
    immediately after the import.
  * Don't run on a multi-tenant box where another process can read
    `/proc/<pid>/maps` or trigger a core dump.
  * Treat the bundle on disk as the canonical secret — the BEAM-heap
    copy is a temporary echo of it.

Use `pkcs11ex` directly (HSM-only path) for any key that should
never have a software copy in memory. This task is for provisioning
fixtures, dev/CI, and importing dormant taxpayer / legal-proxy
certificates into write-permitted file-backed tokens.

Both the bundle password and the user PIN are passed once into the
flow and not stored after this task returns. They transit BEAM
memory the same way and are subject to the same caveats.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
