Certificate Enrollment

Overview

Export certificates from Vault PKI in PKCS#12 format and import into Windows Certificate Store.

Prerequisites

  • Vault CLI installed and configured

  • Access to Vault PKI (pki_int/issue/domus-client role)

  • jq and openssl installed

Step 1: Issue Certificate from Vault

Run from a Linux workstation with Vault access (not from the Windows machine).

Set Variables

# Load Vault secrets
dsource d000 dev/vault

# Target hostname (change this to your Windows machine name)
HOSTNAME="win-pc-01"
DOMAIN="inside.domusdigitalis.dev"
Example: Home enterprise workstation
HOSTNAME="modestus-surface"
DOMAIN="inside.domusdigitalis.dev"

Issue Certificate (1-year TTL)

vault write -format=json pki_int/issue/domus-client \
  common_name="${HOSTNAME}.${DOMAIN}" \
  ttl="8760h" > /tmp/${HOSTNAME}-cert.json

Extract Components

jq -r '.data.certificate' /tmp/${HOSTNAME}-cert.json > /tmp/${HOSTNAME}.crt
jq -r '.data.private_key' /tmp/${HOSTNAME}-cert.json > /tmp/${HOSTNAME}.key
jq -r '.data.ca_chain[]' /tmp/${HOSTNAME}-cert.json > /tmp/${HOSTNAME}-chain.crt

Verify Extraction

# Check certificate subject
openssl x509 -in /tmp/${HOSTNAME}.crt -noout -subject -issuer

# Expected output:
# subject=CN = win-pc-01.inside.domusdigitalis.dev
# issuer=CN = DOMUS-ISSUING-CA

Step 2: Create PKCS#12 Bundle

Windows requires PKCS#12 (.pfx) format for certificate import.

Set Password

# Use a strong password (you'll need this on the Windows side)
PFX_PASS="$(openssl rand -base64 16)"
echo "PFX Password: ${PFX_PASS}"
Save this password - you’ll need it when importing on Windows.

Create Bundle

openssl pkcs12 -export \
  -out /tmp/${HOSTNAME}.pfx \
  -inkey /tmp/${HOSTNAME}.key \
  -in /tmp/${HOSTNAME}.crt \
  -certfile /tmp/${HOSTNAME}-chain.crt \
  -passout pass:${PFX_PASS}

Verify Bundle

# Verify PFX was created
ls -la /tmp/${HOSTNAME}.pfx

# Check bundle contents (enter password when prompted)
openssl pkcs12 -in /tmp/${HOSTNAME}.pfx -info -nodes -passin pass:${PFX_PASS} | head -20

Step 3: Transfer to Windows

Copy files to the Windows machine.

Option A: SCP (from Linux workstation)

# Copy PFX to Windows machine (via SSH if available)
scp /tmp/${HOSTNAME}.pfx administrator@${HOSTNAME}:C:/Temp/

# Also copy CA chain for trust store
scp /tmp/${HOSTNAME}-chain.crt administrator@${HOSTNAME}:C:/Temp/

Option B: Network Share

# Copy to a network share accessible from Windows
cp /tmp/${HOSTNAME}.pfx /mnt/share/certs/
cp /tmp/${HOSTNAME}-chain.crt /mnt/share/certs/

Option C: Manual Copy

Copy the following files to C:\Temp\ on the Windows machine:

  • /tmp/${HOSTNAME}.pfx - Client certificate bundle

  • /tmp/${HOSTNAME}-chain.crt - CA chain

Step 4: Import Certificate (PowerShell)

Run PowerShell as Administrator on the Windows machine.

Set Variables

# Change this to match your hostname
$Hostname = "win-pc-01"
$PfxPath = "C:\Temp\$Hostname.pfx"
$ChainPath = "C:\Temp\$Hostname-chain.crt"

# Enter the PFX password from Step 2
$PfxPassword = Read-Host -AsSecureString "Enter PFX Password"

Import Client Certificate

# Import to Local Machine Personal store
Import-PfxCertificate -FilePath $PfxPath `
  -CertStoreLocation Cert:\LocalMachine\My `
  -Password $PfxPassword

