> ## 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 ML-DSA subordinate CA

> Configure Microsoft AD CS to create an ML-DSA subordinate key through CryptoHub, sign its request with the CryptoHub root CA, and install the signed certificate.

Configure AD CS as an ML-DSA subordinate CA. AD CS creates the subordinate private key through the Futurex CNG provider, then CryptoHub signs the resulting certificate request with the ML-DSA root CA.

## Install the AD CS role

Skip this section if the **Active Directory Certificate Services** Certification Authority role is already installed but not configured.

<Steps>
  <Step>
    Open PowerShell as an administrator and install the Certification Authority role and management tools:

    ```powershell theme={null}
    Install-WindowsFeature ADCS-Cert-Authority -IncludeManagementTools
    ```
  </Step>

  <Step>
    Confirm the role state:

    ```powershell theme={null}
    Get-WindowsFeature ADCS-Cert-Authority
    ```

    <Check>
      The **Install State** is **Installed**.
    </Check>
  </Step>
</Steps>

## Create the subordinate CA request

<Steps>
  <Step>
    In **Server Manager**, select the notification flag, and then select **Configure Active Directory Certificate Services on the destination server**.
  </Step>

  <Step>
    On **Credentials**, select an account that meets the displayed requirements, and then select **Next**.
  </Step>

  <Step>
    On **Role Services**, select **Certification Authority**, and then select **Next**.
  </Step>

  <Step>
    On **Setup Type**, select **Standalone CA**, and then select **Next**.

    <Note>
      Use **Enterprise CA** only when the CA server is joined to Active Directory.
    </Note>
  </Step>

  <Step>
    On **CA Type**, select **Subordinate CA**, and then select **Next**.
  </Step>

  <Step>
    On **Private Key**, select **Create a new private key**, and then select **Next**.
  </Step>

  <Step>
    On **Cryptography for CA**, configure the CryptoHub-backed key:

    * Select one of the following cryptographic provider options:
      * `ML-DSA:44#Futurex CryptoHub Key Storage Provider`
      * `ML-DSA:65#Futurex CryptoHub Key Storage Provider`
      * `ML-DSA:87#Futurex CryptoHub Key Storage Provider`
    * Leave **Key length** set to `192`.
    * Leave **Hash Algorithm** set to `NoHash`.
    * Leave **Allow administrator interaction when the private key is accessed by the CA** cleared.

    Select **Next**.
  </Step>

  <Step>
    On **CA Name**, enter the subordinate CA common name and distinguished-name suffix defined by your PKI policy. This guide uses `Example ML-DSA Issuing CA` in examples.

    Select **Next**.
  </Step>

  <Step>
    On **Certificate Request**, save the request to:

    ```text theme={null}
    C:\example-ml-dsa-issuing-ca.req
    ```

    Select **Next**.
  </Step>

  <Step>
    On **CA Database**, confirm the database and log locations, and then select **Next**.
  </Step>

  <Step>
    Review the configuration and select **Configure**.

    <Check>
      The wizard should report "Configuration succeeded with warnings" along with the message below:
      "The Active Directory Certificate Services installation is incomplete. To complete the installation, use the request file "C:\example-ml-dsa-issuing-ca.req" to obtain a certificate from the parent CA. Then, use the Certification Authority snap-in to install the certificate. To complete this procedure, right-click the node with the name of the CA, and then click Install CA Certificate. The operation completed successfully. Ox0 (WIN32: 0)"
    </Check>

    The Certification Authority service remains unavailable until you install the signed subordinate certificate.
  </Step>
</Steps>

## Sign the subordinate request in CryptoHub

