Clients: Sequoia-PGP

(DSM) integrates with Sequoia-PGP, a modern implementation of the OpenPGP Message Format. Sequoia has a CLI tool called sq with git-like commands for PGP operations, which are extended by sq-dsm to communicate with Fortanix DSM whenever a sensitive cryptographic operation is needed (more specifically, when signing a hash or decrypting a session key).

For details on the Sequoia PGP client OS compatibility matrix, refer to Clients: Compatibility Matrix.

The Fortanix sq-dsm library for all platforms can be downloaded and installed from here.

Set the following environment variables:

  • FORTANIX_API_ENDPOINT, your DSM endpoint.

  • FORTANIX_API_KEY, your application’s (app) API key. It overrides FORTANIX_PKCS12_ID.

  • FORTANIX_PKCS12_ID, a PKCS12 identity file, for certificate-based authentication. Given a PKCS8 pair private.key and public.crt, the public certificate needs to be configured in Fortanix DSM for your app, and the PKCS12 file can be generated with the following command.

    openssl pkcs12 -export -out identity.pfx -inkey private.key -in public.crt
    Bash

    If a password is set for the PKCS12 file, then sq-dsm will ask for it on each key usage (which can happen several times on one PGP operation).

  • FORTANIX_APP_UUID, the UUID of your DSM app, for certificate-based authentication (for example, this environment variable is used together with FORTANIX_PKCS12_ID).

  • (Optional) http_proxy and/or no_proxy.

The binary can be invoked with ./sq-dsm and can be composed with several commands. They can be listed with:

sq-dsm help
Bash

More information about a specific command is obtained with sq-dsm help <command>, for instance, sq-dsm help decrypt.

In the following example, Alice holds a PGP key whose secrets are stored in Fortanix DSM, and Bob and Charlie hold regular PGP keys. Alice will sign, encrypt, and decrypt a file.

  1. Generate a Fortanix DSM key for Alice, and local keys for Bob and Charlie.

    sq-dsm key generate --dsm-key="alice" --cipher-suite="nistp521" --userid="Alice <alice@example.com>"
    sq-dsm key generate --cipher-suite="rsa3k" --userid="Bob <bob@example.com>" --export="bob.sec"
    sq-dsm key generate --userid="Charlie <charlie@example.com>" --export="charlie.asc"
    
    Bash
  2. Recover Alice's Transferable Public Key (TPK).

    sq-dsm key extract-cert --dsm-key="alice" > alice.asc
    
    Bash
  3. Create a file, sign it with Alice's key, and verify it.

    echo "Hello, World!" > msg.txt
    
    sq-dsm sign --dsm-key="alice" msg.txt > msg.txt.signed
    
    sq-dsm verify --signer-cert=alice.asc msg.txt.signed
    
    Good signature from B4C961DE2204FD02
    Hello, World!
    1 good signature.
    
    Bash
  4. Encrypt a file to Alice, signed by Bob, and decrypt it.

    sq-dsm encrypt --recipient-cert=alice.asc --signer-key=bob.sec msg.txt > to_alice.asc
    sq-dsm decrypt --dsm-key="alice" --signer-cert=bob.sec to_alice.asc
    
    Encrypted using AES with 256-bit key
    Compressed using ZIP
    Good signature from DC4358B3EA20F2C6
    Hello, World!
    1 good signature.
    
    Bash
  5. Encrypt a file to Charlie, signed by both Alice and Bob, and decrypt it.

    sq-dsm encrypt --recipient-cert=charlie.asc --signer-dsm-key=alice --signer-key=bob.sec msg.txt > to_charlie.asc
    sq-dsm decrypt --recipient-key=charlie.asc --signer-cert=alice.asc --signer-cert=bob.sec to_charlie.asc
    
    Encrypted using AES with 256-bit key
    Compressed using ZIP
    Good signature from B4C961DE2204FD02
    Good signature from DC4358B3EA20F2C6
    Hello, World!
    2 good signatures.
    
    Bash

