> Markdown version of https://docs.laavat.io/exampleflows/habsigning/ from the LAAVAT PKI and Signing Platform documentation. All pages: https://docs.laavat.io/llms.txt

# HAB usage example

> **Tip: Looking for the full i.MX8M boot chain?**
> This page walks through signing SPL and FIT images with the HAB tree. For
> the complete i.MX8M design — HAB from ROM, a signed kernel FIT, OP-TEE
> Trusted Applications and RAUC update bundles — see
> [Building CRA-ready i.MX8M gateways](https://docs.laavat.io/solutions/cra-ready-imx8m/).

This example shows how to create a product which enables SPL and FIT image signing. Also example signing operations are performed.

SPL signing uses the **SignHAB** operation — NXP CST (Code Signing Tool) based HAB (High Assurance Boot) signing, also covered in the [CST signing](https://docs.laavat.io/usage/signing-encryption/cstsigning/) reference.

This example uses the reference python client and the UI to perform different actions.

The example is divided into the following stages:

- How to get authentication token
- Adding certificate profiles
- Creating product
- Getting the sensitive items.
- Signing SPL images
- Signing FIT images

## Authentication

In order to use the reference python client a valid JWT token is needed. How to obtain one is explained in more detail in the [authentication chapter.](https://docs.laavat.io/api/authentication/)
New token must be requested if the current token expires. ( roughly 1 hour of validity)

```bash
(venv) $ az login --allow-no-subscriptions --only-show-error
A web browser has been opened at https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize. Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with `az login --use-device-code`.

[1]    N/A(tenant level account)  <redacted>  <redacted>

The default is marked with an *; the default tenant is '<redacted>' and subscription is 'N/A(tenant level account)' (<redacted>).

Select a subscription and tenant (Type a number or Enter for no changes): 1

Tenant: <redacted>
Subscription: N/A(tenant level account) (<redacted>)


(venv) $ az account get-access-token --resource api://<redacted>
{
  "accessToken": "<redacted>",
  "expiresOn": "2025-06-04 15:18:10.000000",
  "expires_on": 1749039490,
  "subscription": "<redacted>",
  "tenant": "<redacted>",
  "tokenType": "Bearer"
}
(venv) $ export TOKEN=<redacted>
```

## Add profiles

> **Note: Token handling in these examples**
> The `signing-tool` commands below use `-n test.ini` — a config file created with `config-init` that references
> a `token_file` rather than embedding a token, so no token appears on the command line. Approver steps use `-n
> approver.ini` (the same config for a user in the approvers group). See [Reference Client ›
> Usage](https://docs.laavat.io/democlient/usage/) for how to create these configs and for the secure token-input forms (`-t
> @file`, `-t @-`).

HAB related signing is using a HAB tree which consists in this example of four SRK{0...3} roots and related End-Entity certificates.

The [example profiles](https://docs.laavat.io/usage/productguide/pki-examples/#example-of-ahab-profiles) were taken as base and modified for this example

```bash
(venv) $ signing-tool -n test.ini profile \
    add -F rootca.yaml -N "Customer HAB Root CA" -T ROOT
{
    "id": "80ebbcc7-d0d9-4f44-be75-618d93e710b9",
    "profile_name": "Customer HAB Root CA",
    "profile_type": 3,
    "profile_yaml": "IyBDb25maWcg…(3,384 base64 chars elided; text, shown decoded below as value 1 of 2)"
}
Profile added. Profile ID: 80ebbcc7-d0d9-4f44-be75-618d93e710b9

(venv) $ signing-tool -n test.ini profile \
    add -F endentity.yaml -N "Customer HAB tree endentity" -T END
{
    "id": "747f5d21-251b-4074-9bd2-9304c072286a",
    "profile_name": "Customer HAB tree endentity",
    "profile_type": 1,
    "profile_yaml": "IyBDb25maWcg…(3,280 base64 chars elided; text, shown decoded below as value 2 of 2)"
}
Profile added. Profile ID: 747f5d21-251b-4074-9bd2-9304c072286a

(venv) $ signing-tool -n test.ini profile getall
{
    "count": 2,
    "items": [
        {
            "id": "80ebbcc7-d0d9-4f44-be75-618d93e710b9",
            "profile_name": "Customer HAB Root CA",
            "profile_type": 3
        },
        {
            "id": "747f5d21-251b-4074-9bd2-9304c072286a",
            "profile_name": "Customer HAB tree endentity",
            "profile_type": 1
        }
    ],
    "next": "/cas/profiles/?page=1",
    "pages": 1,
    "prev": "/cas/profiles/?page=1"
}
```

Decoded base64 value 1 of 2:

```text
# Config file for the Root profile. Do not use TABS
# Do not modify the CommonName if this is used as HAB CA.
---
Name: NXP i.MX6 HABv4 Root CA Profile
# Distinguished name of the CA
DN:
  Organization: Customer
  # OrganizationalUnit: 
  # Country: FI
  # Province:
  # Locality:
  # StreetAddress:
  # PostalCode:
  # SerialNumber
  # CommonName: HAB Root CA
# EndEntity is 1, Sub CA profile 2 , Root profile 3
ProfileType: 3
# SignatureAlgorithms
#  SHA1WithRSA = 3
#  SHA256WithRSA = 4
#  SHA384WithRSA = 5
#  SHA512WithRSA = 6
#  DSAWithSHA1 = 7
#  DSAWithSHA256 = 8
#  ECDSAWithSHA1 = 9
#  ECDSAWithSHA256 = 10
#  ECDSAWithSHA384 = 11
#  ECDSAWithSHA512 = 12
#  SHA256WithRSAPSS = 13
#  SHA384WithRSAPSS = 14
#  SHA512WithRSAPSS = 15
SignatureAlgorithm: 4
# KeyAlgorithms
#   RSAAlgorithm = 1
#   ECDSAAlgorithm = 2
KeyAlgorithm: 1
# Validity of the certificate in duration (max 290 years) or with absolute date in RFC3339 e.g. 9999-12-31T23:59:59Z.
# Example in absolute date "9999-12-31T23:59:59Z".
# Example in duration "1h10m10s". Only h, m and/or s are accepted.
ValidityPeriod: "1752000h" # 200 Years
BasicConstraints:
  BasicConstraintsValid: true
  IsCA: true
  MaxPathLen: 0
  # MaxPathLenZero indicates that BasicConstraintsValid==true
  # and MaxPathLen==0 should be interpreted as an actual
  # maximum path length of zero. Otherwise, that combination is
  # interpreted as MaxPathLen not being set.
  MaxPathLenZero: false
AddSKI: true
AddAKI: true
# KeyUsages
#  KeyUsageDigitalSignature = 1
#  KeyUsageContentCommitment = 2
#  KeyUsageKeyEncipherment = 4
#  KeyUsageDataEncipherment = 8
#  KeyUsageKeyAgreement = 16
#  KeyUsageCertSign = 32 
#  KeyUsageCRLSign = 64
#  KeyUsageEncipherOnly = 128
#  KeyUsageDecipherOnly = 256
KeyUsage:
  - 32
ExtendedKeyUsage:
  # ExtendedKeyUsages
  #  ExtKeyUsageAny = 0
  #  ExtKeyUsageServerAuth = 1
  #  ExtKeyUsageClientAuth = 2
  #  ExtKeyUsageCodeSigning = 3
  #  ExtKeyUsageEmailProtection = 4
  #  ExtKeyUsageIPSECEndSystem = 5
  #  ExtKeyUsageIPSECTunnel = 6
  #  ExtKeyUsageIPSECUser = 7
  #  ExtKeyUsageTimeStamping = 8
  #  ExtKeyUsageOCSPSigning = 9
  #  ExtKeyUsageMicrosoftServerGatedCrypto = 10
  #  ExtKeyUsageNetscapeServerGatedCrypto = 11
  #  ExtKeyUsageMicrosoftCommercialCodeSigning = 12
  #  ExtKeyUsageMicrosoftKernelCodeSigning = 13
# ExtraExtensions: true
# SANUsage: true
# CRLDistributionPoints. List of URI strings.
#CRLDistributionPoints:

# PolicyIdentifiers. List of ASN1 policy OIDS
#PolicyIdentifiers:
#  - 1.10.123.432.4.5
#  - 2.10.123.432.4.65
```

Decoded base64 value 2 of 2:

```text
# Config file for the End entity profile. Do not use TABS
# Do not modify the CommonName if this is used as End Entity Certificate and the Common Name comes from the product template.
---
Name: NXP i.MX6 HABv4 EndEntity Profile
DN:
  Organization: Customer
  # OrganizationalUnit: R&D
  # Country: FI
  # Province:
  #- Something
  # Locality:
  # StreetAddress:
  # PostalCode:
  # SerialNumber
  # CommonName: IMG
# EndEntity is 1, Sub CA profile 2 , Root profile 3
ProfileType: 1
# SignatureAlgorithms
#  SHA1WithRSA = 3
#  SHA256WithRSA = 4
#  SHA384WithRSA = 5
#  SHA512WithRSA = 6
#  DSAWithSHA1 = 7
#  DSAWithSHA256 = 8
#  ECDSAWithSHA1 = 9
#  ECDSAWithSHA256 = 10
#  ECDSAWithSHA384 = 11
#  ECDSAWithSHA512 = 12
#  SHA256WithRSAPSS = 13
#  SHA384WithRSAPSS = 14
#  SHA512WithRSAPSS = 15
SignatureAlgorithm: 4
# KeyAlgorithms
#   RSAAlgorithm = 1
#   ECDSAAlgorithm = 2
KeyAlgorithm: 1
# Validity of the certificate in duration (max 290 years) or with absolute date in RFC3339 e.g. 9999-12-31T23:59:59Z.
# Example in absolute date "9999-12-31T23:59:59Z".
# Example in duration "1h10m10s". Only h, m and/or s are accepted.
ValidityPeriod: "1752000h" # 200 Years
BasicConstraints:
  Use: true
  IsCA: false
AddSKI: true
AddAKI: true
# KeyUsages
#  KeyUsageDigitalSignature = 1
#  KeyUsageContentCommitment = 2
#  KeyUsageKeyEncipherment = 4
#  KeyUsageDataEncipherment = 8
#  KeyUsageKeyAgreement = 16
#  KeyUsageCertSign = 32 
#  KeyUsageCRLSign = 64
#  KeyUsageEncipherOnly = 128
#  KeyUsageDecipherOnly = 256
KeyUsage: 
  - 1
ExtendedKeyUsage:
  # ExtendedKeyUsages
  #  ExtKeyUsageAny = 0
  #  ExtKeyUsageServerAuth = 1
  #  ExtKeyUsageClientAuth = 2
  #  ExtKeyUsageCodeSigning = 3
  #  ExtKeyUsageEmailProtection = 4
  #  ExtKeyUsageIPSECEndSystem = 5
  #  ExtKeyUsageIPSECTunnel = 6
  #  ExtKeyUsageIPSECUser = 7
  #  ExtKeyUsageTimeStamping = 8
  #  ExtKeyUsageOCSPSigning = 9
  #  ExtKeyUsageMicrosoftServerGatedCrypto = 10
  #  ExtKeyUsageNetscapeServerGatedCrypto = 11
  #  ExtKeyUsageMicrosoftCommercialCodeSigning = 12
  #  ExtKeyUsageMicrosoftKernelCodeSigning = 13
ExtraExtensions: true
SANUsage: true
# CRLDistributionPoints. List of URI strings.
#CRLDistributionPoints:

# PolicyIdentifiers. List of ASN1 policy OIDS
#PolicyIdentifiers:
#  - 1.10.123.432.4.5
#  - 2.10.123.432.4.65

# EnforceUniqueDN enables the checking if a certificate has been issued with the same subject DN from the CA
# Values true or false
#EnforceUniqueDN: true
```

## Create product

Here is the used [product template](https://docs.laavat.io/usage/productguide/product/#imx6-based-gateway-product). 
The product template was updated with the profile ids obtained from the previous commands. The values $ROOTPROFILEID, $ENDPROFILEID were changed with their corresponding profile id.

- ROOTPROFILEID=80ebbcc7-d0d9-4f44-be75-618d93e710b9
- ENDPROFILEID=747f5d21-251b-4074-9bd2-9304c072286a

In this product there are three operations. **SignHAB** performs CST-based HAB signing (used for the SPL here); **SignUBoot** and **SignKernel** sign FIT images using U-Boot's own verified-boot signatures, each with its own key. The approval rules are decided to be the same for each one.
In the approval rule it was decided that entities in the $WRITERGROUP were able to make signing requests. And entities in the $APPROVERGROUP group would be able to approve those. Autoapproval was not used.

$WRITERGROUP and $APPROVERGROUP were replaced with the corresponding Group Object ID from Microsoft Entra.

The template was saved as product.json.

More information about rules can be found from [approval rules.](https://docs.laavat.io/usage/productguide/product/#approval-rules)

Product was created using the python tool

```bash
(venv) $ signing-tool -n test.ini product add -T product.json 
Product:
{
    "ca_info": [
        {
            "cert_override_payload": null,
            "certificate_type": "ROOT",
            "cn": "SRK0",
            "crl_distribution_points": null,
            "crl_expiry": null,
            "crl_issue_interval": null,
            "csr": null,
            "description": "CA used for i.MX6 HAB",
            "external_request_id": null,
            "external_root": null,
            "id": null,
            "issuer_ca_id": null,
            "key_override_id": null,
            "key_type": "RSA4096",
            "leafs": [
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "CSF0",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "CSF End-Entity certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": null,
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "747f5d21-251b-4074-9bd2-9304c072286a",
                    "state": null,
                    "use_case": "HABCA"
                },
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "IMG0",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "IMG signing certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": null,
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "747f5d21-251b-4074-9bd2-9304c072286a",
                    "state": null,
                    "use_case": "HABCA"
                }
            ],
            "originating_id": null,
            "policy_identifiers": null,
            "product_id": null,
            "profile_id": "80ebbcc7-d0d9-4f44-be75-618d93e710b9",
            "state": null,
            "use_case": "HABCA"
        },
        {
            "cert_override_payload": null,
            "certificate_type": "ROOT",
            "cn": "SRK1",
            "crl_distribution_points": null,
            "crl_expiry": null,
            "crl_issue_interval": null,
            "csr": null,
            "description": "CA used for i.MX6 HAB",
            "external_request_id": null,
            "external_root": null,
            "id": null,
            "issuer_ca_id": null,
            "key_override_id": null,
            "key_type": "RSA4096",
            "leafs": [
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "CSF1",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "CSF End-Entity certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": null,
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "747f5d21-251b-4074-9bd2-9304c072286a",
                    "state": null,
                    "use_case": "HABCA"
                },
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "IMG1",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "IMG signing certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": null,
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "747f5d21-251b-4074-9bd2-9304c072286a",
                    "state": null,
                    "use_case": "HABCA"
                }
            ],
            "originating_id": null,
            "policy_identifiers": null,
            "product_id": null,
            "profile_id": "80ebbcc7-d0d9-4f44-be75-618d93e710b9",
            "state": null,
            "use_case": "HABCA"
        },
        {
            "cert_override_payload": null,
            "certificate_type": "ROOT",
            "cn": "SRK2",
            "crl_distribution_points": null,
            "crl_expiry": null,
            "crl_issue_interval": null,
            "csr": null,
            "description": "CA used for i.MX6 HAB",
            "external_request_id": null,
            "external_root": null,
            "id": null,
            "issuer_ca_id": null,
            "key_override_id": null,
            "key_type": "RSA4096",
            "leafs": [
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "CSF2",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "CSF End-Entity certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": null,
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "747f5d21-251b-4074-9bd2-9304c072286a",
                    "state": null,
                    "use_case": "HABCA"
                },
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "IMG2",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "IMG signing certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": null,
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "747f5d21-251b-4074-9bd2-9304c072286a",
                    "state": null,
                    "use_case": "HABCA"
                }
            ],
            "originating_id": null,
            "policy_identifiers": null,
            "product_id": null,
            "profile_id": "80ebbcc7-d0d9-4f44-be75-618d93e710b9",
            "state": null,
            "use_case": "HABCA"
        },
        {
            "cert_override_payload": null,
            "certificate_type": "ROOT",
            "cn": "SRK3",
            "crl_distribution_points": null,
            "crl_expiry": null,
            "crl_issue_interval": null,
            "csr": null,
            "description": "CA used for i.MX6 HAB",
            "external_request_id": null,
            "external_root": null,
            "id": null,
            "issuer_ca_id": null,
            "key_override_id": null,
            "key_type": "RSA4096",
            "leafs": [
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "CSF3",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "CSF End-Entity certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": null,
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "747f5d21-251b-4074-9bd2-9304c072286a",
                    "state": null,
                    "use_case": "HABCA"
                },
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "IMG3",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "IMG signing certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": null,
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "747f5d21-251b-4074-9bd2-9304c072286a",
                    "state": null,
                    "use_case": "HABCA"
                }
            ],
            "originating_id": null,
            "policy_identifiers": null,
            "product_id": null,
            "profile_id": "80ebbcc7-d0d9-4f44-be75-618d93e710b9",
            "state": null,
            "use_case": "HABCA"
        }
    ],
    "description": "TEST Product for i.MX6 based product",
    "enabled": true,
    "external_request_id": null,
    "id": null,
    "name": "Dummy product for i.MX6",
    "product_config_items": null,
    "product_operations": [
        {
            "approval_rule": {
                "allowed_groups": [
                    "b716abb1-2e3b-47a9-bca5-a3669faa50a6"
                ],
                "approval_groups": [
                    "f65a3ea9-60db-47a4-9ad8-c6915735ec5f"
                ],
                "blanket_groups": [],
                "description": "Rule used for Dummy product",
                "name": "Test rule"
            },
            "ca_use_case": null,
            "description": "HABCST signing",
            "id": null,
            "name": "HAB CST signing",
            "operation_type": "SignHAB",
            "profile_id": null,
            "token": null
        },
        {
            "approval_rule": {
                "allowed_groups": [
                    "b716abb1-2e3b-47a9-bca5-a3669faa50a6"
                ],
                "approval_groups": [
                    "f65a3ea9-60db-47a4-9ad8-c6915735ec5f"
                ],
                "blanket_groups": [],
                "description": "Rule used for testing for Dummy product",
                "name": "Test rule"
            },
            "ca_use_case": null,
            "description": "U-Boot signing operation",
            "id": null,
            "name": "U-Boot signing",
            "operation_type": "SignUBoot",
            "profile_id": null,
            "token": {
                "description": "HSM token for FIT image U-Boot signing.",
                "extractable": null,
                "key_override_id": null,
                "key_type": "RSA2048",
                "name": "Uboot",
                "public_key": null
            }
        },
        {
            "approval_rule": {
                "allowed_groups": [
                    "b716abb1-2e3b-47a9-bca5-a3669faa50a6"
                ],
                "approval_groups": [
                    "f65a3ea9-60db-47a4-9ad8-c6915735ec5f"
                ],
                "blanket_groups": [],
                "description": "Rule used for testing for Dummy product",
                "name": "Test rule"
            },
            "ca_use_case": null,
            "description": "FIT image kernel signing.",
            "id": null,
            "name": "Kernel signing",
            "operation_type": "SignKernel",
            "profile_id": null,
            "token": {
                "description": "HSM token for FIT image kernel signing.",
                "extractable": null,
                "key_override_id": null,
                "key_type": "RSA2048",
                "name": "Kernel",
                "public_key": null
            }
        }
    ],
    "product_type": "Production",
    "rnd_keys": [],
    "state": null
}
Is product ok(Y/N): y
{
    "ca_info": [],
    "description": "TEST Product for i.MX6 based product",
    "enabled": null,
    "external_request_id": null,
    "id": "6f603401-6723-4dec-a4a3-a8749865b46d",
    "name": "Dummy product for i.MX6",
    "product_config_items": null,
    "product_operations": [],
    "product_type": null,
    "rnd_keys": [],
    "state": 2
}
Product Add request sent. Request ID: 6f603401-6723-4dec-a4a3-a8749865b46d state: ApprovalRequire
```

## Approve product

The product was approved using the GUI.

Then with the python tool the state was checked ( state is 16 for ready product) and the product ID and operation ID was obtained.

- productID = 6f603401-6723-4dec-a4a3-a8749865b46d
- operation ID for SignHAB operation = fe55fd4e-7bdc-4278-b594-e75ee81eea14
- operation ID for SignKernel operation = 782c2150-15d5-4622-8e45-9c35fea1bbd1
- operation ID for SignUBoot operation = b13e4264-d8e4-4448-bed4-f2bbef420f74

```bash
(venv) $ signing-tool -n test.ini product getall
{
    "count": 1,
    "items": [
        {
            "description": "TEST Product for i.MX6 based product",
            "id": "6f603401-6723-4dec-a4a3-a8749865b46d",
            "name": "Dummy product for i.MX6",
            "state": 16
        }
    ],
    "next": "/products/?page=1",
    "pages": 1,
    "prev": "/products/?page=1"
}