Expected output shows certificate thumbprint:

   PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\My

Thumbprint                                Subject
----------                                -------
A1B2C3D4E5F6...                          CN=win-pc-01.inside.domusdigitalis.dev

Step 5: Import CA Chain

Import the issuing CA to the Intermediate store and root to Trusted Root.

# Import CA chain (contains both issuing and root)
Import-Certificate -FilePath $ChainPath `
  -CertStoreLocation Cert:\LocalMachine\CA

Verify CA Trust

# Check that DOMUS-ISSUING-CA is trusted
Get-ChildItem Cert:\LocalMachine\CA | Where-Object Subject -like "*DOMUS-ISSUING-CA*" | Format-List Subject, Thumbprint, NotAfter

Step 6: Verify Import

Verify Certificates

Check Client Certificate

# List certificates in Personal store
Get-ChildItem Cert:\LocalMachine\My | Format-Table Subject, NotAfter, Thumbprint

# Check specific cert details
Get-ChildItem Cert:\LocalMachine\My | Where-Object {{ $_.Subject -like "*inside.domusdigitalis.dev*" }} | Format-List *

# Verify certificate has private key
Get-ChildItem Cert:\LocalMachine\My | Where-Object {{ $_.HasPrivateKey }}

# Check EKU includes Client Authentication
Get-ChildItem Cert:\LocalMachine\My | ForEach-Object {{
    $_.EnhancedKeyUsageList | Where-Object {{ $_.FriendlyName -eq "Client Authentication" }}
}}

Check Root CA

# Check DOMUS-ROOT-CA is trusted
Get-ChildItem Cert:\LocalMachine\Root | Where-Object {{ $_.Subject -like "*DOMUS-ROOT-CA*" }} | Format-List Subject, Thumbprint

Check Intermediate CA

# Check DOMUS-ISSUING-CA is present
Get-ChildItem Cert:\LocalMachine\CA | Where-Object {{ $_.Subject -like "*DOMUS-ISSUING-CA*" }} | Format-List Subject, Thumbprint

Additional Verification

# Verify certificate chain is valid
$cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object Subject -like "*$Hostname*"
$chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain
$chain.Build($cert)
$chain.ChainStatus | Format-Table Status, StatusInformation

# Expected: Empty (no errors) or "RevocationStatusUnknown" (acceptable without CRL)

Cleanup

After verifying 802.1X works, remove the temporary files.

On Windows

# Remove PFX and chain files
Remove-Item "C:\Temp\$Hostname.pfx" -Force -ErrorAction SilentlyContinue
Remove-Item "C:\Temp\$Hostname-chain.crt" -Force -ErrorAction SilentlyContinue

On Linux Workstation

# Remove temporary cert files
rm -f /tmp/${HOSTNAME}-cert.json /tmp/${HOSTNAME}.crt /tmp/${HOSTNAME}.key
rm -f /tmp/${HOSTNAME}-chain.crt /tmp/${HOSTNAME}.pfx

Troubleshooting

Certificate Not Appearing

# Check if certificate was imported
Get-ChildItem Cert:\LocalMachine\My | Format-Table Subject, Thumbprint

# If empty, re-run import with verbose
Import-PfxCertificate -FilePath $PfxPath -CertStoreLocation Cert:\LocalMachine\My -Password $PfxPassword -Verbose

"The PFX file is protected" Error

Password mismatch. Verify the password from Step 2:

# Test with plaintext password (for debugging only)
$PlainPwd = "your-password-here"
$SecurePwd = ConvertTo-SecureString -String $PlainPwd -Force -AsPlainText
Import-PfxCertificate -FilePath $PfxPath -CertStoreLocation Cert:\LocalMachine\My -Password $SecurePwd

Chain Validation Fails

# List intermediate CAs
Get-ChildItem Cert:\LocalMachine\CA | Format-Table Subject, NotAfter

# If DOMUS-ISSUING-CA missing, import the chain again
Import-Certificate -FilePath $ChainPath -CertStoreLocation Cert:\LocalMachine\CA

See Also