Given a valid PGP key, you can import it into Fortanix DSM with the dsm-import sub-command:

sq-dsm key dsm-import --dsm-key="Alice" < existing_pgp_private_key.asc
Bash

By default, the command to generate keys as explained in Section 5.1 - Example Usage: Signed Encryption of a File generates keys using the following structure.

Primary key: Certification
Subkey 1: Signing
Subkey 2: Encryption (transport & rest)
Bash

With the introduction of a new flag --key-flags, you can choose from one of the following two structures used for key generation.

  • --key-flags="C,S,EtEr" will generate the keys using the above-mentioned structure and this is also the default behavior (if the flag --key-flags is not specified).

  • --key-flags="CS,EtEr" will generate keys using the following structure:

    Primary key: Certification + Signing
    Subkey: Encryption (transport & rest)
    Bash

Given a valid Transferable Public Key (TPK), you can import it into Fortanix DSM using the dsm-import sub-command:

sq-dsm key dsm-import --dsm-key="Alicepubkey" --input alice_public_key.asc
Bash

To retrieve the TPK from Fortanix DSM, run the extract-cert sub-command:

sq-dsm key extract-cert --dsm-key="Alicepubkey" > retrieved_alice_public_key.asc
Bash

When generating or importing a new key using the Sequoia client, the key is always created in the app's default group.

Run the following commands to generate or import a key into a group other than the default:

  • Retrieve all groups associated with the app:

    sq-dsm key list-dsm-groups
    Bash

    Example Output:

    UUID                                  Date Created             Name
    4080f492-xxxx-xxxx-xxxx-xxxxxxxxxxxx  2024-09-24 09:35:09 UTC  group1
    8e86e18e-xxxx-xxxx-xxxx-xxxxxxxxxxxx  2024-08-10 12:06:24 UTC  group2
    bea46106-xxxx-xxxx-xxxx-xxxxxxxxxxxx  2023-08-21 09:23:23 UTC  group3
    f2a10673-xxxx-xxxx-xxxx-xxxxxxxxxxxx  2023-11-02 08:31:17 UTC  group4
    f3645b2b-xxxx-xxxx-xxxx-xxxxxxxxxxxx  2025-01-25 07:53:48 UTC  group5
    
    TOTAL GROUPS: 5
    Bash
  • Generate the key in the specified group (--dsm-group-id <GROUP UUID>):

    sq-dsm key generate --dsm-key="alice" --cipher-suite="nistp521" --userid="Alice <alice@example.com>" --dsm-group-id f3645b2b-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    Bash
  • Import the key into the specified group (--dsm-group-id <GROUP UUID>):

    sq-dsm key dsm-import --dsm-key="Alice" --dsm-group-id f3645b2b-xxxx-xxxx-xxxx-xxxxxxxxxxxx < existing_pgp_private_key.asc 
    Bash

You can provide custom metadata when creating or importing a key in the Sequoia client.

Run the following commands to generate or import a key with custom metadata:

  • Generate the key with custom metadata (--custom-metadata <key1=value1>):

    sq-dsm key generate --dsm-key="alice" --cipher-suite="nistp521" --userid="Alice <alice@example.com>" --custom-metadata testkey1=testvalue1 --custom-metadata testkey2=testvalue2
    Bash

    Here, testkey1=testvalue1 and testkey2=testvalue2 are the custom metadata key-value pairs.

  • Import the key with custom metadata (--custom-metadata <key1=value1>):

    sq-dsm key dsm-import --dsm-key="Alice" --custom-metadata testkey1=testvalue1 --custom-metadata testkey2=testvalue2 < existing_pgp_private_key.asc
    Bash

    Here, testkey1=testvalue1 and testkey2=testvalue2 are the custom metadata key-value pairs.

The custom metadata key-value pairs will be added to the sq_dsm_user_metadata field in the Custom attributes section of the security object page on the Fortanix DSM user interface (UI).

Figure 1: Custom Metadata Details on the Fortanix DSM UI