(venv) $ signing-tool -n test.ini product \
    get -I 6f603401-6723-4dec-a4a3-a8749865b46d
{
    "ca_info": [
        {
            "cert_override_payload": null,
            "certificate_type": "ROOT",
            "cn": "SRK0",
            "crl_distribution_points": null,
            "crl_expiry": null,
            "crl_issue_interval": null,
            "csr": null,
            "description": "CA used for i.MX6 HAB",
            "external_request_id": null,
            "external_root": null,
            "id": "2219556b-58a3-49a5-9b48-d51f94e68390",
            "issuer_ca_id": null,
            "key_override_id": null,
            "key_type": "RSA4096",
            "leafs": [
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "CSF0",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "CSF End-Entity certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": "8f1422d9-18a4-443c-a15a-a4c0d06f3528",
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "6c51833b-c6e4-4506-8270-e32034598131",
                    "state": 16,
                    "use_case": "HABCA"
                },
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "IMG0",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "IMG signing certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": "ca447d0f-0448-4b97-b656-4e116a8655cb",
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "6c51833b-c6e4-4506-8270-e32034598131",
                    "state": 16,
                    "use_case": "HABCA"
                }
            ],
            "originating_id": null,
            "policy_identifiers": null,
            "product_id": null,
            "profile_id": "3e54bfce-e888-4aca-8430-2c5191be2427",
            "state": 16,
            "use_case": "HABCA"
        },
        {
            "cert_override_payload": null,
            "certificate_type": "ROOT",
            "cn": "SRK1",
            "crl_distribution_points": null,
            "crl_expiry": null,
            "crl_issue_interval": null,
            "csr": null,
            "description": "CA used for i.MX6 HAB",
            "external_request_id": null,
            "external_root": null,
            "id": "633631f2-186f-48e0-8e55-d27ee848e5e5",
            "issuer_ca_id": null,
            "key_override_id": null,
            "key_type": "RSA4096",
            "leafs": [
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "IMG1",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "IMG signing certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": "4d8137ca-1556-4229-809d-db13d73915b8",
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "6c51833b-c6e4-4506-8270-e32034598131",
                    "state": 16,
                    "use_case": "HABCA"
                },
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "CSF1",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "CSF End-Entity certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": "60835384-edc2-4a46-903a-e4e044b37beb",
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "6c51833b-c6e4-4506-8270-e32034598131",
                    "state": 16,
                    "use_case": "HABCA"
                }
            ],
            "originating_id": null,
            "policy_identifiers": null,
            "product_id": null,
            "profile_id": "3e54bfce-e888-4aca-8430-2c5191be2427",
            "state": 16,
            "use_case": "HABCA"
        },
        {
            "cert_override_payload": null,
            "certificate_type": "ROOT",
            "cn": "SRK2",
            "crl_distribution_points": null,
            "crl_expiry": null,
            "crl_issue_interval": null,
            "csr": null,
            "description": "CA used for i.MX6 HAB",
            "external_request_id": null,
            "external_root": null,
            "id": "93be8716-48df-4650-b336-ce5a4c3069d9",
            "issuer_ca_id": null,
            "key_override_id": null,
            "key_type": "RSA4096",
            "leafs": [
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "CSF2",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "CSF End-Entity certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": "615505c8-67d2-47eb-97ae-754a13e2beb5",
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "6c51833b-c6e4-4506-8270-e32034598131",
                    "state": 16,
                    "use_case": "HABCA"
                },
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "IMG2",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "IMG signing certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": "f7435eda-50aa-47aa-9ba4-62f79d9b8db3",
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "6c51833b-c6e4-4506-8270-e32034598131",
                    "state": 16,
                    "use_case": "HABCA"
                }
            ],
            "originating_id": null,
            "policy_identifiers": null,
            "product_id": null,
            "profile_id": "3e54bfce-e888-4aca-8430-2c5191be2427",
            "state": 16,
            "use_case": "HABCA"
        },
        {
            "cert_override_payload": null,
            "certificate_type": "ROOT",
            "cn": "SRK3",
            "crl_distribution_points": null,
            "crl_expiry": null,
            "crl_issue_interval": null,
            "csr": null,
            "description": "CA used for i.MX6 HAB",
            "external_request_id": null,
            "external_root": null,
            "id": "f1dc31c7-abec-4da1-a56f-16bd0b37c093",
            "issuer_ca_id": null,
            "key_override_id": null,
            "key_type": "RSA4096",
            "leafs": [
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "IMG3",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "IMG signing certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": "82e34b82-40c9-4aa5-9ff7-52e06dac968f",
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "6c51833b-c6e4-4506-8270-e32034598131",
                    "state": 16,
                    "use_case": "HABCA"
                },
                {
                    "cert_override_payload": null,
                    "certificate_type": "ENDENTITY",
                    "cn": "CSF3",
                    "crl_distribution_points": null,
                    "crl_expiry": null,
                    "crl_issue_interval": null,
                    "csr": null,
                    "description": "CSF End-Entity certificate",
                    "external_request_id": null,
                    "external_root": null,
                    "id": "fe9f88fc-93e4-414e-b67d-b8d640ee1cfa",
                    "issuer_ca_id": null,
                    "key_override_id": null,
                    "key_type": "RSA4096",
                    "leafs": [],
                    "originating_id": null,
                    "policy_identifiers": null,
                    "product_id": null,
                    "profile_id": "6c51833b-c6e4-4506-8270-e32034598131",
                    "state": 16,
                    "use_case": "HABCA"
                }
            ],
            "originating_id": null,
            "policy_identifiers": null,
            "product_id": null,
            "profile_id": "3e54bfce-e888-4aca-8430-2c5191be2427",
            "state": 16,
            "use_case": "HABCA"
        }
    ],
    "description": "TEST Product for i.MX6 based product",
    "enabled": null,
    "external_request_id": "05205857-23f0-4e4c-fad7-4cb0dcfbfa27",
    "id": "6f603401-6723-4dec-a4a3-a8749865b46d",
    "name": "Dummy product for i.MX6",
    "product_config_items": [],
    "product_operations": [
        {
            "approval_rule": {
                "allowed_groups": [
                    "b716abb1-2e3b-47a9-bca5-a3669faa50a6"
                ],
                "approval_groups": [
                    "f65a3ea9-60db-47a4-9ad8-c6915735ec5f"
                ],
                "blanket_groups": [
                    ""
                ],
                "description": "Rule used for testing for Dummy product",
                "name": "Test rule"
            },
            "ca_use_case": null,
            "description": "FIT image kernel signing.",
            "id": "782c2150-15d5-4622-8e45-9c35fea1bbd1",
            "name": "Kernel signing",
            "operation_type": "SignKernel",
            "profile_id": "00000000-0000-0000-0000-000000000000",
            "token": {
                "description": "HSM token for FIT image kernel signing.",
                "extractable": null,
                "key_override_id": null,
                "key_type": "RSA2048",
                "name": "Kernel",
                "public_key": "MIIBIjANBgkq…(392 base64 chars elided; DER public key: RSA-2048)"
            }
        },
        {
            "approval_rule": {
                "allowed_groups": [
                    "b716abb1-2e3b-47a9-bca5-a3669faa50a6"
                ],
                "approval_groups": [
                    "f65a3ea9-60db-47a4-9ad8-c6915735ec5f"
                ],
                "blanket_groups": [
                    ""
                ],
                "description": "Rule used for testing for Dummy product",
                "name": "Test rule"
            },
            "ca_use_case": null,
            "description": "U-Boot signing operation",
            "id": "b13e4264-d8e4-4448-bed4-f2bbef420f74",
            "name": "U-Boot signing",
            "operation_type": "SignUBoot",
            "profile_id": "00000000-0000-0000-0000-000000000000",
            "token": {
                "description": "HSM token for FIT image U-Boot signing.",
                "extractable": null,
                "key_override_id": null,
                "key_type": "RSA2048",
                "name": "Uboot",
                "public_key": "MIIBIjANBgkq…(392 base64 chars elided; DER public key: RSA-2048)"
            }
        },
        {
            "approval_rule": {
                "allowed_groups": [
                    "b716abb1-2e3b-47a9-bca5-a3669faa50a6"
                ],
                "approval_groups": [
                    "f65a3ea9-60db-47a4-9ad8-c6915735ec5f"
                ],
                "blanket_groups": [
                    ""
                ],
                "description": "Rule used for Dummy product",
                "name": "Test rule"
            },
            "ca_use_case": null,
            "description": "HABCST signing",
            "id": "fe55fd4e-7bdc-4278-b594-e75ee81eea14",
            "name": "HAB CST signing",
            "operation_type": "SignHAB",
            "profile_id": "00000000-0000-0000-0000-000000000000",
            "token": null
        }
    ],
    "product_type": "Production",
    "rnd_keys": [],
    "state": 16
}
```

## Getting the sensitive items

In manufacturing there are some sensitive items which are needed. Here a client is registered which can obtain e.g., public keys of the Kernel and uBoot operations.
Also in HAB case the SRK table and SRK hash are returned. 

```bash
(venv) $ signing-tool -n test.ini client add -N Manufacturing -D "Get sensitive information" \
     -K client.public -U "oid:<your-object-id>" -T ProductionPC -p 6f603401-6723-4dec-a4a3-a8749865b46d
{
    "client_type": "ProductionPC",
    "description": "Get sensitive information",
    "id": "5235da30-6c2b-493c-bfec-937b70dc6742",
    "id_product": "6f603401-6723-4dec-a4a3-a8749865b46d",
    "name": "Manufacturing",
    "state": 2
}
Client Add request sent. Request ID: 5235da30-6c2b-493c-bfec-937b70dc6742 state: ApprovalRequired
```

Approve the client from UI

Now the product sensitive items can be fetched. 

```bash
(venv) $  signing-tool -n test.ini secrets get \
    -P 6f603401-6723-4dec-a4a3-a8749865b46d -C client.private -O /tmp/prod.json
