Last active
January 30, 2025 20:51
Revisions
-
zx0r revised this gist
Jan 30, 2025 . 1 changed file with 7 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -265,6 +265,9 @@ configure_gnupghome() { # Configure GPG to use pinentry-mac curl -fOsSL --output-dir $dir $download_url/gpg-agent.conf curl -fOsSL --output-dir $dir $download_url/gpg.conf # To send the keys to the OpenPgp keyserver: gpg --keyserver keys.openpgp.org --send-key $(gpg --list-secret-keys --with-keygrip --with-colons | grep '^sec:' | awk -F: '{print $5}') # Get current GPG key ID KEY_ID=$(gpg --list-secret-keys --keyid-format=long | grep sec | head -1 | cut -d'/' -f2 | cut -d' ' -f1) @@ -514,9 +517,12 @@ configure_git_gpg() { echo -e " ${GREEN} Your GPG public key for GitHub: ${NC}" echo -e "\n${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" # Add to github repository (var 1) # gpg --armor --export $(gpg --list-secret-keys --with-keygrip --with-colons | grep '^sec:' | awk -F: '{print $5}') # Add to github repository(var 2) gpg --armor --export "$GPG_KEY_ID" } ptint_hints() { -
zx0r revised this gist
Jan 30, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -146,7 +146,7 @@ install_dependencies() { # Install gnupg and pinentry-mac if not already installed if ! is_installed gpg || ! is_installed pinentry-mac || ! is_installed smimesign; then print_step "Installing gnupg and pinentry-mac and smimesign..." brew install gnupg pinentry-mac smimesign else print_step "Update Homebrew and upgrade existing packages" brew doctor && brew update && brew upgrade && brew cleanup && brew doctor -
zx0r revised this gist
Jan 30, 2025 . 1 changed file with 626 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,626 @@ #!/usr/bin/env bash # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # :::::::: :::: ::: ::: ::: ::::::::: :::::::: # :+: :+: :+:+: :+: :+: :+: :+: :+: :+: :+: # +:+ :+:+:+ +:+ +:+ +:+ +:+ +:+ +:+ # :#: +#+ +:+ +#+ +#+ +:+ +#++:++#+ :#: # +#+ #+#+# +#+ +#+#+# +#+ +#+ +#+ +#+ #+#+# # #+# #+# #+# #+#+# #+# #+# #+# #+# #+# # ######## ### #### ######## ### ######## # Copyright (c) 2025 zx0r. All rights reserved. # Script: setup-gpg-git-macos.sh # Author: zx0r # License: MIT License # Contact Info: https:#github.com/zx0r # Version: 1.0 # Date: 2025-01-20 # Description: This script installs and configures GnuPG (GPG) for macOS, # sets up Git to use GPG for signing commits and ensures # security settings are applied.It also auto-detects the user # shell, configures GUI App to use GPG for commits and setup # launch agent for gpg-agent # “Stay Hungry, Stay Foolish.” # - Steve Jobs Apple # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # Enable strict handling set -euo pipefail IFS=$'\n\t' # Regular Colors BLACK='\033[0;30m' # Black RED='\033[0;31m' # Red GREEN='\033[0;32m' # Green CYAN='\033[0;33m' # CYAN BLUE='\033[1;34m' # Blue CYAN='\033[1;34m' # Blue YELLOW='\033[1;33m' # Yellow PURPLE='\033[0;35m' # Purple CYAN='\033[1;36m' # Cyan WHITE='\033[0;37m' # White BWHITE='\033[1;37m' # Bold White NC='\033[0m' # Text Rese# Function to check if a package is installed # Function to print a step message print_step() { local step_name="$1" echo -e "${BLUE} ➜ ${step_name}${NC}" } # Print colorful messages print_message() { echo -e "${CYAN}💭 $1${NC}" } # Print Success message print_success() { echo -e "\n${GREEN}✅ $1${NC}\n" } # Print Warnining message print_warn() { echo -e "${YELLOW}[Warn] $1${NC}" } # Print Error message and exit print_error() { echo -e "${RED}❗️$1${NC}" exit 1 } # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Main ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # Main function to orchestrate the setup process main() { # First Phase - Setup initialize_installation # Start install_dependencies # Install GPG and related tools detect_shell # Detect the user's shell create_gpg_dir # Create $HOME/.gnupg generate_gpg_key # Generate a new GPG key (if needed) configure_gnupghome # Configure gpg.conf gpg-agent.conf # Second Phase - Configuration configure_vscode_gpg # Configure VSCode/VSCodium to use GPG for commits configure_gui_git_signing # Configure Git to use GPG for signing commits configure_gpg_agent_launch_agent # Set up gpg-agent as a launch agent apply_security_settings # Apply additional security settings configure_ssh_signing # (Option) SSH Key Signing # configure_smime_signing # (Option) S/MIME Signing using smimesign configure_git_gpg # Configure Git commit signing # Third Phase - Verification ptint_hints # Displaying hints #export_gpg_key # Export GPG Key verify_setup # Functional check complete_installation # End # Reload Shell reload_shell # Reload Shell } # ━━━━━━━━━━━━━━━━━━━━━━━━━━━ First Phase - Setup ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ initialize_installation() { print_category "Initialization" print_step "Starting installation process..." } print_category() { local category_name="$1" echo -e "\n${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━${NC} ${PURPLE}${category_name}${NC} ━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" # step_counter=1 # Reset step counter for each new category } is_installed() { local package_name=$1 if command -v "$package_name" &>/dev/null; then return 0 # Package is installed else return 1 # Package is not installed fi } # Install required packages install_dependencies() { print_step "Installing dependencies..." # Check if Homebrew is installed, and install it if not if ! command -v brew &>/dev/null; then print_step "Homebrew not found. Installing Homebrew..." /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" else print_success "Homebrew is already installed." fi # Install gnupg and pinentry-mac if not already installed if ! is_installed gpg || ! is_installed pinentry-mac || ! is_installed smimesign; then print_step "Installing gnupg and pinentry-mac and smimesign..." brew install gnupg pinentry-mac else print_step "Update Homebrew and upgrade existing packages" brew doctor && brew update && brew upgrade && brew cleanup && brew doctor fi } # Function to detect the user's shell detect_shell() { shell_name=$(basename "$SHELL") # Determine the shell configuration file case "$shell_name" in bash) shell_config="$HOME/.bashrc" ;; zsh) shell_config="$HOME/.zshrc" ;; fish) shell_config="$HOME/.config/fish/config.fish" ;; *) print_warn "Unsupported shell: $shell_name. Please manually configure your shell." exit 1 ;; esac print_step "Detected shell: ${GREEN}$shell_name{NC}" print_step "Using configuration file: ${GREEN}$shell_config${NC}" export SHELL_NAME="$shell_name" export SHELL_CONFIG="$shell_config" } # Configure GPG create_gpg_dir() { local dir="$HOME/.gnupg" # Check if the directory exists; if not, create it if [[ ! -d "$dir" ]]; then print_step "Creating GnuPG directory: ${GREEN}$dir${NC}" # Create GPG config directory mkdir -p "$dir" || print_error "Failed to create directory: $dir" # Set proper permissions chmod 700 $HOME/.gnupg fi } # Function to generate a new GPG key generate_gpg_key() { print_step "Generating a new GPG key..." # Collect user information securely read -rp "Enter Your Name for GPG key: " NAME read -rp "Enter Your Email for GPG key: " EMAIL read -rsp "[Secure Mode] Enter passphrase for GPG key: " PASSPHRASE echo # Ensure clean GPG agent state gpgconf --kill gpg-agent gpg-agent --daemon # Generate key with secure parameters # Name-Real: $(git config user.name) # Name-Email: $(git config user.email) # Name-Comment: GITHUB-KEY gpg --batch --generate-key <<EOF Key-Type: RSA Key-Length: 4096 Subkey-Type: RSA Subkey-Length: 4096 Name-Real: $NAME Name-Email: $EMAIL Passphrase: $PASSPHRASE Expire-Date: 0 %commit EOF GPG_KEY_ID=$(gpg --list-secret-keys --keyid-format LONG | grep sec | tail -1 | awk '{print $2}' | cut -d'/' -f2) print_success "GPG key generated successfully with passphrase protection" print_step "GPG key details:" print_step "• Name: ${GREEN}$NAME${NC}" print_step "• Email: ${GREEN}$EMAIL${NC}" print_step "• KEY ID: ${GREEN}${GPG_KEY_ID}{NC}" } configure_gnupghome() { dir="$HOME/.gnupg" download_url="https://gist.githubusercontent.com/zx0r/843298b67cd91a0835dcf36aada529d5/raw/15a8954620cad5c9bd066237bf210ba475da3014" # Set GPG to use the TTY for passphrase prompts export GPG_TTY=$(tty) export GPG_DIR="$HOME/.gnupg" # Add GPG_TTY to the user's shell configuration file if [[ "$SHELL_NAME" == "zsh" ]]; then echo 'export GPG_TTY=$(tty)' >>"$SHELL_CONFIG" echo "export GNUPGHOME=$GPG_DIR" >>"$SHELL_CONFIG" elif [[ "$SHELL_NAME" == "bash" ]]; then echo 'export GPG_TTY=$(tty)' >>"$SHELL_CONFIG" echo "export GNUPGHOME=$GPG_DIR" >>"$SHELL_CONFIG" elif [[ "$SHELL_NAME" == "fish" ]]; then echo 'set -gx GPG_TTY $(tty)' >>"$SHELL_CONFIG" echo "set -gx GNUPGHOME $GPG_DIR" >>"$SHELL_CONFIG" else print_warn "Unsupported shell. Please manually add 'export GPG_TTY=\$(tty)' to your shell configuration file." fi # Configure GPG to use pinentry-mac curl -fOsSL --output-dir $dir $download_url/gpg-agent.conf curl -fOsSL --output-dir $dir $download_url/gpg.conf # Get current GPG key ID KEY_ID=$(gpg --list-secret-keys --keyid-format=long | grep sec | head -1 | cut -d'/' -f2 | cut -d' ' -f1) # Set it as `default-key` in ~/.gnupg/gpg.conf sed -i '' "s/\(default-key \)[^ ]*/\1$KEY_ID/" ~/.gnupg/gpg.conf print_success "Download files ${BLUE}$dir/gpg-agent.conf and $dir/gpg.conf${NC} completed${NC}" } # Function to configure Git signing in GUI applications (e.g., Git Tower, GitHub Desktop) configure_gui_git_signing() { print_step "Configuring Git signing for GUI applications..." # Get the GPG key ID GPG_KEY_ID=$(gpg --list-secret-keys --keyid-format LONG | grep sec | tail -1 | awk '{print $2}' | cut -d'/' -f2) # Configure Git Tower if [[ -d "/Applications/Git Tower.app" ]]; then echo "✓ Configuring Git Tower signing..." cat >~/.gitconfig.tower <<EOF [commit] gpgsign = true signingkey = $GPG_KEY_ID EOF sleep 1 git config --global include.path ~/.gitconfig.tower fi # Configure GitHub Desktop if [[ -d "/Applications/GitHub Desktop.app" ]]; then print_success "Configuring GitHub Desktop signing..." cat >~/.gitconfig.github <<EOF [commit] gpgsign = true signingkey = $GPG_KEY_ID EOF sleep 1 git config --global include.path ~/.gitconfig.github fi print_success "Git signing configured for GUI applications" } # ━━━━━━━━━━━━━━━━━━━━━━━━━━━ Second Phase - Configuration ━━━━━━━━━━━━━━━━━━━━━━━━━━ configure_vscode_gpg() { local extensions=( "wdhongtw.gpg-indicator" "jheilingbrunner.vscode-gnupg-tool" ) local settings='{"git.enableCommitSigning": true}' if command -v code &>/dev/null; then print_step "Configuring VSCode for GPG commit signing..." for ext in "${extensions[@]}"; do code --force --install-extension "$ext" done # code --wait --reuse-window --settings-json "$settings" print_step "VSCode GPG signing configuration complete" elif command -v codium &>/dev/null; then print_step "Configuring VSCodium for GPG commit signing..." for ext in "${extensions[@]}"; do codium --force --install-extension "$ext" done # codium --wait --reuse-window --settings-json "$settings" print_success "VSCodium GPG signing configuration complete" else print_warn "✗ No compatible editor found (VSCode/VSCodium)" return 1 fi } configure_gpg_agent_launch_agent() { echo "Setting up gpg-agent as a launch agent..." # Define paths with more descriptive names readonly LOCAL_BIN_DIR="$HOME/.local/bin" readonly GPG_START_SCRIPT="$LOCAL_BIN_DIR/start-gpg-agent.sh" readonly LAUNCH_AGENTS_DIR="$HOME/Library/LaunchAgents" readonly GPG_AGENT_PLIST="$LAUNCH_AGENTS_DIR/org.gnupg.gpg-agent.plist" # Source URLs readonly PLIST_URL="https://gist.githubusercontent.com/zx0r/843298b67cd91a0835dcf36aada529d5/raw/6673f8ee76898aa8f8f59cfdbfb14728481b1276/org.gnupg.gpg-agent.plist" readonly SCRIPT_URL="https://gist.githubusercontent.com/zx0r/843298b67cd91a0835dcf36aada529d5/raw/6673f8ee76898aa8f8f59cfdbfb14728481b1276/startup-gpg-agent.sh" # Create required directories for dir in "$LOCAL_BIN_DIR" "$LAUNCH_AGENTS_DIR"; do if [[ ! -d "$dir" ]]; then mkdir -p "$dir" || { echo "Failed to create directory: $dir" return 1 } echo "Created directory: $dir" fi done # Download files with error checking if ! curl -fsSL "$PLIST_URL" -o "$GPG_AGENT_PLIST"; then print_warn "Failed to download plist file" return 1 fi if ! curl -fsSL "$SCRIPT_URL" -o "$GPG_START_SCRIPT"; then print_warn "Failed to download start script" return 1 fi # Set correct permissions chmod +x "$GPG_START_SCRIPT" # Load the launch agent launchctl load -w "$GPG_AGENT_PLIST" print_success "GPG agent launch agent setup complete" print_step "Installed files:" print_step "• Launch Agent: ${GREEN}$GPG_AGENT_PLIST${NC}" print_step "• Start Script: ${GREEN}$GPG_START_SCRIPT${NC}" } # Function to apply additional security settings apply_security_settings() { echo "Applying additional security settings..." # Start GPG agent if not running if ! gpg-connect-agent /bye >/dev/null 2>&1; then echo "Starting GPG agent..." gpg-agent --daemon fi # Set recommended security configurations gpg-connect-agent "scd serialno" /bye >/dev/null 2>&1 gpg-connect-agent "learn --force" /bye >/dev/null 2>&1 print_success "Security settings applied successfully." } configure_ssh_signing() { # Define constants readonly SSH_DIR="$HOME/.ssh" readonly SSH_KEY="$SSH_DIR/id_ed25519" GPG_DIR="$HOME/.gnupg" SSHCONTROL="$GPG_DIR/sshcontrol" KEYGRIPS="$(gpg --list-keys --with-keygrip | awk '/^sub/{p=1;next} /Keygrip/{if(p){print $3;p=0}}')" # for Fish Shell FISH_PATH="$HOME/.config/fish/functions" SSH_AGENT_FISH_URL="https://gist.githubusercontent.com/zx0r/843298b67cd91a0835dcf36aada529d5/raw/d59f1f8ca738241c6cb34da8055f417cee73dd86/ssh_agent.fish" GPG_SSH_FISH_URL="https://gist.githubusercontent.com/zx0r/843298b67cd91a0835dcf36aada529d5/raw/d59f1f8ca738241c6cb34da8055f417cee73dd86/gpg_ssh_agent.fish" SSHCONTROL_URL="https://gist.githubusercontent.com/zx0r/843298b67cd91a0835dcf36aada529d5/raw/deaa0d4c123baad306c0b3e8e78289e985587cd6/sshcontrol" SSH_CONFIG="https://gist.githubusercontent.com/zx0r/843298b67cd91a0835dcf36aada529d5/raw/5f946ee0bc44f0fe122f19e4461ef07a8e24e3cc/config" # Create SSH directory with proper permissions if [[ ! -d "$SSH_DIR" ]]; then mkdir -p "$SSH_DIR" chmod 700 "$SSH_DIR" fi # Generate SSH key if needed if [[ ! -f "$SSH_KEY" ]]; then ssh-keygen -t ed25519 -C "git-signing-key" -f "$SSH_KEY" -N "" chmod 600 "$SSH_KEY" chmod 644 "${SSH_KEY}.pub" fi # Generate SSH key if needed if [[ ! -f "$SSH_DIR/config" ]]; then curl -fsSL "$SSH_CONFIG" -o "$SSH_DIR/config" || print_warn "Failed to download $SSH_DIR/config" chmod 600 "$SSH_DIR/config" else mv "$SSH_DIR/config" "$SSH_DIR/config.bak" fi # Add SSH key with keychain integration ssh-add --apple-use-keychain $SSH_DIR/id_ed25519 # Configure Git signing git config --global gpg.format ssh git config --global user.signingkey "$(cat ${SSH_KEY}.pub)" git config --global commit.gpgsign true # Setup GPG directory and sshcontrol mkdir -p "$GPG_DIR" chmod 700 "$GPG_DIR" # Extract and add keygrips curl -fsSL "$SSHCONTROL_URL" -o "$GPG_DIR/sshcontrol" || print_warn "Failed to download $GPG_DIR/sshcontrol" # Add keygrips to sshcontrol if [[ -n "$KEYGRIPS" ]]; then echo "$KEYGRIPS" >>"$SSHCONTROL" chmod 600 "$SSHCONTROL" print_success "SSH control configured with keygrips" fi # Download ssh_agent.fish if [[ "$SHELL_NAME" == "fish" ]]; then curl -fsSL "$SSH_AGENT_FISH_URL" -o "$FISH_PATH/ssh_agent.fish" || print_warn "Failed to download $FISH_PATH/ssh_agent.fish" curl -fsSL "$GPG_SSH_FISH_URL" -o "$FISH_PATH/gpg_ssh_agent.fish" || print_warn "Failed to download $FISH_PATH/gpg_ssh_agent.fish" print_step "Download competed: ${GREEN}$FISH_PATH/ssh_agent.fish and $FISH_PATH/gpg_ssh_agent.fish${NC}" fi print_success "SSH signing setup complete!" print_step "Public key: ${BLUE}$(cat ${SSH_KEY}.pub)${NC}" } # S/MIME Signing using smimesign configure_smime_signing() { # Configure Git to use smimesign git config --global gpg.x509.program smimesign git config --global gpg.format x509 git config --global commit.gpgsign true print_success "S/MIME Signing using smimesign configured" } configure_git_gpg() { # Get the GPG key ID GPG_KEY_ID=$(gpg --list-secret-keys --keyid-format LONG | grep sec | tail -1 | awk '{print $2}' | cut -d'/' -f2) # GPG_KEY_ID=$(gpg --list-secret-keys --with-keygrip --with-colons | grep '^sec:' | awk -F: '{print $5}') # Check and clean existing GPG settings if git config --list --show-origin | grep -q "commit.gpgsign"; then git config --global --unset commit.gpgsign fi # Configure Git with new GPG settings git config --global gpg.program $(which gpg) git config --global user.signingkey "$GPG_KEY_ID" sleep 1 git config --global log.showSignature "true" git config --global commit.gpgsign "true" git config --global tag.gpgSign "true" # Display success and next steps print_success "Git configured to use GPG key: $GPG_KEY_ID" echo -e "\n${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e " ${GREEN} Your GPG public key for GitHub: ${NC}" echo -e "\n${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" gpg --armor --export "$GPG_KEY_ID" # gpg --armor --export $(gpg --list-secret-keys --with-keygrip --with-colons | grep '^sec:' | awk -F: '{print $5}') } ptint_hints() { # Print clear instructions with colors echo -e "\n${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e " ${GREEN} Next Steps for GPG Setup ${NC}" echo -e "\n${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${YELLOW}Step 1. 👆 Copy your GPG key 👆${NC}" echo -e "${YELLOW}• Include both BEGIN and END lines${NC}" echo -e "${YELLOW}• Ensure no extra spaces are copied${NC}" echo -e "${YELLOW}Step 2. Add key to GitHub:${NC}" print_step "${GREEN}https://github.com/settings/gpg/new${NC}" echo -e "${YELLOW}Step 3. Verify your signed commits:${NC}" print_step "${GREEN}'git log --show-signature'${NC}" echo -e "${YELLOW}Step 4. Use commit signature verification:${NC}" print_step "${GREEN}'git commit -S -m "YOUR_COMMIT_MESSAGE"'${NC}" echo -e "${YELLOW}Step 5. Learn more about commit signing:${NC}" print_step "${GREEN}https://docs.github.com/authentication/managing-commit-signature-verification${NC}" } # ━━━━━━━━━━━━━━━━━━━━━━━━━━━ Third Phase - Verification ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # Export the GPG Key Materials export_gpg_key() { # Get the GPG key ID GPG_KEY_ID=$(gpg --list-secret-keys --keyid-format LONG | grep sec | tail -1 | awk '{print $2}' | cut -d'/' -f2) # Set secure export paths EXPORT_DIR="$HOME/.gnupg/backup" mkdir -p "$EXPORT_DIR" # Export both public and private keys with armor gpg --armor --export "$GPG_KEY_ID" >"$EXPORT_DIR/gpg_public_${GPG_KEY_ID}.asc" gpg --armor --export-secret-key "$GPG_KEY_ID" >"$EXPORT_DIR/gpg_private_${GPG_KEY_ID}.asc" print_success "GPG keys exported successfully:" print_step "• Public key: ${GREEN}$EXPORT_DIR/gpg_public_${GPG_KEY_ID}.asc${NC}" print_step "• Private key: ${GREEN}$EXPORT_DIR/gpg_private_${GPG_KEY_ID}.asc${NC}" print_step "$(git config --list --show-origin | grep user.signingkey)" #print_step "\n$(gpg --list-secret-keys --keyid-format=long)" } verify_setup() { # Print clear instructions with colors echo -e "\n${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e " ${GREEN} 🔍 Running system verification... ${NC}" echo -e "\n${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" print_step "\n📌 GPG Configuration\n" gpg --list-secret-keys --keyid-format=long gpg-connect-agent --quiet /bye print_success "GPG Agent Status: ✔️" echo "\n🔑 SSH Configuration\n" ssh-add -l print_step "• SSH_AUTH_SOCK: ${GREEN}$SSH_AUTH_SOCK${NC}" print_success "• SSH Agent Status: ✔️" print_step "\n✍️ Git Signing Setp\n" git config --global --list | grep -E 'gpg|signing' git verify-commit HEAD 2>/dev/null || print_step "No signed commits yet" print_step "\n🔐 Environment Variables" print_step "• GPG_TTY: ${GREEN}$GPG_TTY${NC}" print_step "• GNUPGHOME: ${GREEN}$GNUPGHOME${NC}" print_step "\n✨ Running signing test...\n" echo "Final Check" | gpg --clearsign && print_success "GPG signing: ✔️" echo -e "\n${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e " ${GREEN} 🎉 Verification complete.Happy Secure Committing 🎉 ${NC}" echo -e "\n${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" } reload_shell() { if [[ -f "$SHELL_CONFIG" ]]; then # print_step "Reloading shell configuration..." source "$SHELL_CONFIG" else print_warn "Error: Shell configuration file not found at $SHELL_CONFIG" >&2 exit 1 fi } complete_installation() { print_category "Completion" print_success "GnuPG and Git configuration completed successfully 🎉" } # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ End ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # Execute main function only if script is run directly [[ "${BASH_SOURCE[0]}" == "${0}" ]] && main -
zx0r revised this gist
Jan 30, 2025 . 1 changed file with 41 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,41 @@ # $HOME/.ssh/config # Global Settings Host * AddKeysToAgent yes UseKeychain yes IdentitiesOnly yes #IdentityFile ~/.ssh/id_ed25519 # Performance Compression yes TCPKeepAlive yes ServerAliveInterval 60 ServerAliveCountMax 30 # Security HashKnownHosts yes PasswordAuthentication no PubkeyAuthentication yes IdentitiesOnly yes # Modern Crypto KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256 Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com # GitHub Host github.com User git IdentityFile ~/.ssh/github_ed25519 # GitLab Host gitlab.com User git IdentityFile ~/.ssh/gitlab_ed25519 # Custom Server Example Host dev HostName dev.example.com User developer Port 2222 IdentityFile ~/.ssh/dev_ed25519 -
zx0r revised this gist
Jan 30, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -12,4 +12,4 @@ # flags. Prepend the keygrip with an '!' mark to disable it. # gpg --list-keys --with-keygrip | awk '/^sub/{p=1;next} /Keygrip/{if(p){print $3;p=0}}' >> $HOME/.gnupg/sshcontrol # FF8852FA7D6ED25CF4169132698BBA5536A68134 -
zx0r revised this gist
Jan 30, 2025 . 1 changed file with 72 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,72 @@ # Configure your SSH client to automatically add keys to the SSH agent # $HOME/.ssh/config # Host * # AddKeysToAgent yes # UseKeychain yes # Optional: This is useful on macOS to use the keychain. # $HOME/.config/fish/functions/ssh_agent.fish function ssh_agent --description "Start and manage SSH agent" set -l SSH_ENV "$HOME/.ssh/ssh-agent.env" # Check if the SSH agent environment file exists if test -f $SSH_ENV; and test -z "$SSH_AGENT_PID" source $SSH_ENV >/dev/null end # If the SSH agent is not running, start it if test -z "$SSH_AGENT_PID" eval (ssh-agent -c) >$SSH_ENV chmod 600 $SSH_ENV echo "SSH agent started." else echo "Using existing SSH agent." end # Add SSH keys set -l SSH_KEYS (fd '^id_' $HOME/.ssh --type f --exclude '*.pub') for KEY in $SSH_KEYS ssh-add $KEY end end # Automatically start the ssh-agent on shell initialization ssh_agent # https://github.com/ivakyb/fish_ssh_agent # # function ssh_agent_is_started -d "check if ssh agent is already started" # if begin # test -f $SSH_ENV; and test -z "$SSH_AGENT_PID" # end # source $SSH_ENV >/dev/null # end # # if test -z "$SSH_AGENT_PID" # return 1 # end # # ps -ef | grep $SSH_AGENT_PID | grep -v grep | grep -q ssh-agent # return $status # end # # function ssh_agent_start -d "start a new ssh agent" # ssh-agent -c | sed 's/^echo/#echo/' >$SSH_ENV # chmod 600 $SSH_ENV # source $SSH_ENV >/dev/null # true # suppress errors from setenv, i.e. set -gx # end # # function fish_ssh_agent --description "Start ssh-agent if not started yet, or uses already started ssh-agent." # if test -z "$SSH_ENV" # set -xg SSH_ENV $HOME/.ssh/ssh-agent.env # end # # if not ssh_agent_is_started # ssh_agent_start # end # end # Automatically start the ssh-agent on shell initialization # fish_ssh_agent -
zx0r revised this gist
Jan 30, 2025 . 1 changed file with 49 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,49 @@ # $HOME/.config/fish/functions/gpg_ssh_agent.fish function gpg_ssh_agent --description "Start and manage GPG agent" # Skip for root user test $USER = root; and return # Early return if gpgconf is not available command -q gpgconf; or return 1 # Determine GPG directory set -l GPG_DIR (test -n "$GNUPGHOME"; and echo $GNUPGHOME; or echo "$HOME/.gnupg") # Ensure GPG directory exists with secure permissions if not test -d $GPG_DIR mkdir -p $GPG_DIR chmod 700 $GPG_DIR end # Set GPG environment file path set -l GPG_ENV "$GPG_DIR/gpg-agent.env" # Create or update GPG environment file with secure permissions if not test -f $GPG_ENV touch $GPG_ENV chmod 600 $GPG_ENV end # Source existing environment variables if the file is not empty test -s $GPG_ENV; and source $GPG_ENV ^/dev/null # Clear SSH_AUTH_SOCK set -e SSH_AUTH_SOCK # Set curses for SSH connections if active test -n "$SSH_CONNECTION"; and set -x PINENTRY_USER_DATA "USE_CURSES=1" # Set GPG and SSH environment variables set -gx GPG_TTY (tty) set -gx GPG_AGENT_INFO (gpgconf --list-dirs agent-socket) set -gx SSH_AUTH_SOCK (gpgconf --list-dirs agent-ssh-socket) # Initialize GPG agent gpg-connect-agent updatestartuptty /bye ^/dev/null gpgconf --launch gpg-agent return 0 end # Call the function to initialize GPG agent at startup gpg_ssh_agent -
zx0r revised this gist
Jan 30, 2025 . 1 changed file with 15 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,15 @@ # Using a PGP key for SSH authentication # List of allowed ssh keys. Only keys present in this file are used # in the SSH protocol. The ssh-add tool may add new entries to this # file to enable them; you may also add them manually. Comment # lines, like this one, as well as empty lines are ignored. Lines do # have a certain length limit but this is not serious limitation as # the format of the entries is fixed and checked by gpg-agent. A # non-comment line starts with optional white spaces, followed by the # keygrip of the key given as 40 hex digits, optionally followed by a # caching TTL in seconds, and another optional field for arbitrary # flags. Prepend the keygrip with an '!' mark to disable it. # gpg --list-keys --with-keygrip | awk '/^sub/{p=1;next} /Keygrip/{if(p){print $3;p=0}}' >> $HOME/.gnupg/sshcontrol FF8852FA7D6ED25CF4169132698BBA5536A68134 -
zx0r revised this gist
Jan 30, 2025 . 2 changed files with 31 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,19 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>org.gnupg.gpg-agent</string> <key>ProgramArguments</key> <array> <string>$HOME/.local/bin/start-gpg-agent.sh</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>StandardErrorPath</key> <string>~/.gnupg/gpg-agent.log</string> <key>StandardOutPath</key> <string>~/.gnupg/gpg-agent.log</string> </plist> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,12 @@ #!/usr/bin/env bash # The configuration will keep your GPG agent running smoothly across all applications! if [ -f $HOME/.gnupg/.gpg-agent-info ] && [ -n "$(pgrep gpg-agent)" ]; then source $HOME/.gnupg/.gpg-agent-info export GPG_AGENT_INFO else eval $(gpg-agent --daemon --write-env-file $HOME/.gnupg/.gpg-agent-info) fi # This line is important for GUI tools to also find it launchctl setenv GPG_AGENT_INFO $GPG_AGENT_INFO -
zx0r revised this gist
Jan 30, 2025 . 2 changed files with 9 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,12 +1,9 @@ # Script: setup-gpg-git-macos.sh # Author: zx0r # Date: 2025-01-30 # Description: This script installs and configures GnuPG (GPG) for macOS, sets up Git to use GPG for signing commits, # and ensures security settings are applied. It also auto-detects the user's shell, configures VSCode/VSCodium # to use GPG for commits, and sets up a launch agent for gpg-agent. # Set cache times for normal and SSH keys (in seconds) default-cache-ttl 3600 This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,10 @@ # Script: setup-gpg-git-macos.sh # Author: zx0r # Date: 2025-01-30 # Description: This script installs and configures GnuPG (GPG) for macOS, sets up Git to use GPG for signing commits, # and ensures security settings are applied. It also auto-detects the user's shell, configures VSCode/VSCodium # to use GPG for commits, and sets up a launch agent for gpg-agent. # ┌───────────────────────────────────────────────────────────────────────────┐ # │ Setting defaults │ # └───────────────────────────────────────────────────────────────────────────┘ -
zx0r created this gist
Jan 30, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,39 @@ # Script: setup-gpg-git-macos.sh # Description: This script installs and configures GnuPG (GPG) for macOS, sets up Git to use GPG for signing commits, # and ensures security settings are applied. It also auto-detects the user's shell, configures VSCode/VSCodium # to use GPG for commits, and sets up a launch agent for gpg-agent. # Author: zx0r # Date: 2025-01-30 # https://github.com/drduh/config/blob/master/gpg-agent.conf # https://www.gnupg.org/documentation/manuals/gnupg/Agent-Options.html # Set cache times for normal and SSH keys (in seconds) default-cache-ttl 3600 max-cache-ttl 7200 default-cache-ttl-ssh 3600 max-cache-ttl-ssh 7200 # Enable SSH support enable-ssh-support # Set pinentry program for macOS pinentry-program /usr/local/bin/pinentry-mac # Set TTY ttyname $GPG_TTY # Write environment file write-env-file ~/.gnupg/gpg-agent.env # Keyboard control settings no-grab # Allow preset passphrases allow-preset-passphrase # Enable loopback for better integration allow-loopback-pinentry # Set longer key grace period ignore-cache-for-signing This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,195 @@ # ┌───────────────────────────────────────────────────────────────────────────┐ # │ Setting defaults │ # └───────────────────────────────────────────────────────────────────────────┘ # Default/trusted key ID to use (helpful with throw-keyids) # $ gpg --list-secret-keys --with-keygrip --with-colons | grep '^sec:' | awk -F: '{print $5}' default-key <YOUR-KEY> # Automatically encrypt replies to encrypted messages to yourself as well default-recipient-self # UTF-8 support for compatibility charset utf-8 # when outputting certificates, view user IDs distinctly from keys: fixed-list-mode # Use the GPG agent for passphrase caching use-agent # Disable recipient key ID in messages throw-keyids # default-preference-list SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed armor # include an unambiguous indicator of which key made a signature: # (see http://thread.gmane.org/gmane.mail.notmuch.general/3721/focus=7234) # (and http://www.ietf.org/mail-archive/web/openpgp/current/msg00405.html) # sig-notation issuer-fpr@notations.openpgp.fifthhorseman.net=%g # ┌───────────────────────────────────────────────────────────────────────────┐ # │ Algorithms & Ciphers │ # └───────────────────────────────────────────────────────────────────────────┘ # SHA512 as digest to sign keys cert-digest-algo SHA512 # SHA512 as digest for symmetric ops s2k-digest-algo SHA512 # AES256 as cipher for symmetric ops s2k-cipher-algo AES256 # Set default key generation algorithm to RSA with 4096-bit length [strong protection] default-new-key-algo rsa4096 # Use AES256, 192, or 128 as cipher personal-cipher-preferences AES256 AES192 AES # Use SHA512, 384, or 256 as digest personal-digest-preferences SHA512 SHA384 SHA256 # Use ZLIB, BZIP2, ZIP, or no compression personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed # Default preferences for new keys default-preference-list SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed # ┌───────────────────────────────────────────────────────────────────────────┐ # │ Behavior of GnuPG │ # └───────────────────────────────────────────────────────────────────────────┘ # Repair legacy PGP subkey bug during import import-options repair-pks-subkey-bug # Remove all signatures from imported keys that are not usable import-options import-clean # Remove all non-exportable signatures during export export-options export-clean # Display Options # Show validity of user IDs during key listings list-options show-uid-validity # Show validity of user IDs during signature verification verify-options show-uid-validity # Show Unix timestamps fixed-list-mode # Disable caching of passphrase for symmetrical ops no-symkey-cache # Disable banner Interface Options no-greeting # No comments on signatures no-comments # No version in signatures no-emit-version # Show unix timestamps fixed-list-mode # Long hexadecimal key format keyid-format 0xlong # Display fingerprint with-fingerprint # Disable caching of passphrasae for symmetrical encryption no-symkey-cache # Disable recipient key ID in messages # throw-keyids trust-model always # Skip time conflict warnings during signature verification # This is useful when system clock differences might cause issues ignore-time-conflict # Ensure cross-certification on signing subkeys # This enhances security by requiring signatures between primary and subkeys require-cross-certification # Commented out: Allow non-standard UIDs during key generation # Enabling this would allow creation of UIDs without email addresses # allow-freeform-uid # Display all keys and their fingerprints with-fingerprint # Display key origins and updates #with-key-origin # Cross-certify subkeys are present and valid require-cross-certification # no-tty # pinentry-mode loopback # ┌───────────────────────────────────────────────────────────────────────────┐ # │ Keyring & Keyserver │ # └───────────────────────────────────────────────────────────────────────────┘ # Disable the use of the default public and secret keyrings # This allows explicit specification of which keyrings to use no-default-keyring # Keyring Options # Specify the primary public keyring # keyring ~/.gnupg/pubring.kbx # trustdb-name ~/.gnupg/trustdb.gpg # primary-keyring ~/.gnupg/pubring.kbx # Automatically retrieve missing keys from keyserver when verifying signatures # This makes signature verification more seamless by fetching required keys auto-key-retrieve # Keyserver Options # Don't add additional comments in downloaded certificates keyserver-options no-include-attributes # Honor the preferred keyserver URL from the key keyserver-options honor-keyserver-url # Do not include key signatures from keyserver responses keyserver-options no-include-revoked # Include subkeys when downloading keys from keyserver keyserver-options include-subkeys # Automatically fetch keys from keyserver when verifying signatures keyserver-options auto-key-retrieve # Include revoked keys in search results keyserver-options include-revoked # Number of seconds to wait for a keyserver response keyserver-options timeout=10 # Default keyserver to use keyserver hkps://keys.openpgp.org keyserver hkp://zkaan2xfbuxia2wpf7ofnkbz6r5zdbbvxbunvp5g2iebopbfc4iqmbad.onion # keyserver hkp://pgp.mit.edu # keyserver hkp://pool.sks-keyservers.net # keyserver hkp://keys.gnupg.net # keyserver hkps://keyserver.ubuntu.com # keyserver hkps://pgp.mit.edu # keyserver hkp://keyoxide.org # keyserver hkp://na.pool.sks-keyservers.net # keyserver https://sks-keyservers.net/status/ # keyserver hkp://keyserver.ubuntu.com # keyserver hkp://keybase.io # keyserver hkp://keyserver.undergrid.net # keyserver hkp://keyring.debian.org # keyserver hkp://hkps.pool.sks-keyservers.net # Define a keygroup named 'purse_keygroup' # This allows you to refer to multiple keys as a single group # group purse_keygroup = 0xFF123456 0xABCDEF01 0x12345678