> ## 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.

# Configure the KMIP client

> Configure a KMIP application with the endpoint TLS files, then verify TLS 1.2 client authentication and one authenticated KMIP operation against CryptoHub.

Configure the application's KMIP client with the files from the endpoint download, then verify that CryptoHub accepts the client certificate and answers a KMIP request. Field names and import steps differ by application, so use this page with the application vendor's KMIP or external key manager documentation.

## Map the endpoint files to KMIP settings

Most KMIP applications ask for the same settings. Use these values from the endpoint download:

| KMIP setting | Value |
| - | - |
| Server host | The KMIP address from `info.txt`, for example `cryptohub.example.com` |
| Server port | `5696` |
| Client certificate | `client-cert.pem`, or the certificate inside `pki.p12` |
| Client private key | The private key inside `pki.p12`, protected by the password in `pki-password.txt` |
| Server CA certificate | `ca-chain.pem` |
| TLS version | TLS 1.2 or TLS 1.3 |
| Username and password | Leave empty. TLS-bundle authentication uses the client certificate. |

## Prepare the TLS files

Run these commands on a protected administrator host with OpenSSL 3. Replace `<endpoint-zip>` with the path of the downloaded ZIP.

<Steps>
  <Step title="Extract the endpoint download">
    Create a private working directory and extract the ZIP into it.

    ```bash theme={null}
    umask 077
    mkdir kmip-endpoint
    unzip <endpoint-zip> -d kmip-endpoint
    cd kmip-endpoint
    ```

    <Check>
      The directory contains `pki.p12`, `pki-password.txt`, `client-cert.pem`, and `ca-chain.pem`.
    </Check>
  </Step>

  <Step title="Extract the client private key">
    Write the unencrypted client private key to `client-key.pem`. The command reads the PKCS #12 password from `pki-password.txt`, so the password does not appear in your shell history, and `openssl pkey` removes the PKCS #12 bag attributes from the output.

    ```bash theme={null}
    openssl pkcs12 -in pki.p12 -passin file:pki-password.txt -nocerts -nodes | openssl pkey -out client-key.pem
    ```

    OpenSSL 3 opens `pki.p12` without the `-legacy` option.

    <Check>
      `client-key.pem` begins with a `-----BEGIN PRIVATE KEY-----` line.
    </Check>
  </Step>

  <Step title="Confirm that the key matches the certificate">
    Compare the public-key hash of the certificate with the public-key hash of the private key.

    ```bash theme={null}
    openssl x509 -in client-cert.pem -noout -pubkey | openssl sha256
    openssl pkey -in client-key.pem -pubout | openssl sha256
    openssl x509 -in client-cert.pem -noout -subject -enddate
    ```

    <Check>
      The two hashes are identical, and the certificate expiry date is in the future.
    </Check>
  </Step>

  <Step title="Convert to the format the application accepts">
    Use the files in the format that the application requires:

    * **Separate PEM files:** use `client-cert.pem`, `client-key.pem`, and `ca-chain.pem`.
    * **Combined PEM file:** run `cat client-cert.pem client-key.pem > client-cert-and-key.pem`.
    * **PKCS #12 file:** import `pki.p12` directly and enter the password from `pki-password.txt`.

    <Check>
      You have the client certificate, client private key, and server CA in the format that the application's KMIP settings accept.
    </Check>
  </Step>

  <Step title="Transfer and protect the files">
    Copy only the files that the application needs to the application host over a protected channel. Make the private key readable only by the account that runs the application's KMIP client, then delete the working directory from the administrator host.

    <Check>
      The private key file on the application host is not readable by other accounts.
    </Check>
  </Step>
</Steps>

## Configure the application

<Steps>
  <Step title="Open the KMIP settings">
    Open the application's KMIP, external key manager, or key management server settings. Use the vendor's documentation for the exact location.
  </Step>

  <Step title="Enter the server settings">
    Enter the CryptoHub KMIP host from `info.txt` and port `5696`. Add the contents of `ca-chain.pem` as the trusted server CA.
  </Step>

  <Step title="Enter the client credential">
    Import the client certificate and private key in the format that the application accepts. Leave any KMIP username and password fields empty.
  </Step>

  <Step title="Save and test">
    Save the settings and run the application's connection or key-server test, if it has one.

    <Check>
      The application reports a successful connection to the key server.
    </Check>
  </Step>
</Steps>

## Verify the connection

Run two checks before you rely on the integration: TLS 1.2 client authentication, then one authenticated KMIP operation. Run them from the application host or from a host with the same network path to CryptoHub.