<Steps>
  <Step>
    Transfer `example-ml-dsa-issuing-ca.req` to the administrative workstation used to access CryptoHub.

    <Note>
      The request contains the subordinate public key and identity attributes. It does not contain the CryptoHub-protected private key.
    </Note>
  </Step>

  <Step>
    In CryptoHub, select **PKI & CA** > **Certificate Management** and expand the certificate container that holds the ML-DSA root CA.
  </Step>

  <Step>
    Right-click the root CA, and then select **Add Certificate** > **From Request**. Upload `example-ml-dsa-issuing-ca.req`.

    <Check>
      The certificate window displays the subject and ML-DSA public-key information from the request.
    </Check>
  </Step>

  <Step>
    Review **Subject DN** and the validity dates on **Basic Info**. The subordinate validity must end before the root CA expires.
  </Step>

  <Step>
    On **V3 Extensions**, select the **Certificate Authority** profile.
  </Step>

  <Step>
    If you publish a CRL, add the **CRL Distribution Points** extension. Skip this step if you turn off revocation checking.

    1. Select **Add**, select **CRL Distribution Points**, and then select **OK**.
    2. Leave **Critical** set to **No**.
    3. Select **Add**, and leave the type set to **HTTP**.
    4. Enter the URL where the CDP server publishes the root CA CRL, for example `http://crl.example.com/example-ml-dsa-root-ca.crl`. Then select **OK**.

    <Note>
      Include the protocol (`http://`) in the URL. The **CRL Distribution Points** extension requires it.
    </Note>

    <Check>
      The **V3 Extensions** table contains a **CRL Distribution Points** row.
    </Check>
  </Step>

  <Step>
    Select **OK** to submit the request to the root CA.

    <Check>
      After the job completes, the subordinate certificate appears beneath the ML-DSA root CA and reports **Valid**.
    </Check>
  </Step>

  <Step>
    Right-click the subordinate certificate and select **Export** > **Certificate(s)**. Export it as an X.509 certificate to `example-ml-dsa-issuing-ca.cer`.
  </Step>

  <Step>
    Right-click the root CA and select **Export** > **Certificate(s)**. Export the public root certificate to `example-ml-dsa-root-ca.cer`.
  </Step>
</Steps>

## Publish the root CA CRL

Skip this section if you turn off revocation checking.

Create a certificate revocation list (CRL) for the ML-DSA root CA in CryptoHub, and then publish it on your CRL distribution point (CDP) server. You provide the CDP server. Any HTTP web server that the AD CS server can reach can serve the CRL file.

<Note>
  The filename and path on the CDP server must exactly match the URL in the subordinate certificate's **CRL Distribution Points** extension.
</Note>

### Create the CRL

<Steps>
  <Step>
    In CryptoHub, select **PKI & CA** > **Certificate Management**, and expand the certificate container that holds the ML-DSA root CA.
  </Step>

  <Step>
    Right-click the ML-DSA root CA, and then select **CRL** > **Create**.
  </Step>

  <Step>
    Configure the CRL:

    * Leave **Initial revision** set to `1`.
    * Set **CRL period** according to your PKI policy. The CRL expires at the end of this period.
    * Leave **First issue** set to the current date and time.

    Select **OK**.

    <Note>
      CryptoHub signs the CRL with the ML-DSA root key. The **Signature hash** and **Padding** values do not change the ML-DSA signature.
    </Note>
  </Step>
</Steps>

### Export the CRL

<Steps>
  <Step>
    Right-click the ML-DSA root CA, and then select **CRL** > **Export**.
  </Step>

  <Step>
    Configure the export:

    * Under **CRL Period**, leave **Last Revision** selected.
    * Set **Encoding** to **DER**.
    * Leave **Format** set to **X509**.
    * In **File**, enter the filename from the extension URL, for example `example-ml-dsa-root-ca.crl`.

    Select **OK**.
  </Step>

  <Step>
    When CryptoHub reports that it wrote the CRL, select **OK**. Save the file that your browser downloads.
  </Step>
</Steps>

### Publish the CRL on the CDP server

