Ctrl K
ComunidadGuías…

docs/verify-profile.sh

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bash
# verify-profile.sh — issue a throwaway leaf via the Vault PKI c2pa-leaf
# role and assert the strict KU/EKU/BasicConstraints profile. Fails
# non-zero on drift so this can be wired into CI.
#
# Requires:
#   VAULT_ADDR, VAULT_TOKEN  in env
#   openssl, jq              on PATH
#   curl                     on PATH
#
# Optional:
#   VAULT_CACERT             path to CA bundle for self-signed Vault TLS
#   MOUNT                    PKI mount path (default: pki-c2pa)
#   ROLE                     role name (default: c2pa-leaf)

set -euo pipefail

MOUNT="${MOUNT:-pki-c2pa}"
ROLE="${ROLE:-c2pa-leaf}"

if [[ -z "${VAULT_ADDR:-}" || -z "${VAULT_TOKEN:-}" ]]; then
  echo "FATAL: VAULT_ADDR and VAULT_TOKEN must be set" >&2
  exit 2
fi

WORK="$(mktemp -d)"
trap 'rm -rf "$WORK"' EXIT

# 1. Generate a throwaway P-256 keypair + CSR.
openssl ecparam -name prime256v1 -genkey -noout -out "$WORK/leaf.key.pem" 2>/dev/null
openssl req -new -key "$WORK/leaf.key.pem" \
  -subj "/CN=cuecrux daemon C2PA signer (verify-profile)" \
  -out "$WORK/leaf.csr.pem" 2>/dev/null

# 2. POST the CSR to Vault, signed by the c2pa-leaf role.
CURL_OPTS=(--silent --show-error --fail)
if [[ -n "${VAULT_CACERT:-}" ]]; then
  CURL_OPTS+=(--cacert "$VAULT_CACERT")
fi

REQ_BODY="$(jq -n \
  --arg csr "$(cat "$WORK/leaf.csr.pem")" \
  '{csr: $csr, common_name: "cuecrux daemon C2PA signer", ttl: "1h"}')"

curl "${CURL_OPTS[@]}" \
  -H "X-Vault-Token: $VAULT_TOKEN" \
  -H "Content-Type: application/json" \
  -X POST \
  -d "$REQ_BODY" \
  "$VAULT_ADDR/v1/$MOUNT/sign/$ROLE" \
  | jq -r .data.certificate > "$WORK/leaf.cert.pem"

if [[ ! -s "$WORK/leaf.cert.pem" ]]; then
  echo "FATAL: Vault returned empty certificate" >&2
  exit 3
fi

# 3. Decode the leaf and assert the strict profile.
TEXT="$(openssl x509 -in "$WORK/leaf.cert.pem" -noout -text)"

# KU = Digital Signature only.
if ! echo "$TEXT" | grep -A1 'X509v3 Key Usage' | grep -E 'Digital Signature$' > /dev/null; then
  echo "FAIL: leaf KU is not exactly 'Digital Signature'" >&2
  echo "$TEXT" | grep -A1 'X509v3 Key Usage' >&2
  exit 4
fi
if echo "$TEXT" | grep -A1 'X509v3 Key Usage' | grep -E 'Certificate Sign|CRL Sign|Key Encipherment|Key Agreement' > /dev/null; then
  echo "FAIL: leaf KU includes extra bits beyond Digital Signature" >&2
  exit 5
fi

# EKU = E-mail Protection only.
if ! echo "$TEXT" | grep -A1 'X509v3 Extended Key Usage' | grep -E '^[ ]*E-mail Protection$' > /dev/null; then
  echo "FAIL: leaf EKU is not exactly 'E-mail Protection'" >&2
  echo "$TEXT" | grep -A1 'X509v3 Extended Key Usage' >&2
  exit 6
fi
if echo "$TEXT" | grep -A1 'X509v3 Extended Key Usage' | grep -E 'TLS Web|Code Signing|OCSP|Time Stamping' > /dev/null; then
  echo "FAIL: leaf EKU includes extra purposes" >&2
  exit 7
fi

# BasicConstraints CA:FALSE asserted (NOT absent — the constraint must be present).
if ! echo "$TEXT" | grep -A1 'X509v3 Basic Constraints' | grep -E 'CA:FALSE' > /dev/null; then
  echo "FAIL: leaf BasicConstraints is not 'CA:FALSE' (missing or CA:TRUE)" >&2
  echo "$TEXT" | grep -A1 'X509v3 Basic Constraints' >&2
  exit 8
fi

# Public key algorithm = P-256.
if ! echo "$TEXT" | grep -E 'Public Key Algorithm: id-ecPublicKey' > /dev/null; then
  echo "FAIL: leaf is not P-256 / id-ecPublicKey" >&2
  exit 9
fi
if ! echo "$TEXT" | grep -E 'ASN1 OID: prime256v1' > /dev/null; then
  echo "FAIL: leaf curve is not prime256v1 / secp256r1" >&2
  exit 10
fi

# Signature algorithm = ecdsa-with-SHA256.
if ! echo "$TEXT" | grep -E 'Signature Algorithm: ecdsa-with-SHA256' > /dev/null; then
  echo "FAIL: leaf signature alg is not ecdsa-with-SHA256" >&2
  exit 11
fi

echo "PROFILE OK: leaf has KU=DigitalSignature only, EKU=EmailProtection only,"
echo "            BasicConstraints CA:FALSE asserted, P-256 + ecdsa-with-SHA256."