<Steps>
  <Step title="Check TLS 1.2 client authentication">
    Open a TLS 1.2 connection to the KMIP port with the endpoint client certificate.

    ```bash theme={null}
    openssl s_client -connect cryptohub.example.com:5696 -tls1_2 \
      -cert client-cert.pem -key client-key.pem -CAfile ca-chain.pem \
      -verify_return_error </dev/null
    ```

    The command forces TLS 1.2 because a TLS 1.3 server can reject a client certificate after the handshake appears complete. With TLS 1.2, a rejected client certificate fails the handshake with an alert.

    <Check>
      The output shows `Verify return code: 0 (ok)` and no `alert` line. The **Acceptable client certificate CA names** list includes `CN=Client App TLS CA <number>`, the CA whose certificate is in the endpoint download.
    </Check>
  </Step>

  <Step title="Run one authenticated KMIP operation">
    Run the application's own key-server test, or use the PyKMIP client as a neutral KMIP client. To use PyKMIP, install it in a Python virtual environment:

    ```bash theme={null}
    python3 -m venv pykmip-venv
    . pykmip-venv/bin/activate
    pip install PyKMIP==0.11.0
    ```

    Create `pykmip.conf` with the endpoint files:

    ```ini theme={null}
    [client]
    host=cryptohub.example.com
    port=5696
    certfile=/path/to/client-cert.pem
    keyfile=/path/to/client-key.pem
    ca_certs=/path/to/ca-chain.pem
    cert_reqs=CERT_REQUIRED
    ssl_version=PROTOCOL_TLS
    do_handshake_on_connect=True
    suppress_ragged_eofs=True
    ```

    Omit the `username` and `password` options. Without them, PyKMIP sends no KMIP credential and authenticates with the client certificate alone.

    Send a KMIP `Locate` request:

    ```python theme={null}
    from kmip.pie.client import ProxyKmipClient

    client = ProxyKmipClient(config="client", config_file="pykmip.conf")
    with client:
        print(client.locate())
    ```

    PyKMIP verifies the server certificate chain against `ca-chain.pem`. It does not compare the server certificate with the host name. With `ssl_version=PROTOCOL_TLS`, PyKMIP negotiates TLS 1.3 with CryptoHub.

    <Check>
      The script prints a list of object identifiers. A new service can return an empty list, `[]`. An error or a closed connection means the operation failed.
    </Check>
  </Step>

  <Step title="Check key retrieval (applications that retrieve keys)">
    If the application retrieves key material, confirm that it can create and retrieve a key. This PyKMIP example creates a test AES-256 key and retrieves it.

    <Note>
      The example ends with a KMIP `Destroy` request for the test key only. Do not reuse its identifier for application keys.
    </Note>

    ```python theme={null}
    from kmip.core import enums
    from kmip.pie.client import ProxyKmipClient

    client = ProxyKmipClient(config="client", config_file="pykmip.conf")
    with client:
        uid = client.create(enums.CryptographicAlgorithm.AES, 256, name="kmip-connection-test")
        key = client.get(uid)
        print(uid, len(key.value) * 8)
        client.destroy(uid)
    ```

    Skip this step if the application uses only server-side operations. KMIP object names must be unique: if an earlier run stopped before the `Destroy` request, change the `name` value before you run the example again.

    <Check>
      The script prints an object identifier and `256`, and completes without an error.
    </Check>
  </Step>

  <Step title="Find the key in CryptoHub">
    In the CryptoHub web interface, open **Key Management** and select **Keys**. Select the key by name and open its **History** tab to see which endpoint identity created or retrieved it.

    KMIP secret data objects appear under **Classic Tools** > **Key Management** > **GO TO SECRETS**.

    <Check>
      The key's **History** tab lists the endpoint identity name under **Username(s)**.
    </Check>
  </Step>
</Steps>

## Troubleshooting

| Symptom | Cause and resolution |
| - | - |
| The TLS 1.2 check fails with `alert unknown ca`, `alert certificate unknown`, or `alert handshake failure` | CryptoHub did not accept the client certificate. Use `client-cert.pem` and the key from the same endpoint download, and confirm that the endpoint still exists in the service. If the files are lost or expired, create a new endpoint. |
| `Verify return code` is not `0 (ok)`, or the application reports an untrusted server certificate | The client does not trust the KMIP server certificate. Use `ca-chain.pem` from the endpoint download as the server CA. |
| The connection times out or is refused | A firewall, proxy, or TLS inspection device blocks TCP 5696. Allow TCP 5696 from the application host to CryptoHub and exempt it from TLS inspection. |
| An operation fails as unsupported | The CryptoHub KMIP server does not implement that operation or attribute. Record the operation name and contact Futurex support. |
