#!/usr/bin/env bash # minisign signing script for token lists # Signs token list files for integrity verification set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" TOKEN_LISTS_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" LISTS_DIR="$TOKEN_LISTS_DIR/lists" TOKEN_LIST_FILE="$LISTS_DIR/dbis-138.tokenlist.json" PUBLIC_KEY_FILE="$TOKEN_LISTS_DIR/minisign.pub" SIGNATURE_FILE="${TOKEN_LIST_FILE}.sig" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } # Check if minisign is available if ! command -v minisign &> /dev/null; then log_error "minisign is required but not installed" log_info "Installation:" log_info " macOS: brew install minisign" log_info " Ubuntu/Debian: apt-get install minisign" log_info " From source: https://github.com/jedisct1/minisign" exit 1 fi # Generate keypair (only if keys don't exist) generate_keypair() { local private_key_file="${MINISIGN_PRIVATE_KEY_FILE:-$TOKEN_LISTS_DIR/minisign.key}" if [[ -f "$private_key_file" ]]; then log_warn "Private key already exists: $private_key_file" log_info "Skipping key generation" return 0 fi log_info "Generating minisign keypair..." log_info "Private key will be saved to: $private_key_file" log_info "Public key will be saved to: $PUBLIC_KEY_FILE" log_warn "Keep the private key secure and never commit it to the repository!" # Generate keypair (minisign will prompt for password) if minisign -G -s "$private_key_file" -p "$PUBLIC_KEY_FILE"; then log_success "Keypair generated successfully" log_info "" log_info "Next steps:" log_info "1. Store the private key securely (e.g., password manager, secure vault)" log_info "2. Add private key to GitHub Secrets as MINISIGN_PRIVATE_KEY" log_info "3. Commit the public key: git add $PUBLIC_KEY_FILE" log_info "4. Set MINISIGN_PRIVATE_KEY_FILE environment variable if using custom path" else log_error "Failed to generate keypair" exit 1 fi } # Sign token list sign_list() { local private_key_file="${MINISIGN_PRIVATE_KEY_FILE:-$TOKEN_LISTS_DIR/minisign.key}" local private_key_content="${MINISIGN_PRIVATE_KEY:-}" if [[ ! -f "$TOKEN_LIST_FILE" ]]; then log_error "Token list file not found: $TOKEN_LIST_FILE" exit 1 fi log_info "Signing token list: $TOKEN_LIST_FILE" # Check if private key exists or is provided via environment if [[ -n "$private_key_content" ]]; then # Use private key from environment variable log_info "Using private key from MINISIGN_PRIVATE_KEY environment variable" echo "$private_key_content" | minisign -S -s /dev/stdin -m "$TOKEN_LIST_FILE" -x "$SIGNATURE_FILE" || { log_error "Failed to sign token list" exit 1 } elif [[ -f "$private_key_file" ]]; then # Use private key file minisign -S -s "$private_key_file" -m "$TOKEN_LIST_FILE" -x "$SIGNATURE_FILE" || { log_error "Failed to sign token list" exit 1 } else log_error "Private key not found" log_info "Provide private key via:" log_info " 1. File: Set MINISIGN_PRIVATE_KEY_FILE environment variable" log_info " 2. Environment: Set MINISIGN_PRIVATE_KEY environment variable" log_info " 3. Generate new: Run '$0 --generate-key'" exit 1 fi log_success "Token list signed successfully" log_info "Signature file: $SIGNATURE_FILE" # Display signature info if [[ -f "$SIGNATURE_FILE" ]]; then log_info "" log_info "Signature preview:" head -n 2 "$SIGNATURE_FILE" | head -c 100 echo "..." log_info "" fi } # Verify signature verify_signature() { if [[ ! -f "$TOKEN_LIST_FILE" ]]; then log_error "Token list file not found: $TOKEN_LIST_FILE" exit 1 fi if [[ ! -f "$SIGNATURE_FILE" ]]; then log_error "Signature file not found: $SIGNATURE_FILE" exit 1 fi if [[ ! -f "$PUBLIC_KEY_FILE" ]]; then log_error "Public key file not found: $PUBLIC_KEY_FILE" log_info "Public key should be at: $PUBLIC_KEY_FILE" exit 1 fi log_info "Verifying signature..." if minisign -V -p "$PUBLIC_KEY_FILE" -m "$TOKEN_LIST_FILE" -x "$SIGNATURE_FILE"; then log_success "Signature verification passed!" return 0 else log_error "Signature verification failed!" return 1 fi } # Main main() { local command="${1:-sign}" case "$command" in --generate-key|-g) generate_keypair ;; --sign|-s) sign_list ;; --verify|-v) verify_signature ;; sign) sign_list ;; verify) verify_signature ;; *) echo "Usage: $0 [command]" echo "" echo "Commands:" echo " sign, -s Sign the token list (default)" echo " verify, -v Verify the signature" echo " --generate-key, -g Generate a new keypair" echo "" echo "Environment variables:" echo " MINISIGN_PRIVATE_KEY_FILE Path to private key file" echo " MINISIGN_PRIVATE_KEY Private key content (for CI/CD)" exit 1 ;; esac } main "${1:-sign}"