

# Key management and usage with quorum authentication enabled for AWS CloudHSM using CloudHSM CLI
<a name="key-quorum-auth-chsm-cli-crypto-user"></a>

After you configure quorum authentication for your AWS CloudHSM cluster, crypto users can't perform HSM key management or usage operations on their own if their key has associated quorum values. This topic explains how a crypto-user can get a temporary token to perform an HSM key management or key usage operation.

**Note**  
Each quorum token is valid for one operation. When that operation succeeds, the token is no longer valid and the crypto-user must obtain a new token. A quorum token is only valid during your current login session. If you log out of the CloudHSM CLI or if the network disconnects, the token is no longer valid and you need to get a new token. You can only use a CloudHSM token within the CloudHSM CLI. You can't use it to authenticate in a different application.

The following example shows the output when a crypto-user tries to create a signature with a quorum-associated key on the HSM after quorum authentication is configured. The command fails with a `Quorum Failed` error, which means quorum authentication failed:

```
aws-cloudhsm > crypto sign rsa-pkcs --key-filter attr.label=rsa-private-key-example --hash-function sha256 --data YWJjMTIz
{
  "error_code": 1,
  "data": "Quorum Failed"
}
```

A crypto-user must complete the following tasks to get a temporary token for performing a key management or key usage operation on the HSM:

