> ## Documentation Index
> Fetch the complete documentation index at: https://docs.futurex.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create the HSM-backed CA and responder keys

> Generate the CA and responder RSA key pairs in the CryptoHub, self-sign the CA certificate, and issue the responder certificate with the CryptoHub-resident CA key.

Generate two RSA key pairs inside the CryptoHub: one acts as the certificate authority, the other is the responder's IKE authentication key. Neither private key exists on the Linux host at any point.

Use distinct object IDs so the final tunnel test is not affected by older test objects.

## Key requirements

| Purpose       | Label          | ID   | Key type | Usage             |
| ------------- | -------------- | ---- | -------- | ----------------- |
| CA key        | `strongSwanCA` | `01` | RSA 3072 | sign, signRecover |
| Responder key | `StrongSwan`   | `02` | RSA 3072 | sign, signRecover |

## Generate the CryptoHub-resident CA key

```shell expandable lines wrap title="Shell" theme={null}
read -rsp "HSM PIN: " HSM_PIN
echo

sudo env FXPKCS11_CFG=/etc/fxpkcs11.cfg HOME=/root \
pkcs11-tool \
--module /usr/local/lib/fxpkcs11/libfxpkcs11.so \
--login --pin "$HSM_PIN" \
--keypairgen --key-type rsa:3072 \
--label "strongSwanCA" --id "01" --usage-sign

unset HSM_PIN
```

<Check>
  The command reports the generated public key, `Public Key Object; RSA 3072 bits`, with the label `strongSwanCA`.
</Check>

<Warning>
  If this step fails with `CKR_TEMPLATE_INCONSISTENT`, the endpoint role is missing `CertManage:Add`. The client-side error text does not name the missing permission. Review the permissions in [Before you start](/Integrations/CryptoHub/VPN/strongSwan/Before_you_start) and retry.
</Warning>

Confirm the CA key exists:

```shell expandable lines wrap title="Shell" theme={null}
read -rsp "HSM PIN: " HSM_PIN
echo

sudo env FXPKCS11_CFG=/etc/fxpkcs11.cfg HOME=/root \
pkcs11-tool \
--module /usr/local/lib/fxpkcs11/libfxpkcs11.so \
--login --pin "$HSM_PIN" \
--list-objects --type privkey --id 01 -v

unset HSM_PIN
```

<Check>
  The output shows `Private Key Object; RSA`, label `strongSwanCA`, ID `01`, and `Usage: sign, signRecover`.
</Check>

<Warning>
  If this returns **no output at all** — no error, just nothing — the role is missing `CertManage:Export` or `CertManage:Export Private Key`. The key was created successfully; the client cannot enumerate it. Grant both and retry.
</Warning>

## Create the self-signed CA certificate

<Note>
  When using an HSM object ID with `ipsec pki --self`, include `--type priv`. Without this option, strongSwan may fail to locate the HSM-backed private key.
</Note>

```shell expandable lines wrap title="Shell" theme={null}
mkdir -p ~/strongswan-certs
cd ~/strongswan-certs

sudo env FXPKCS11_CFG=/etc/fxpkcs11.cfg HOME=/root \
ipsec pki --self \
--type priv \
--keyid 01 \
--ca \
--lifetime 3650 \
--serial 01 \
--dn "C=US, O=Example, CN=strongSwan Test CA" \
--outform pem > strongswanCert.pem
```

Substitute your own organization and common name in `--dn`.

Verify the CA certificate:

```shell expandable lines wrap title="Shell" theme={null}
head -n 2 strongswanCert.pem

ipsec pki --print --in strongswanCert.pem
```

<Check>
  The output reports the subject and issuer as the same DN, `flags: CA CRLSign self-signed`, and `pubkey: RSA 3072 bits`. The log lines confirming `found key on PKCS#11 token 'futurex':0` show the signature was produced inside the CryptoHub.
</Check>

## Generate the CryptoHub-resident responder key

```shell expandable lines wrap title="Shell" theme={null}
read -rsp "HSM PIN: " HSM_PIN
echo

sudo env FXPKCS11_CFG=/etc/fxpkcs11.cfg HOME=/root \
pkcs11-tool \
--module /usr/local/lib/fxpkcs11/libfxpkcs11.so \
--login --pin "$HSM_PIN" \
--keypairgen --key-type rsa:3072 \
--label "StrongSwan" --id "02" --usage-sign

unset HSM_PIN
```

Confirm the responder key exists:

```shell expandable lines wrap title="Shell" theme={null}
read -rsp "HSM PIN: " HSM_PIN
echo

sudo env FXPKCS11_CFG=/etc/fxpkcs11.cfg HOME=/root \
pkcs11-tool \
--module /usr/local/lib/fxpkcs11/libfxpkcs11.so \
--login --pin "$HSM_PIN" \
--list-objects --id 02 -v

unset HSM_PIN
```

<Check>
  Both a private and a public key object appear with the label `StrongSwan` and ID `02`.
</Check>

Read the public key out of the HSM so the CA can certify it:

```shell expandable lines wrap title="Shell" theme={null}
cd ~/strongswan-certs

read -rsp "HSM PIN: " HSM_PIN
echo

sudo env FXPKCS11_CFG=/etc/fxpkcs11.cfg HOME=/root \
pkcs11-tool \
--module /usr/local/lib/fxpkcs11/libfxpkcs11.so \
--login --pin "$HSM_PIN" \
--read-object --type pubkey --id "02" \
--output-file strongswan-pub.der

unset HSM_PIN

ls -lh strongswan-pub.der
```

<Check>
  `strongswan-pub.der` exists and is several hundred bytes. Only the **public** key is read out; the private key remains in the CryptoHub.
</Check>

## Issue the responder certificate with the CryptoHub CA key

```shell expandable lines wrap title="Shell" theme={null}
cd ~/strongswan-certs

sudo env FXPKCS11_CFG=/etc/fxpkcs11.cfg HOME=/root \
ipsec pki --issue \
--in strongswan-pub.der \
--type pub \
--cacert strongswanCert.pem \
--cakeyid 01 \
--dn "CN=StrongSwan" \
--flag clientAuth \
--serial 02 \
--outform pem > strongswan-cert.pem
```

`--cakeyid 01` tells `pki` to sign with the CA key inside the CryptoHub.

Verify the issued certificate:

```shell expandable lines wrap title="Shell" theme={null}
head -n 2 strongswan-cert.pem

ipsec pki --print --in strongswan-cert.pem

ipsec pki --verify \
--in strongswan-cert.pem \
--cacert strongswanCert.pem
```

<Check>
  `--print` reports subject `CN=StrongSwan`, the CA DN as issuer, and `pubkey: RSA 3072 bits`. `--verify` reports `certificate trusted, lifetimes valid` after reaching the self-signed root.
</Check>

If any command on this page fails, see [Troubleshooting](/Integrations/CryptoHub/VPN/strongSwan/Troubleshooting).