SRKHASH written to: /tmp/prod.jsonSRKHASH
SRKTABLE written to: /tmp/prod.jsonSRKTABLE
KEKIV written to: /tmp/prod.jsonKEKIV
Full secret payload written to: /tmp/prod.json
```

The SRKHash has been store to /tmp/prod.jsonSRKHASH and SRKTable has been stored to /tmp/prod.jsonSRKTABLE. The /tmp/prod.json contains all the items in one file. All the Certificates can be seen in that file.

More info can be found from [client usage](https://docs.laavat.io/usage/clientguide/clients/).

## SPL signing

An SPL image is signed here with the **SignHAB** operation — CST-based HAB signing.

```bash
(venv) $ signing-tool -n test.ini imagesigning add SignHAB \
    -P 6f603401-6723-4dec-a4a3-a8749865b46d \
    --operid fe55fd4e-7bdc-4278-b594-e75ee81eea14 \
    -N TEST -D TEST -F SPL-hab 
{
    "call_back_url": null,
    "description": "TEST",
    "id": "5f7bc725-938d-46f6-8573-77efedfe33c6",
    "id_product": "6f603401-6723-4dec-a4a3-a8749865b46d",
    "id_product_operation": "fe55fd4e-7bdc-4278-b594-e75ee81eea14",
    "name": "TEST",
    "payload": {
        "id": null,
        "metadata": [
            {
                "name": "first",
                "value": "val"
            }
        ],
        "modified_sha256": null,
        "name": "SPL-hab",
        "original_sha256": null,
        "s3_url": null,
        "service_provided_parameters": null
    },
    "state": 1
}
Request sent. Request ID: 5f7bc725-938d-46f6-8573-77efedfe33c6, state: Created
```

The operation created ID "5f7bc725-938d-46f6-8573-77efedfe33c6" which is then used when querying/downloading the signed content.

## Approve SPL signing request

Request was approved from the GUI.

## Download SPL signed content

After approval the request is processed and it can be queried. If the state is 16 then the signing is complete and the content is downloaded.

```bash
(venv) $ signing-tool -n test.ini imagesigning get \
    -I 5f7bc725-938d-46f6-8573-77efedfe33c6 -O /tmp/test.bin --skipBase64
{
    "call_back_url": null,
    "description": "TEST",
    "id": "5f7bc725-938d-46f6-8573-77efedfe33c6",
    "id_product": "6f603401-6723-4dec-a4a3-a8749865b46d",
    "id_product_operation": "fe55fd4e-7bdc-4278-b594-e75ee81eea14",
    "name": "TEST",
    "payload": {
        "id": "6bba4fdc-92c9-4ab3-991b-c66aae65383d",
        "metadata": [
            {
                "name": "first",
                "value": "val"
            }
        ],
        "modified_sha256": null,
        "name": "SPL-hab",
        "original_sha256": null,
        "s3_url": "<redacted>",
        "service_provided_parameters": []
    },
    "state": 16
}
Downloading signed binary to: /tmp/test.bin
File Downloaded
```

## FIT signing

A FIT image is signed here with the **SignUBoot** operation.

```bash
(venv) $ signing-tool -n test.ini imagesigning add SignUBoot \
    -P 6f603401-6723-4dec-a4a3-a8749865b46d \
    --operid b13e4264-d8e4-4448-bed4-f2bbef420f74 \
    -N TEST -D TEST -F linux-uImage.bin 
{
    "call_back_url": null,
    "description": "TEST",
    "id": "e37c86e9-21ab-4d04-8d83-5c7e91721d1e",
    "id_product": "6f603401-6723-4dec-a4a3-a8749865b46d",
    "id_product_operation": "b13e4264-d8e4-4448-bed4-f2bbef420f74",
    "name": "TEST",
    "payload": {
        "id": null,
        "metadata": [
            {
                "name": "first",
                "value": "val"
            }
        ],
        "modified_sha256": null,
        "name": "linux-uImage.bin",
        "original_sha256": null,
        "s3_url": null,
        "service_provided_parameters": null
    },
    "state": 1
}
Request sent. Request ID: e37c86e9-21ab-4d04-8d83-5c7e91721d1e, state: Created
```

The operation created ID "e37c86e9-21ab-4d04-8d83-5c7e91721d1e" which is then used when querying/downloading the signed content.

## Approve FIT signing request

Request was approved from the GUI.

## Download FIT signed content

After approval the request is processed and it can be queried. If the state is 16 then the signing is complete and the content is downloaded.

```bash
(venv) $ signing-tool -n test.ini imagesigning get \
    -I e37c86e9-21ab-4d04-8d83-5c7e91721d1e -O /tmp/test.bin
{
    "call_back_url": null,
    "description": "TEST",
    "id": "e37c86e9-21ab-4d04-8d83-5c7e91721d1e",
    "id_product": "6f603401-6723-4dec-a4a3-a8749865b46d",
    "id_product_operation": "b13e4264-d8e4-4448-bed4-f2bbef420f74",
    "name": "TEST",
    "payload": {
        "id": "63a9e096-2aa3-4e6c-84e4-d6429f74a171",
        "metadata": [
            {
                "name": "first",
                "value": "val"
            }
        ],
        "modified_sha256": null,
        "name": "linux-uImage.bin",
        "original_sha256": null,
        "s3_url": "<redacted>",
        "service_provided_parameters": []
    },
    "state": 16
}
Downloading signed binary to: /tmp/test.bin
File Downloaded
```

## Archive-mode signing (request.json)

In addition to the raw-binary input shown above, the `SignHAB` operation
also accepts an archive payload (`.tar`, `.tar.gz`, or `.zip`) containing a
top-level `request.json` plus the binary file(s) to sign. The same `SignHAB`
operation handles both formats and detects automatically which one you sent.
The output is a `.signed.tar.gz` archive
containing the patched binary (or detached signatures) and a `response.json`
describing each CSF.

Use archive-mode when you need:

- A custom block layout (`authenticate.blocks[]`) that the platform's IVT
  parser would not produce on its own.
- Signing the **same binary file multiple times** in one request, with each
  signature inserted at a different offset (e.g., the SPL stage and the u-boot
  stage of one `u-boot.bin`). List the binary once per CSF in `csfs[]` with the
  same `binaryFilename` and a distinct `signatureOffset` for each — all patches
  land in the same output `signed/<binaryFilename>`.
- Signing several distinct binaries in a single request.
- A detached signature file (`output: "raw"`) instead of an in-place patch.

The full `request.json` schema is documented in [CST Signing → Archive-mode input](https://docs.laavat.io/usage/signing-encryption/cstsigning/#archive-mode-input).

### Build the input archive

Create `request.json` next to the binary. Minimal example for signing an SPL image with the platform's IVT-derived blocks (the same blocks the platform would derive for raw-binary input):

```json
{
  "csfs": [
    {
      "binaryFilename": "u-boot.bin",
      "authenticate": { "auto": true }
    }
  ]
}
```

Or an explicit-blocks example signing both the SPL stage and the u-boot stage of the same binary at different offsets:

```json
{
  "csfs": [
    {
      "id": "spl",
      "mode": "hab4-spl",
      "binaryFilename": "u-boot.bin",
      "signatureOffset": "0x20000",
      "csfRegionSize": "0x2000",
      "unlock": { "features": ["MID"] },
      "authenticate": {
        "blocks": [
          { "address": "0x87800000", "offset": "0x0", "length": "0x20000" }
        ]
      }
    },
    {
      "id": "uboot",
      "mode": "hab4",
      "binaryFilename": "u-boot.bin",
      "signatureOffset": "0x180000",
      "authenticate": {
        "blocks": [
          { "address": "0x80000000", "offset": "0x40000",  "length": "0x800"   },
          { "address": "0x80100000", "offset": "0x80000",  "length": "0x80000" },
          { "address": "0x80180000", "offset": "0x100000", "length": "0x8000"  },
          { "address": "0x80188000", "offset": "0x108000", "length": "0x4000"  }
        ]
      }
    }
  ]
}
```

Pack `request.json` and the binary into a flat tar.gz (no subdirectories):

```bash
$ tar czf /tmp/spl-archive.tar.gz -C /path/to/inputs request.json u-boot.bin
$ tar tzf /tmp/spl-archive.tar.gz
request.json
u-boot.bin
```

### Submit the signing request

The submission is identical to the raw-binary SPL example earlier — only the payload file changes. Point `-F` at the `.tar.gz`:

```bash
(venv) $ signing-tool -n test.ini imagesigning add SignHAB \
    -P 6f603401-6723-4dec-a4a3-a8749865b46d \
    --operid fe55fd4e-7bdc-4278-b594-e75ee81eea14 \
    -N TEST -D TEST -F /tmp/spl-archive.tar.gz
