#!/usr/bin/env bash set -euo pipefail real_openssl="${BURROW_REAL_OPENSSL:-openssl}" gcloud_bin="${BURROW_GCLOUD_BIN:-gcloud}" original_args=("$@") exec_real_openssl() { exec "$real_openssl" "$@" } truthy() { case "${1:-}" in 1|true|TRUE|True|yes|YES|Yes|y|Y|on|ON|On) return 0 ;; *) return 1 ;; esac } parse_pkcs11_key_name() { local uri="$1" local value value="${uri#*;object=}" if [[ "$value" != "$uri" ]]; then printf '%s\n' "${value%%;*}" return 0 fi value="${uri#*;id=}" if [[ "$value" != "$uri" ]]; then printf '%s\n' "${value%%;*}" return 0 fi return 1 } select_single_enabled_version() { local project_id="$1" local kms_location="$2" local kms_keyring_name="$3" local crypto_key_name="$4" local versions=() local version while IFS= read -r version; do [[ -n "$version" ]] && versions+=("$version") done < <( "$gcloud_bin" kms keys versions list \ --project="$project_id" \ --location="$kms_location" \ --keyring="$kms_keyring_name" \ --key="$crypto_key_name" \ --filter=state=ENABLED \ --format='value(name)' ) if [[ "${#versions[@]}" -ne 1 || -z "${versions[0]:-}" ]]; then echo "error: Google KMS crypto key ${crypto_key_name} has ${#versions[@]} ENABLED versions; set BURROW_GCP_KMS_ACTIVE_CRYPTO_KEY_VERSION" >&2 return 1 fi printf '%s\n' "${versions[0]##*/}" } if [[ "${1:-}" != "dgst" ]]; then exec_real_openssl "${original_args[@]}" fi if ! truthy "${BURROW_APPLE_PKCS11_SIGN_WITH_GCLOUD:-true}"; then exec_real_openssl "${original_args[@]}" fi shift digest_algorithm="" signature_file="" input_file="" sign_uri="" while [[ $# -gt 0 ]]; do case "$1" in -sha256) digest_algorithm="sha256" shift ;; -sign) [[ $# -ge 2 ]] || { echo "error: openssl dgst shim received -sign without a key URI" >&2 exit 2 } sign_uri="$2" shift 2 ;; -out) [[ $# -ge 2 ]] || { echo "error: openssl dgst shim received -out without a path" >&2 exit 2 } signature_file="$2" shift 2 ;; -provider|-passin) [[ $# -ge 2 ]] || { echo "error: openssl dgst shim received $1 without a value" >&2 exit 2 } shift 2 ;; -*) exec_real_openssl "${original_args[@]}" ;; *) input_file="$1" shift ;; esac done if [[ "$digest_algorithm" != "sha256" || "$sign_uri" != pkcs11:* ]]; then exec_real_openssl "${original_args[@]}" fi if [[ -z "$signature_file" || -z "$input_file" ]]; then echo "error: openssl dgst shim requires -out and an input file" >&2 exit 2 fi if [[ ! -f "$input_file" ]]; then echo "error: openssl dgst shim input file does not exist: $input_file" >&2 exit 1 fi command -v "$gcloud_bin" >/dev/null 2>&1 || { echo "error: gcloud is required for Google KMS direct signing; set BURROW_GCLOUD_BIN" >&2 exit 1 } command -v python3 >/dev/null 2>&1 || { echo "error: python3 is required to decode Google KMS signatures" >&2 exit 1 } crypto_key="${BURROW_GCP_KMS_ACTIVE_CRYPTO_KEY:-}" if [[ -z "$crypto_key" ]]; then crypto_key="$(parse_pkcs11_key_name "$sign_uri" || true)" fi if [[ -z "$crypto_key" ]]; then echo "error: BURROW_GCP_KMS_ACTIVE_CRYPTO_KEY or a pkcs11 object selector is required" >&2 exit 1 fi key_version="${BURROW_GCP_KMS_ACTIVE_CRYPTO_KEY_VERSION:-}" key_ring="${BURROW_GCP_KMS_KEY_RING:-${GOOGLE_KMS_KEY_RING:-projects/${GOOGLE_CLOUD_PROJECT:-project-88c23ce9-918a-470a-b33}/locations/${BURROW_KMS_LOCATION:-global}/keyRings/${BURROW_KMS_KEYRING:-burrow-identity}}}" project_id="${GOOGLE_CLOUD_PROJECT:-project-88c23ce9-918a-470a-b33}" kms_location="" kms_keyring_name="" crypto_key_name="" if [[ "$crypto_key" =~ ^projects/([^/]+)/locations/([^/]+)/keyRings/([^/]+)/cryptoKeys/([^/]+)/cryptoKeyVersions/([^/]+)$ ]]; then project_id="${BASH_REMATCH[1]}" kms_location="${BASH_REMATCH[2]}" kms_keyring_name="${BASH_REMATCH[3]}" crypto_key_name="${BASH_REMATCH[4]}" key_version="${BASH_REMATCH[5]}" elif [[ "$crypto_key" =~ ^projects/([^/]+)/locations/([^/]+)/keyRings/([^/]+)/cryptoKeys/([^/]+)$ ]]; then project_id="${BASH_REMATCH[1]}" kms_location="${BASH_REMATCH[2]}" kms_keyring_name="${BASH_REMATCH[3]}" crypto_key_name="${BASH_REMATCH[4]}" else if [[ ! "$key_ring" =~ ^projects/([^/]+)/locations/([^/]+)/keyRings/([^/]+)$ ]]; then echo "error: BURROW_GCP_KMS_KEY_RING must be projects//locations//keyRings/, got: ${key_ring}" >&2 exit 1 fi project_id="${BASH_REMATCH[1]}" kms_location="${BASH_REMATCH[2]}" kms_keyring_name="${BASH_REMATCH[3]}" crypto_key_name="$crypto_key" fi if [[ -z "$key_version" ]]; then key_version="$(select_single_enabled_version "$project_id" "$kms_location" "$kms_keyring_name" "$crypto_key_name")" fi encoded_signature_file="$(mktemp "${TMPDIR:-/tmp}/burrow-google-kms-signature.XXXXXX")" trap 'rm -f "$encoded_signature_file"' EXIT "$gcloud_bin" kms asymmetric-sign \ --project="$project_id" \ --location="$kms_location" \ --keyring="$kms_keyring_name" \ --key="$crypto_key_name" \ --version="$key_version" \ --digest-algorithm="$digest_algorithm" \ --input-file="$input_file" \ --signature-file="$encoded_signature_file" \ --quiet >/dev/null python3 - "$encoded_signature_file" "$signature_file" <<'PY' import base64 import pathlib import sys encoded_path = pathlib.Path(sys.argv[1]) signature_path = pathlib.Path(sys.argv[2]) signature_path.write_bytes(base64.b64decode(encoded_path.read_text(encoding="utf-8").strip())) PY