<Steps>
  <Step>
    Copy the CRL file to the CDP server at the path in the extension URL. For example, for `http://crl.example.com/example-ml-dsa-root-ca.crl`, publish the file as `example-ml-dsa-root-ca.crl` at the web root of `crl.example.com`.
  </Step>

  <Step>
    Confirm that the CDP server serves the file over the protocol and port in the extension URL, for example port 80 for an `http://` URL.
  </Step>

  <Step>
    From the AD CS server, download the CRL from the extension URL:

    ```powershell theme={null}
    Invoke-WebRequest http://crl.example.com/example-ml-dsa-root-ca.crl -OutFile C:\CA\example-ml-dsa-root-ca.crl
    ```

    <Check>
      The file downloads without errors and is not empty.
    </Check>
  </Step>
</Steps>

<Warning>
  Create, export, and publish a new CRL before the current CRL period ends, and after you revoke a certificate issued by the root CA. If the published CRL expires, AD CS cannot check revocation and denies certificate requests.
</Warning>

## Install the CA certificates in Windows

Transfer the two public certificate files to `C:\CA` on the AD CS server. You may need to create the `C:\CA` folder.

<Steps>
  <Step>
    Open PowerShell as an administrator and add the CryptoHub root certificate to the local-machine trusted root store:

    ```powershell theme={null}
    certutil -addstore -f Root C:\CA\example-ml-dsa-root-ca.cer
    ```

    <Check>
      CertUtil reports that it added the certificate to the store.
    </Check>
  </Step>

  <Step>
    If you publish a CRL, confirm that Windows can check the revocation status of the subordinate certificate:

    ```powershell theme={null}
    certutil -verify -urlfetch C:\CA\example-ml-dsa-issuing-ca.cer
    ```

    <Check>
      CertUtil retrieves the CRL from the CDP URL and reports no revocation errors.
    </Check>
  </Step>

  <Step>
    Install the signed subordinate CA certificate and associate it with the key created by the AD CS configuration wizard:

    ```powershell theme={null}
    certutil -installcert C:\CA\example-ml-dsa-issuing-ca.cer
    ```

    * **If you publish a CRL:** No warning appears. If a **Cannot verify certificate chain** warning appears, select **Cancel**, and then confirm that the AD CS server can download the CRL from the CDP URL.
    * **If you turn off revocation checking:** A **Cannot verify certificate chain** warning appears and reports `CRYPT_E_NO_REVOCATION_CHECK` (`0x80092012`). This warning is expected. Select **OK** to continue.

    <Check>
      CertUtil reports success and does not report a missing private key or provider error.
    </Check>
  </Step>
</Steps>

## Turn off revocation checking

Skip this section if you publish a CRL.

<Warning>
  With these settings, AD CS issues certificates even when it cannot check whether the subordinate CA certificate is revoked. Use them only in test environments or when your PKI policy accepts this risk.
</Warning>

Run these commands from an elevated PowerShell session on the AD CS server:

```powershell theme={null}
certutil -setreg CA\CRLFlags +CRLF_REVCHECK_IGNORE_NOREVCHECK
certutil -setreg CA\CRLFlags +CRLF_REVCHECK_IGNORE_OFFLINE
```

* `CRLF_REVCHECK_IGNORE_NOREVCHECK` ignores missing revocation information, such as a CA certificate with no **CRL Distribution Points** extension.
* `CRLF_REVCHECK_IGNORE_OFFLINE` ignores a CRL that the AD CS server cannot reach.

<Check>
  CertUtil reports that it updated `CRLFlags`. The new values take effect when the Certification Authority service starts.
</Check>

## Start the Certification Authority service

<Steps>
  <Step>
    Start the Certification Authority service and confirm its state:

    ```powershell theme={null}
    Start-Service certsvc
    Get-Service certsvc
    ```

    <Check>
      The service state is **Running**.
    </Check>

    <Note>
      If the service was already running when you changed `CRLFlags`, restart it with `Restart-Service certsvc`.
    </Note>
  </Step>

  <Step>
    Confirm the configured provider:

    ```powershell theme={null}
    certutil -getreg CA\CSP\Provider
    ```

    <Check>
      The provider is **Futurex CryptoHub Key Storage Provider**.
    </Check>
  </Step>
</Steps>

Continue to [Verify the integration](./verify-integration).
