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

# Validate and test

> Step-by-step testing procedures using Ansible playbooks to validate integration via signing/verification examples.

This section demonstrates how to test the integration of Ansible with the Futurex﻿ PKCS#11 library and CryptoHub. This is done thorugh 2 SSH example and signing and verifying a sample `.txt` file. The example highlights the flexibility and increased security of keys stored on the CryptoHub, allowing Ansible to perform signing and verification operations instead of relying on password-based authentication.

## Ansible Playbooks

Ansible uses **Playbooks**, which are YAML-formatted files, to carry out automated tasks on a set of managed hosts. Within the Playbook file, you can use the Futurex PKCS #11 library to execute various functions by using the CryptoHub, including safeguarding, using SSH private keys, and signing data. For more information on Ansible Playbooks, see the Ansible

[**documentation**](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html).

## Inventory file

An inventory file in Ansible defines the hosts that Ansible will manage. It can list IP addresses, hostnames, and groupings of machines, allowing you to organize and target them in playbooks. The file can be written in INI or YAML format.**Example (INI format):**

```ini expandable lines wrap title="Ini" theme={null}
[local]
localhost ansible_connection=local
```

In the example above, `local`, is targeted for local execution, common in test setups.

The following examples demonstrate using Playbook:

## Testing Ansible integration with CryptoHub

### Prerequisites

Perform the following two tasks to create a key pair:

#### Set Futurex environment variables

Perform the following steps to set Futurex PKCS #11 environment variables:

In a terminal, run the following commands to set the required **FXPKCS11** environment variables:

```shell expandable lines wrap title="Shell" theme={null}
export FXPKCS11_MODULE=/path/to/libfxpkcs11.so;
```

<Note>
  Be sure to modify the file path to match the location where the `libfxpkcs11.so` is on your system.
</Note>

#### Generate a key pair