```

Approve the request through the GUI as in the previous examples.

### Download and inspect the signed archive

The downloaded file is a `.tar.gz` (not a raw binary). Extract it to inspect the contents:

```bash
(venv) $ signing-tool -n test.ini imagesigning get \
    -I <request-id> -O /tmp/signed.tar.gz --skipBase64

$ mkdir /tmp/signed && tar xzf /tmp/signed.tar.gz -C /tmp/signed
$ find /tmp/signed -type f
/tmp/signed/signed/u-boot.bin
/tmp/signed/response.json

$ cat /tmp/signed/response.json
{
  "version": "1",
  "csfs": [
    {
      "id": "spl",
      "binaryFilename": "u-boot.bin",
      "mode": "hab4-spl",
      "sha256_input":  "f3a1...",
      "sha256_output": "9b22...",
      "patched": true,
      "signatureOffset": "0x20000",
      "signatureSize": 4096
    },
    {
      "id": "uboot",
      "binaryFilename": "u-boot.bin",
      "mode": "hab4",
      "sha256_input":  "f3a1...",
      "sha256_output": "c804...",
      "patched": true,
      "signatureOffset": "0x180000",
      "signatureSize": 4096
    }
  ]
}
```

Verify integrity by hashing each delivered binary — `sha256sum signed/<binaryFilename>` — and comparing it to that binary's `sha256_output` in `response.json`.
`sha256_output` is the SHA-256 of the **whole patched binary** as of that CSF's patch, so it matches the complete file only — not an extracted region or a detached `.sig`.

When one binary is signed by several CSFs (the SPL + u-boot case above), the patches are applied in order to a single `signed/<binaryFilename>`, so only the **last** CSF for that binary has a `sha256_output` matching the delivered file — the earlier values are intermediate hashes.
In the example above, `signed/u-boot.bin` matches the `uboot` CSF's `sha256_output` (`c804...`), not the `spl` CSF's (`9b22...`).

Do not hash the outer `.tar.gz` — the same result can produce slightly different archive bytes from one run to the next.

For CSFs declared with `output: "raw"`, the detached signature appears under `signatures/<id>.sig` instead of a patched binary under `signed/`.
