PKI & Certificate Patterns

PKI and certificate patterns I’ve actually used. Every entry has a date and context.

2026-04-03: Vault PKI Certificate Issuance Workflow

Problem: Issue client certificate from Vault PKI for EAP-TLS authentication on a new workstation.

Context: P16g deployment, Vault PKI intermediate CA (pki_int), domus-client role. Need cert with CN matching hostname, extract components with jq, install to system paths.

The Fix:

# Set target hostname explicitly — may be issuing from a different machine
HOSTNAME="modestus-p16g"
echo "Issuing cert for: ${HOSTNAME}.inside.domusdigitalis.dev"
# Issue certificate — tee saves full JSON AND pipes summary to screen
vault write -format=json pki_int/issue/domus-client \
    common_name="${HOSTNAME}.inside.domusdigitalis.dev" \
    ttl=8760h \
    | tee /tmp/${HOSTNAME}-vault-cert.json \
    | jq '{common_name: .data.common_name, serial: .data.serial_number, expiration: .data.expiration}' \
    > /tmp/${HOSTNAME}-vault-summary.json
# Extract client certificate
jq -r '.data.certificate' /tmp/${HOSTNAME}-vault-cert.json >| /tmp/${HOSTNAME}-eaptls.pem
# Extract private key
jq -r '.data.private_key' /tmp/${HOSTNAME}-vault-cert.json >| /tmp/${HOSTNAME}-eaptls.key
# Extract CA chain (issuing CA + root CA)
jq -r '.data.ca_chain[]' /tmp/${HOSTNAME}-vault-cert.json >| /tmp/DOMUS-CA-CHAIN.pem
# Verify certificate details
openssl x509 -in /tmp/${HOSTNAME}-eaptls.pem -noout -subject -issuer -dates
# CRITICAL: Must include "TLS Web Client Authentication"
openssl x509 -in /tmp/${HOSTNAME}-eaptls.pem -noout -text | grep -A1 "Extended Key Usage"
# Install to system paths
sudo cp /tmp/${HOSTNAME}-eaptls.pem /etc/ssl/certs/
sudo cp /tmp/${HOSTNAME}-eaptls.key /etc/ssl/private/
sudo chmod 600 /etc/ssl/private/${HOSTNAME}-eaptls.key
sudo chown root:root /etc/ssl/private/${HOSTNAME}-eaptls.key
sudo cp /tmp/DOMUS-CA-CHAIN.pem /etc/ssl/certs/

Rule: Always tee the full JSON response before extracting — if jq extraction fails, you still have the raw data. Set HOSTNAME explicitly (don’t rely on $(hostname)) when issuing from a remote machine. Verify Extended Key Usage includes TLS Web Client Authentication — ISE silently rejects without it.

Worklog: WRKLOG-2026-04-03


2026-04-03: Key-Certificate Modulus Match Verification

Problem: EAP-TLS handshake fails silently — need to verify the private key matches the certificate before deploying.

Context: P16g deployment, Vault-issued certificate. Mismatched key/cert is a common cause of "TLS handshake failed" that wastes hours.

The Fix:

# Both MD5 hashes MUST match
CERT_MOD=$(openssl x509 -in /tmp/${HOSTNAME}-eaptls.pem -noout -modulus | md5sum | cut -d' ' -f1)
KEY_MOD=$(openssl rsa -in /tmp/${HOSTNAME}-eaptls.key -noout -modulus 2>/dev/null | md5sum | cut -d' ' -f1)
echo "Cert: $CERT_MOD"
echo "Key:  $KEY_MOD"
[ "$CERT_MOD" == "$KEY_MOD" ] && echo "MATCH" || echo "MISMATCH — DO NOT PROCEED"

Rule: Always verify modulus match before installing cert+key. Mismatched pairs cause silent TLS failures that look like CA trust issues.

Worklog: WRKLOG-2026-04-03


2026-03-05: PEM Certificate Chain Split

Problem: Need to extract individual certificates from a concatenated chain file for ISE certificate store import.

Context: ISE certificate deployment, splitting chain.pem into leaf, issuing CA, and root CA components.

The Fix:

awk '/-----BEGIN CERTIFICATE-----/{n++} n==1' chain.pem > leaf.pem
awk '/-----BEGIN CERTIFICATE-----/{n++} n==2' chain.pem > issuing-ca.pem
awk '/-----BEGIN CERTIFICATE-----/{n++} n==3' chain.pem > root-ca.pem

Rule: awk counter pattern — increment on BEGIN CERTIFICATE, print while counter equals target value. Works for any PEM bundle regardless of cert count. Adjust n==N for the position you want.

Worklog: WRKLOG-2026-03-05