NOTE

Run the following command to retrieve the key details:

sq-dsm key info --dsm-key="<DSM KEY NAME>"
Bash

Example Output:

<DSM KEY NAME>:
    UUID: 0ce121b1-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    Group ID: f3645b2b-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    Object Type: Rsa
    Created at: 2025-03-21 03:32:02 UTC
    Last used at: NA
    PGP fingerprint: 10BFF49131xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    Custom Metadata: {
    "sq_dsm": "{\"sq_dsm_version\":\"1.8.0\",\"fingerprint\":\"10BFF49131xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\"key_flags\":{\"raw\":[1]},\"certificate\":\"-----BEGIN PGP PUBLIC KEY BLOCK-----\\nComment: 10BF F491 3103 FA5F DD26  1406 6A2B FCE2 5542 3469\\nComment: Alice <alice@openpgp.example>\\n\\nxsBNBGfc3bIBCAC<CERT_DATA>V34h\n+eif0vP+v\\n-----END PGP PUBLIC KEY BLOCK-----\\n\"}",
    "sq_dsm_user_metadata": "{\"testkey1\":\"testvalue1\",\"testkey2\":\"testvalue2\"}",
}
Bash

See the test runs on the Fortanix GitHub repository for more example usages, such as exporting secrets and importing them into a local gpg keyring.

Crypto

Algorithm

Parameters

Use

Symmetric

Preferred Algorithms: AES128 / AES256

Data Encryption

Hash

Preferred Algorithms: SHA256 / SHA512

OpenPGP Data Hashing

Asymmetric Encryption

RSA

Supported Key Sizes:

rsa2k[2048]

rsa3k[3072]

rsa4k[4096]

rsa8k[8192]

OpenPGP Session Key Encryption

Key Agreement

ECDH, X25519

Supported Curves:

nistp256

nistp384

nistp521
Curve25519

OpenPGP Session Key Agreement

Key Derivation Function (KDF)

Iterated and Salted S2K (String-to-Key)

OpenPGP Session Key Derivation

Signature

ECDSA, EdDSA

Supported Curves:

nistp256

nistp384

nistp521

Edwards25519

OpenPGP Data Signing

RSA

Supported Key Sizes:

rsa2k[2048]

rsa3k[3072]

rsa4k[4096]

rsa8k[8192]

ERROR

REASON

RESOLUTION

environment variable not found

NA

Set FORTANIX_API_ENDPOINT and FORTANIX_API_KEY

Error: could not create primary key

Authentication failed. Neither the HTTP basic header nor the client certificate was provided.

Ensure that the API key is correct (env | grep FORTANIX). If you are using an http proxy, also make sure that the http_proxy is set, and the DSM API endpoint is not in the no_proxy list (env | grep proxy).

Error: could not create primary key

Connection refused (os error 111).

Ensure that the proxy is reachable, and check the proxy logs.

Error: could not create primary key

sobject already exists.

Use a different name, for example, use a different value for the --dsm-key option.

Error: dsm client could not create sobject

Error: Given RSA key policy not allowed by policy

Ensure that the RSA Padding policy allows PKCS1v15, as dictated by RFC4880bis.

The user is experiencing random errors during decryption with GnuPG, RNP, and similar tools.
For example,
gpg: handle plaintext failed: Unexpected error
or gpg: packet(13) too large, and so on.

There may be compatibility issues when using GnuPG, RNP, and similar tools to handle messages encrypted with the Fortanix Sequoia PGP client.

Fortanix DSM suggests opting for one of the following padding methods instead of using the default padding (pad) for encryption:

  • zip

  • zlib

  • bzip2

  • none

For example, you can use the following command for encryption:

sq-dsm encrypt --recipient-cert=alice.asc --signer-key=bob.sec --compression zip msg.txt > to_alice.asc
Bash

For details on Sequoia PGP client changelog, refer to Sequoia PGP - Changelog.

For more details about PGP, refer to the blog PGP with secrets in the cloud.