| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- #!/usr/bin/env bash
- # test-certs.sh — Generate throwaway test certs for unit tests in
- # internal/auth/mtls_test.go. NOT for production. Creates a temp
- # self-signed CA + a few leaf certs (valid, expired, wrong-CN, untrusted)
- # in scripts/cert-manager/testdata/ so tests can read them with
- # crypto/x509.ReadFile.
- #
- # Usage:
- # scripts/cert-manager/test-certs.sh
- # scripts/cert-manager/test-certs.sh clean # remove testdata
- #
- # Idempotent: regenerates the dir each run.
- set -euo pipefail
- TESTDATA="$(dirname "$0")/testdata"
- case "${1:-}" in
- clean)
- rm -rf "$TESTDATA"
- echo "removed $TESTDATA"
- exit 0
- ;;
- "")
- ;;
- *)
- echo "usage: $0 [clean]" >&2
- exit 1
- ;;
- esac
- rm -rf "$TESTDATA"
- mkdir -p "$TESTDATA"
- # --- Test CA (self-signed) -------------------------------------------------
- TEST_CA_KEY="$TESTDATA/test-ca.key"
- TEST_CA_CRT="$TESTDATA/test-ca.crt"
- openssl genrsa -out "$TEST_CA_KEY" 2048 2>/dev/null
- openssl req -new -x509 -key "$TEST_CA_KEY" -sha256 -days 365 \
- -subj "/CN=broad-announce Test CA/O=test/OU=test" \
- -addext "basicConstraints=critical,CA:TRUE" \
- -out "$TEST_CA_CRT"
- # Helper: generate a leaf signed by the test CA
- gen_leaf() {
- local name="$1" cn="$2" san="$3" days="$4"
- local key="$TESTDATA/${name}.key"
- local csr="$TESTDATA/${name}.csr"
- local crt="$TESTDATA/${name}.crt"
- openssl genrsa -out "$key" 2048 2>/dev/null
- if [[ -n "$san" ]]; then
- openssl req -new -key "$key" -sha256 \
- -subj "/CN=$cn/O=test/OU=test" \
- -addext "subjectAltName=$san" \
- -out "$csr"
- else
- openssl req -new -key "$key" -sha256 \
- -subj "/CN=$cn/O=test/OU=test" \
- -out "$csr"
- fi
- # Build extfile: include subjectAltName only if non-empty
- local extfile
- if [[ -n "$san" ]]; then
- extfile=$(mktemp)
- cat > "$extfile" <<EOF
- basicConstraints=CA:FALSE
- keyUsage=critical,digitalSignature,keyEncipherment
- extendedKeyUsage=clientAuth
- subjectAltName=$san
- EOF
- else
- extfile=$(mktemp)
- cat > "$extfile" <<'EOF'
- basicConstraints=CA:FALSE
- keyUsage=critical,digitalSignature,keyEncipherment
- extendedKeyUsage=clientAuth
- EOF
- fi
- openssl x509 -req -in "$csr" -CA "$TEST_CA_CRT" -CAkey "$TEST_CA_KEY" \
- -CAcreateserial -sha256 -days "$days" \
- -extfile "$extfile" \
- -out "$crt"
- rm -f "$extfile"
- }
- # --- Test fixtures ---------------------------------------------------------
- # source_cn format: source:<source_id>.<company_slug>
- gen_leaf "valid" "source:src-123.acme-001" "DNS:source.src-123.acme-001" 30
- gen_leaf "wrong-cn" "source:src-999.acme-001" "DNS:source.src-999.acme-001" 30
- gen_leaf "no-san" "source:src-789.acme-001" "" 30
- # Note: "expired" is generated in-memory in internal/auth/mtls_test.go
- # (template.NotAfter in the past), not as a file fixture, because openssl
- # refuses to sign certs with end-before-start dates.
- # An UNTRUSTED leaf — signed by a different CA
- UNTRUSTED_KEY="$TESTDATA/untrusted-ca.key"
- UNTRUSTED_CRT="$TESTDATA/untrusted-ca.crt"
- UNTRUSTED_LEAF_KEY="$TESTDATA/untrusted.key"
- UNTRUSTED_LEAF_CRT="$TESTDATA/untrusted.crt"
- openssl genrsa -out "$UNTRUSTED_KEY" 2048 2>/dev/null
- openssl req -new -x509 -key "$UNTRUSTED_KEY" -sha256 -days 30 \
- -subj "/CN=untrusted-attacker/O=evil/OU=evil" \
- -addext "basicConstraints=critical,CA:TRUE" \
- -out "$UNTRUSTED_CRT"
- openssl genrsa -out "$UNTRUSTED_LEAF_KEY" 2048 2>/dev/null
- openssl req -new -key "$UNTRUSTED_LEAF_KEY" -sha256 \
- -subj "/CN=source:src-123.acme-001/O=evil/OU=evil" \
- -addext "subjectAltName=DNS:source.src-123.acme-001" \
- -out "$TESTDATA/untrusted.csr"
- openssl x509 -req -in "$TESTDATA/untrusted.csr" -CA "$UNTRUSTED_CRT" -CAkey "$UNTRUSTED_KEY" \
- -CAcreateserial -sha256 -days 30 \
- -extfile <(echo "extendedKeyUsage=clientAuth") \
- -out "$UNTRUSTED_LEAF_CRT"
- # --- Write a manifest for the tests ----------------------------------------
- cat > "$TESTDATA/MANIFEST.txt" <<EOF
- test-ca.crt — self-signed test CA (the trust anchor for tests)
- test-ca.key — test CA private key (DO NOT use in prod)
- valid.{key,crt} — leaf with correct CN/SAN, valid 30d
- wrong-cn.{key,crt} — leaf with correct format but wrong source_id in CN
- no-san.{key,crt} — leaf with correct CN but no SAN
- untrusted.{key,crt} — leaf signed by an UNTRUSTED CA (simulates attacker)
- untrusted-ca.{key,crt} — the attacker's CA
- Note: "expired" fixture is generated in-memory in
- internal/auth/mtls_test.go (template.NotAfter in the past), not as a
- file fixture, because openssl refuses to sign certs with
- end-before-start dates.
- Production uses scripts/cert-manager/ca-init.sh to generate the real PKI.
- This dir is .gitignored.
- EOF
- echo "test certs generated in $TESTDATA"
- ls "$TESTDATA" | head
|