Hamish Burke | 2025-06-30


Renewing with DigiCert

  1. Export DIGICERT_API_KEY as env var
    1. API calls need this in X-DC-DEVKEY header
  2. Create CSR normally with openssl
  3. Send renew request to digicert api
  4. Wait for issued status
  5. When received, get fullchain from API
  6. Reload service/push keys to LB

As mentioned here. use cron or task scheduler and run daily

Linux (bash)

# Using openssl to make CSR, could rotate keys, or use static
CSR_PEM=$(openssl req -new -sha256 -key server-key.pem -subj "/C=NZ/ST=Wellington/L=Wellington/O=PCBook/OU=CompSec/CN=*.pcbook.com" | sed -e '1,/BEGIN CERTIFICATE REQUEST/d' -e '/END CERTIFICATE REQUEST/,$d')

# POST request to digicert api
curl -sS \
  -H "X-DC-DEVKEY: $DIGICERT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "certificate":{
      "common_name":"*.pcbook.com",
      "csr":"'"$CSR_PEM"'",
      "signature_hash":"SHA256",
      "server_platform_id":"286",      # e.g. Nginx
      "validity_years":1,
      "organization_units":["Computer"]
    }
  }' \
  https://certcentral.digicert.com/services/v2/order/certificate \
| jq -r '.id' > order_id.txt


# Wait for cert api to issue certificate
ORDER_ID=$(cat order_id.txt)
until curl -sS \
  -H "X-DC-DEVKEY: $DIGICERT_API_KEY" \
  https://certcentral.digicert.com/services/v2/certificate/$ORDER_ID \
| jq -e '.status=="issued"'; do
  echo "Waiting for issuance…"
  sleep 15
done

# Get fullchain (includes itermediate certificates)
curl -sS \
  -H "X-DC-DEVKEY: $DIGICERT_API_KEY" \
https://certcentral.digicert.com/services/v2/certificate/$ORDER_ID/download/format/pem_all \
> /etc/ssl/certs/pcbook_fullchain.pem


# Reloa service
systemctl reload nginx # or similar

# if load balancer, push keys to LB if centralised, and reload
# rsync -az /etc/ssl/certs/*.pem lb1:/etc/ssl/certs/ && ssh lb1 systemctl reload haproxy

Windows (powershell)

$apiKey = $env:DIGICERT_API_KEY

$csr = Get-Content .\server-req.pem -Raw

$body = @{
  certificate = @{
    common_name = "*.domain.com"
    csr         = $csr
    signature_hash = "SHA256"
    server_platform_id = 286
    validity_years = 1
  }
} | ConvertTo-Json

# Order
$response = Invoke-RestMethod -Uri "https://certcentral.digicert.com/services/v2/order/certificate" `
  -Headers @{ "X-DC-DEVKEY" = $apiKey; "Content-Type" = "application/json" } `
  -Method POST -Body $body
$orderId = $response.id

# Poll until issued
do {
  Start-Sleep -Seconds 15
  $status = (Invoke-RestMethod -Uri "https://certcentral.digicert.com/services/v2/certificate/$orderId" `
    -Headers @{ "X-DC-DEVKEY" = $apiKey }).status
} until ($status -eq "issued")

# Download
Invoke-RestMethod -Uri "https://certcentral.digicert.com/services/v2/certificate/$orderId/download/format/pem_all" `
  -Headers @{ "X-DC-DEVKEY" = $apiKey } -OutFile "C:\Certs\pcbook_fullchain.pem"

# Reload IIS, nginx, whatever
Restart-Service -Name "W3SVC"