Perform the following steps by using the pkcs11-tool available from the OpenSC suite (

[**github.com/OpenSC/OpenSC**](https://github.com/OpenSC/OpenSC)) to generate keys. On both DEB-based and RPM-based distributions, the package is called `opensc`.

In a terminal, run the following command to create a new RSA key pair on the CryptoHub by using**pkcs11-tool**:

```text expandable lines wrap title="Text" theme={null}
pkcs11-tool --module $FXPKCS11_MODULE --login --keypairgen --key-type rsa:2048 --label "ansible_rsa" --id "123456" --usage-sign
```

The preceding**pkcs11-tool** command prompts for the user PIN. Enter the identity password configured inside the `<CRYPTO-OPR-PASS>` tag in the `fxpkcs11.cfg` file.

<Check>
  If successful, the command output lists the keys that pkcs11-tool created on the CryptoHub.
</Check>

#### For both SSH examples: Adding public key to SSH authorized keys

Before proceeding with the SSH example, the public key for `ansible_rsa` must be added to `/home/<target user>/.ssh/authorized_keys` on the target host. When the client initiates a connection, it queries the CryptoHub for its public keys, which are then sent to the server. The server checks its `authorized_keys` file to see if any of the public keys match. If a match is found, the server issues a challenge that the client must sign. The client passes this challenge to CryptoHub, which signs it using the corresponding private key. Once the server verifies the signature, the client is allowed to connect, eliminating the need for passwords entirely.

Perform the following steps to get the public key from CryptoHub, put it in a format that OpenSSH understands, and add it to the `authorized_keys` file:

<Steps>
  <Step>
    Get the pulic key from the `ansible_rsa` key pair and output the information to a `.der` file:

    ```shell expandable lines wrap title="Shell" theme={null}
    pkcs11-tool --module $FXPKCS11_MODULE -r --label ansible_rsa -y pubkey -o hsm_pubkey.der
    ```
  </Step>

  <Step>
    Convert the public key file from `.der` to `.pem`:

    ```shell expandable lines wrap title="Shell" theme={null}
    openssl rsa -pubin -inform DER -in hsm_pubkey.der -outform PEM -out hsm_pubkey.pem
    ```
  </Step>

  <Step>
    Re-encode the `.pem` file into **PKCS#8** so that OpenSSH can read the file:

    ```shell expandable lines wrap title="Shell" theme={null}
    ssh-keygen -i -m PKCS8 -f hsm_pubkey.pem > hsm_pubkey_ssh.pub
    ```
  </Step>

  <Step>
    Put the information in the `.pub` file in `authorized_keys`.
    If the SSH server is remote, first move the `.pub` file to the target destination before running this command:

    ```shell expandable lines wrap title="Shell" theme={null}
    cat hsm_pubkey_ssh.pub >> ~/.ssh/authorized_keys
    ```
  </Step>
</Steps>

### Use Futurex PKCS #11 with Ansible: Local SSH example

Perform the following steps to use Futurex PKCS #11 with Ansible for testing Ansible SSH on a local machine:

<Steps>
  <Step>
    Create a working directory for a new Ansible project and change into it:

    ```shell expandable lines wrap title="Shell" theme={null}
    mkdir ~/ansible_test_ssh && cd ~/ansible_test_ssh
    ```
  </Step>

  <Step>
    Create an inventory file.

    ```shell expandable lines wrap title="Shell" theme={null}
    nano inventory.ini
    ```

    Enter the following information for local SSH testing:

    ```ini expandable lines wrap title="Ini" theme={null}
    [local]
    localhost ansible_user=<name of user of local machine> ansible_host=localhost ansible_ssh_common_args='-I /path/to/libfxpkcs11.so'
    ```
  </Step>

  <Step>
    Create a playbook file `local_ssh_playbook.yml`:

    ```shell expandable lines wrap title="Shell" theme={null}
    nano local_ssh_playbook.yml
    ```
  </Step>

  <Step>
    The playbook file will test Ansible's SSH connection using the private key created on the CryptoHub in the previous section (**ansible\_rsa**).

    Enter the following information for local SSH testing with the playbook

    ```yaml expandable lines wrap title="YAML" theme={null}
    ---
    - name: Test Futurex HSM PKCS11 Integration - Local SSH example
      hosts: local
      gather_facts: false

      tasks:
        - name: Run a remote command
          ansible.builtin.command: hostname
          register: hostname_result

        - name: Show command output
          ansible.builtin.debug:
            msg: "Remote command output: {{ hostname_result.stdout }}"
    ```
  </Step>

  <Step>
    Run the following command to execute the playbook while referencing the private key stored on the HSM during the SSH connection step.

    ```text expandable lines wrap title="Text" theme={null}
    ansible-playbook -i inventory.ini local_ssh_playbool.yml 
    ```
  </Step>

  <Step>
    When prompted for the password of the user you are connecting to the machine with through SSH, enter it to complete the process.

    <Check>
      If successful, you see a response similar to the following:

      ```none expandable lines wrap title="None" theme={null}
      PLAY [Test Futurex HSM PKCS11 Integration - Local SSH example] *******
      TASK [Run a remote command] ***************************************
      Enter PIN for 'Futurex': 
      [WARNING]: sftp transfer mechanism failed on [localhost]. 
      Use ANSIBLEDEBUG=1 to see detailed information
      [WARNING]: scp transfer mechanism failed on [localhost]. 
      Use ANSIBLEDEBUG=1 to see detailed information
      changed: [localhost]

      TASK [Show command output]****************************************
      ok: [localhost] => {
          "msg": "Remote command output: General-Integration"
      }

      PLAY RECAP ***********************************************************
      localhost: ok=2    changed=1    unreachable=0    failed=0    
      skipped=0    rescued=0    ignored=0   
      ```

      The remote command output should match the hostname of your local machine.
    </Check>

    You can verify the successful pulling of the private key within the **FXPKCS11** log file.
  </Step>
</Steps>

### Use Futurex PKCS #11 with Ansible: Remote SSH example

<Steps>
  <Step>
    In the same directory as the example before, create a new inventory file.

    ```shell expandable lines wrap title="Shell" theme={null}
    nano remote_inventory.ini
    ```

    Enter the following information for remote SSH testing:

    ```ini expandable lines wrap title="Ini" theme={null}
    [remote_target]
    target ansible_user=<user of target server machine> ansible_host=<server IP> ansible_ssh_common_args='-I /path/to/libfxpkcs11.so'
    ```
  </Step>

  <Step>
    Create a playbook file `remote_ssh_playbook.yml`:

    ```shell expandable lines wrap title="Shell" theme={null}
    nano local_ssh_playbook.yml
    ```
  </Step>

  <Step>
    The playbook file will test Ansible's SSH connection using the private key created on the CryptoHub in the previous section (**ansible\_rsa**).

    Enter the following information for local SSH testing with the playbook

    ```yaml expandable lines wrap title="YAML" theme={null}
    ---
    - name: Test Futurex HSM PKCS11 Integration - Remote SSH example
      hosts: remote_target
      gather_facts: false

      tasks:
        - name: Ensure connectivity to target host
          ansible.builtin.ping:
          register: ping_result

        - name: Show ping result
          ansible.builtin.debug:
            msg: "SSH connection successful via PKCS#11! Result: {{ ping_result.ping }}"

        - name: Run a remote command
          ansible.builtin.command: hostname
          register: hostname_result

        - name: Show command output
          ansible.builtin.debug:
            msg: "Remote command output: {{ hostname_result.stdout }}"
    ```
  </Step>

  <Step>
    Run the following command to execute the playbook while referencing the private key stored on the HSM during the SSH connection step.

    ```text expandable lines wrap title="Text" theme={null}
    ansible-playbook -i remote_inventory.ini remote_ssh_playbool.yml 
    ```
  </Step>

  <Step>
    <Check>
      If successful, you see a response similar to the following:

      ```none expandable lines wrap title="None" theme={null}
      PLAY [Test Futurex HSM PKCS#11 Integration]***********************************************

      TASK [Ensure connectivity to target host] **********************************************
      Enter PIN for 'Futurex': 
      [WARNING]: sftp transfer mechanism failed on [10.40.20.10]. Use 
      ANSIBLEDEBUG=1 to see detailed information
      [WARNING]: scp transfer mechanism failed on [10.40.20.10]. Use 
      ANSIBLEDEBUG=1 to see detailed information
      [WARNING]: Platform linux on host target is using the discovered Python 
      interpreter at /usr/bin/python3.12, but future installation of another
      Python interpreter could change the meaning of that path. 
      See https://docs.ansible.com/ansible-core/2.16/referenceappendices/interpreterdiscovery.html for more information.
      ok: [target]

      TASK [Show ping result]****************************************************************
      ok: [target] => {
          "msg": "SSH connection successful via PKCS#11! Result: pong"
      }

      TASK [Run a remote command] ************************************************************
      changed: [target]

      TASK [Show command output] *************************************************************
      ok: [target] => {
          "msg": "Remote command output: Remote-Desktop"
      }

      PLAY RECAP ********************************************************************************
      target                     : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
      ```

      The remote command output should match the hostname of your target machine.
    </Check>

    You can verify the successful pulling of the private key within the **FXPKCS11** log file.
  </Step>
</Steps>

### Use Futurex PKCS #11 with Ansible: Signing data example

Perform the following steps to use Futurex PKCS #11 with Ansible: Signing data example:

<Steps>
  <Step>
    Create a working directory for a new Ansible project.

    ```text expandable lines wrap title="Text" theme={null}
    mkdir ~/ansible_test_sign && cd ~/ansible_test_sign
    ```
  </Step>

  <Step>
    Create an inventory file.

    ```text expandable lines wrap title="Text" theme={null}
    nano sign_inventory.ini
    ```

    The following example inventory file uses localhost:

    ```text expandable lines wrap title="Text" theme={null}
    [local]
    localhost ansible_user=<name of user of local machine> ansible_host=localhost
    ```
  </Step>

  <Step>
    Create a `sign_playbook.yml` file.

    ```text expandable lines wrap title="Text" theme={null}
    nano sign_verify_playbook.yml
    ```

    The following is an example Ansible Playbook file for signing data by using the private key created on the CryptoHub (`ansible_rsa`).

    ```yaml expandable lines wrap title="YAML" theme={null}
    ---
    - name: Test Futurex HSM PKCS11 Integration - Local sign and verify example
      hosts: localhost
      connection: local
      vars:
        module_path: /path/to/libfxpkcs11.so
        key_label: "ansible_rsa"
      vars_prompt:
        - name: hsm_pin
          prompt: "Enter HSM PIN"
          private: yes
      tasks:

        - name: Create sample data
          copy:
            dest: /tmp/data.txt
            content: "This is the message to be signed."

        - name: Sign data with CryptoHub (using pkcs11-tool)
          command: >
            pkcs11-tool --module "{{ module_path }}"
                        --sign --label "{{key_label}}"
                        --pin "{{ hsm_pin }}" -v
                        --mechanism SHA256-RSA-PKCS
                        --input-file /tmp/data.txt
                        --output-file /tmp/data.sig
          register: sign_result

        - name: Verify signature with public key (using OpenSSL)
          command: >
            pkcs11-tool --module "{{ module_path }}"
                        --login --pin "{{ hsm_pin }}"
                        --label "{{ key_label }}"
                        --verify
                        --mechanism SHA256-RSA-PKCS
                        --input-file /tmp/data.txt
                        --signature-file /tmp/data.sig
          register: verify_result
          ignore_errors: true

        - debug:
            msg:
              - "Verify result: {{ verify_result.stdout }}"
    ```

    * Replace **pkcs11\_module** with the location of the Futurex PKCS #11 library on your system.
  </Step>

  <Step>
    Run the following command to execute the playbook, while referencing the private key stored on the CryptoHub to perform the signing operation.

    ```text expandable lines wrap title="Text" theme={null}
    ansible-playbook -i sign_inventory.ini sign_verify_playbook.yml
    ```

    When prompted, enter the identity password configured inside the `<CRYPTO-OPR-PASS>` tag in the `fxpkcs11.cfg` file.
  </Step>

  <Step>
    <Check>
      If successful, you see a response similar to the following:

      ```none expandable lines wrap title="None" theme={null}
      Enter HSM PIN: 

      PLAY [Test Futurex HSM PKCS11 Integration - Local sign and verify example] ****************

      TASK [Gathering Facts]*****************************************************************
      ok: [localhost]

      TASK [Create sample data] **************************************************************
      ok: [localhost]

      TASK [Sign data with CryptoHub (using pkcs11-tool)] ************************************
      changed: [localhost]

      TASK [Verify signature with public key (using OpenSSL)] ********************************
      changed: [localhost]

      TASK [debug] ***************************************************************************
      ok: [localhost] => {
          "msg": [
              "Verify result: Signature is valid"
          ]
      }

      PLAY RECAP********************************************************************************
      localhost                  : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
      ```
    </Check>

    You can verify the signing operations within the **FXPKCS11** log file.
  </Step>
</Steps>