**Topics**
+ [Step 1. Get a quorum token](#key-quorum-admin-gen-token-chsm-cli)
+ [Step 2. Get signatures from approving crypto-users](#key-quorum-crypto-user-get-approval-signatures-chsm-cli)
+ [Step 3. Approve the token on the CloudHSM; cluster and execute an operation](#key-quorum-crypto-user-approve-token-chsm-cli)

## Step 1. Get a quorum token
<a name="key-quorum-admin-gen-token-chsm-cli"></a>

1. Start CloudHSM CLI.

------
#### [ Linux ]

   ```
   $ /opt/cloudhsm/bin/cloudhsm-cli interactive
   ```

------
#### [ Windows ]

   ```
   PS C:\> & "C:\Program Files\Amazon\CloudHSM\bin\cloudhsm-cli.exe" interactive
   ```

------

1. Log in to the cluster as a crypto-user.

   ```
   aws-cloudhsm > login --username {{<crypto_user1>}} --role crypto-user --password {{password123}}
   ```

   This example signs `crypto_user1` into the CloudHSM CLI with the `crypto-user` role. Replace these values with your own.

   ```
   {
     "error_code": 0,
     "data": {
       "username": "crypto_user1",
       "role": "crypto-user"
     }
   }
   ```

1. Generate a quorum token using the **quorum token-sign generate** command.

   In the following command, `key-usage` identifies the *service name* where you will use token that you are generating. In this case, the token is for key-usage operations (`key-usage` service) This example uses the `--filter` flag to associate the token with a specific key.

   ```
   aws-cloudhsm > quorum token-sign generate --service key-usage --token {{</path/crypto_user1.token>}} --filter attr.label=rsa-private-key-example
   {
     "error_code": 0,
     "data": {
       "path": "/home/crypto_user1.token"
     }
   }
   ```

   This example gets a quorum token for the crypto-user with username `crypto_user1` and saves the token to a file named `crypto_user1.token`. To use the example command, replace these values with your own:

   The **quorum token-sign generate** command generates a key-usage service quorum token at the specified file path. You can inspect the token file:

   ```
   $ cat {{</path/crypto_user1.token>}}
   {
     "version": "2.0",
     "service": "key-usage",
     "key_reference": "0x0000000000680006",
     "approval_data": "AAIABQAAABkAAAAAAGgABi5CDa9x9VyyRIaFbkSrHgJjcnlwdG9fdXNlcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnPQBLAAAAAAAAAAAAAgAFAAAAGgAAAAAAaAAGQvd2qKY+GJj8gXo9lKuANGNyeXB0b191c2VyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGc9AEsAAAAAAAAAAA==",
     "token": "5GlgoWOlQU4fw4QIlbxkPGZVOVoDugFGuSKE/k67ncM=",
     "signatures": []
   }
   ```

   The token file consists of the following:
   + **service**: An identifier for the quorum service the token is associated with.
   + **key\_reference**: An identifier for the key that this quorum token is associated with.
   + **approval\_data**: A base64 encoded raw data token generated by the HSM.
   + **token**: A base64 encoded and SHA-256 hashed token of the approval\_data
   + **signatures**: An array of base64 encoded signed tokens (signatures) of the unsigned token. Each approver signature is in the form of a JSON object literal: 

     ```
     {
           "username": "{{<APPROVER_USERNAME>}}",
           "role": "{{<APPROVER_ROLE>}}",
           "signature": "{{<APPROVER_RSA2048_BIT_SIGNATURE>}}"
     }
     ```

     Each signature is created from the result of an approver using their corresponding RSA 2048-bit private key whose public key was registered with the HSM.

1. Validate the new user service quorum token. The **quorum token-sign list** command confirms that the token exists on CloudHSM.

   ```
   aws-cloudhsm > quorum token-sign list
   {
     "error_code": 0,
     "data": {
       "tokens": [
         {
           "username": "crypto_user",
           "service": "key-usage",
           "key-reference": "0x0000000000680006",
           "minimum-token-count": 2
         }
       ]
     }
   }
   ```

   The `minimum-token-count` presents an aggregated cluster view of the minimum usable number of key tokens corresponding to the username, service, and key-reference that are retrieved from a single HSM in the cluster.

   For example, assuming a 2-HSM cluster, if we receive two (2) key-usage tokens generated by user `crypto_user1` for key with reference `0x0000000000680006` from the first HSM in the cluster and we receive one (1) key-usage tokens generated by user `crypto_user1` for key with reference `0x0000000000680006` from the other HSM in the cluster, we will display `"minimum-token-count": 1`.

## Step 2. Get signatures from approving crypto-users
<a name="key-quorum-crypto-user-get-approval-signatures-chsm-cli"></a>

An crypto user who has a quorum token must get the token approved by other crypto-users. To give their approval, the other crypto =-users use their signing key to cryptographically sign the token outside the HSM.

There are many different ways to sign the token. The following example shows how to sign the token using [OpenSSL](https://www.openssl.org/). To use a different signing tool, make sure that the tool uses the private key (signing key) of the crypto-user to sign a SHA-256 digest of the token.

In this example, the crypto-user that has the token (`crypto-user`) needs at least two (2) approvals. The following example commands show how two (2) crypto-users can use OpenSSL to cryptographically sign the token.

1. Decode the base64 encoded unsigned token and place it into a binary file:

   ```
   $echo -n '5GlgoWOlQU4fw4QIlbxkPGZVOVoDugFGuSKE/k67ncM=' | base64 -d > crypto_user1.bin
   ```

1. Use OpenSSL and the approver's private key to sign the binary quorum unsigned token for the user service and create a binary signature file:

   ```
   $openssl pkeyutl -sign \
   -inkey crypto_user1.key \
   -pkeyopt digest:sha256 \
   -keyform PEM \
   -in crypto_user1.bin \
   -out crypto_user1.sig.bin
   ```

1. Encode the binary signature into base64:

   ```
   $ base64 -w0 crypto_user1.sig.bin > crypto_user1.sig.b64
   ```

1. Copy and paste the base64 encoded signature into the token file, using the JSON object literal format specified earlier for approver signature:

   ```
   {
     "version": "2.0",
     "service": "key-usage",
     "key_reference": "0x0000000000680006",
     "approval_data": "AAIABQAAABkAAAAAAGgABi5CDa9x9VyyRIaFbkSrHgJjcnlwdG9fdXNlcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnPQBLAAAAAAAAAAAAAgAFAAAAGgAAAAAAaAAGQvd2qKY+GJj8gXo9lKuANGNyeXB0b191c2VyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGc9AEsAAAAAAAAAAA==",
     "token": "5GlgoWOlQU4fw4QIlbxkPGZVOVoDugFGuSKE/k67ncM=",
     "signatures": [
       {
         "username": "crypto_user1",
         "role": "crypto-user",
         "signature": "wa7aPzmGwBjcEoZ6jAzYASp841AfgOvcI27Y/tGlCj1E9DawnFw5Uf0IJT2Ca7T5XD2ThVkUi0B+dhAomdqYNl6aUUFrJyH9GBJ+E0PmA5jNVm25tzeRWBJzneTg4/zTeE2reNqrHFHicWnttQLe9jS09J1znuDGWDe0HaBKWUaz2gUInJRqmeXDsZYdSvZksrqUH5dci/RsaDE2+tGiS9g0RcIkFbsPW4HpGe2e5HVzGsqrV8O3PKlYQv6+fymfcNTTuoxKcHAkOjpl43QSuSIu2gVq7KI8mSmmWaPJL47NPjmcBVB5vdEQU+oiukaNfLJr+MoDKzAvCGDg4cDArg=="
       },
       {
         "username": "crypto_user2",
         "role": "crypto-user",
         "signature": "wa7aPzmGwBjcEoZ6jAzYASp841AfgOvcI27Y/tGlCj1E9DawnFw5Uf0IJT2Ca7T5XD2ThVkUi0B+dhAomdqYNl6aUUFrJyH9GBJ+E0PmA5jNVm25tzeRWBJzneTg4/zTeE2reNqrHFHicWnttQLe9jS09J1znuDGWDe0HaBKWUaz2gUInJRqmeXDsZYdSvZksrqUH5dci/RsaDE2+tGiS9g0RcIkFbsPW4HpGe2e5HVzGsqrV8O3PKlYQv6+fymfcNTTuoxKcHAkOjpl43QSuSIu2gVq7KI8mSmmWaPJL47NPjmcBVB5vdEQU+oiukaNfLJr+MoDKzAvCGDg4cDArg=="
       }
     ]
   }
   ```

## Step 3. Approve the token on the CloudHSM; cluster and execute an operation
<a name="key-quorum-crypto-user-approve-token-chsm-cli"></a>

After a crypto-user has the necessary approvals and signatures, they can supply that token to the CloudHSM cluster along with a key management or key usage operation. 

Make sure the key operation corresponds to the appropriate quorum service associated with the quorum token. For more information, see [Supported services and types](key-quorum-auth-chsm-cli-service-names.md) for more information.

During the transaction, the token will be approved within the AWS CloudHSM cluster and execute the requested key operation. The success of the key operation is contingent upon both a valid approved quorum token and a valid key operation.

**Example Generate a signature with the RSA-PKCS mechanism**  
In the following example, a logged in crypto-user creates a signature with a key on the HSM:  

```
aws-cloudhsm > crypto sign rsa-pkcs --key-filter attr.label=rsa-private-key-example --hash-function sha256 --data YWJjMTIz --approval /path/crypto_user1.token
      
{
  "error_code": 0,
  "data": {
    "key-reference": "0x0000000000640007",
    "signature": "h6hMqXacBrT3x3MXV13RXHdQno0+IQ6iy0kVrGzo23+eoWT0ZZgrSpBCu5KcuP6IYYHw9goQ5CfPf4jI1nO5m/IUJtF1A1lmcz0HjEy1CJ7ICXNReDRyeOU8m43dkJzt0OUdkbtkDJGAcxkbKHLZ02uWsGXaQ8bOKhoGwsRAHHF6nldTXquICfOHgSd4nimObKTqzUkghhJW5Ot5oUyLMYP+pZmUS38ythybney94Wj6fzYOER8v7VIY5ijQGa3LfxrjSG4aw6QijEEbno5LSf18ahEaVKmVEnDBL54tylCJBGvGsYSY9HNhuJoHPgiDL/TDd2wfvP4PaxbFRyyHaw=="
  }
}
```
If the crypto user tries to perform another HSM key usage operation with the same token, it fails:  

```
aws-cloudhsm > crypto sign rsa-pkcs --key-filter attr.label=rsa-private-key-example --hash-function sha256 --data YWJjMTIz --approval /home/crypto_user1.token
{
  "error_code": 1,
  "data": "Quorum approval is required for this operation"
}
```
To perform another HSM key operation, the crypto user must generate a new quorum token, get new signatures from approvers, and execute the desired key operation with the --approval argument to supply the quorum token.  
Use the **quorum token-sign list** to check for available token. This example shows that the crypto-user has no approved tokens.   

```
aws-cloudhsm > quorum token-sign list
{
  "error_code": 0,
  "data": {
    "tokens": []
  }
}
```