From 7c4b791a035682c246c1fb60f7b78935fc1477bf Mon Sep 17 00:00:00 2001 From: PrincessPi3 Date: Wed, 28 Jan 2026 10:31:59 -0700 Subject: [PATCH] 1769621519 --- Windows-Scripts/windows-repair.ps1 | 3 +- customscripts/ssh_create_sign_verify | 594 +++++++++++++++++++-------- 2 files changed, 432 insertions(+), 165 deletions(-) diff --git a/Windows-Scripts/windows-repair.ps1 b/Windows-Scripts/windows-repair.ps1 index 6415b69..fedd43b 100644 --- a/Windows-Scripts/windows-repair.ps1 +++ b/Windows-Scripts/windows-repair.ps1 @@ -1,4 +1,5 @@ +# powershell.exe -ExecutionPolicy Bypass -File "C:\\path\\to\\yourscript.ps1" # Check for administrator privileges if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { # Restart with elevated privileges @@ -21,7 +22,7 @@ Write-Host "RUNNING DISM" DISM /Online /Cleanup-Image /RestoreHealth # powershell checks image and replaces bad files Write-Host "SCHEDULING OFFLINE CHECK DISK OF C: (chkdsk)" -chkdsk /r C: # cmd checks C drive after reboot to waste time and fix errors +echo y | chkdsk /r C: # cmd checks C drive after reboot to waste time and fix errors Write-Host "SCHEDULING WINDOWS DEFENDER OFFLINE SCAN" Start-MpWDOScan # powershell starts Windows Defender Offline Scan after reboot diff --git a/customscripts/ssh_create_sign_verify b/customscripts/ssh_create_sign_verify index f680f8a..2855232 100644 --- a/customscripts/ssh_create_sign_verify +++ b/customscripts/ssh_create_sign_verify @@ -1,214 +1,480 @@ #!/bin/bash -# packages: cracklib-runtime, openssh-client(s) -# set -x # debug mode -set -Eeuo pipefail # safety shit. fail to trap on any error, undeclared var, pipe filure -IFS=$'\n\t' # safer handlin of filenames and shit with spaces, prevents splitting -trap 'error_handler $?' ERR # prettyful trap for error handlin :3 +# +# SSH File Signing Tool +# Purpose: Creates cryptographic signatures for files using SSH keys with dual-layer verification +# Dependencies: cracklib-runtime, openssh-client(s) +# Author: [Your name] +# Date: $(date +%Y-%m-%d) +# +# Features: +# - SSH signature verification using private key +# - Salted SHA256/SHA512 checksums for independent verification +# - Enforces strong 50+ character passphrases via cracklib +# - Creates complete verification package with instructions +# -# these can be adjusted interactively +# Debug mode (uncomment to enable) +# set -x + +# Shell safety options +set -Eeuo pipefail # Exit on error, undefined vars, pipe failures +IFS=$'\n\t' # Safe field splitting (newline and tab only) +trap 'error_handler $?' ERR # Trap errors and call error handler + +# ============================================================================ +# HELP AND USAGE +# ============================================================================ + +show_help() { + cat << EOF +SSH File Signing Tool - Cryptographic File Signature Generator + +Creates cryptographic signatures for files using SSH keys with dual-layer verification: + 1. SSH signature using private key (cryptographic proof) + 2. Salted checksums for independent verification (passphrase-based) + +Usage: $(basename "$0") [OPTIONS] + +Options: + -h, --help Show this help message and exit + +Features: + • Generates ed25519 (or other) SSH key pair with strong passphrase + • Creates detached signatures for files using SSH signing + • Generates normal and salted SHA256/SHA512 checksums + • Creates complete verification package with public key and instructions + • Enforces strong 50+ character passphrases validated by cracklib + • Two independent verification methods (key-based and passphrase-based) + +Output: + Creates a public_files directory containing: + - Signed file + - Signature files (.sig) + - Checksums file with normal and salted hashes + - Public key and allowed_signers file + - Verification instructions + +Security: + • Private key protected with unique 50+ character passphrase + • Checksum salt uses different 50+ character passphrase + • Both passphrases must pass cracklib security checks + • Passphrases cleared from memory after use + +EOF + exit 0 +} + +# Parse command-line arguments +if [[ "${1:-}" == "-h" ]] || [[ "${1:-}" == "--help" ]]; then + show_help +fi + +# ============================================================================ +# CONFIGURATION AND CONSTANTS +# ============================================================================ + +# Default values (can be overridden during execution) default_email="anonymous@anonymous.com" default_algo="ed25519" default_working_dir="$PWD" default_key_name="Signing_Key_$default_algo" default_public_files_dir_name="public_files" -# set here not thrugh interactive txt_help_file_name="How_to_Verify_Files.txt" -RED='\033[0;31m' # red color for errorz -NO_COLOR='\033[0m' # reset to no color after red -# my silly pretty lil error handler :3 +# ANSI color codes for output formatting +RED='\033[0;31m' # Error messages +GREEN='\033[0;32m' # Success messages +BLUE='\033[0;34m' # Section headers +YELLOW='\033[0;33m' # Warnings +NO_COLOR='\033[0m' # Reset color + +# ============================================================================ +# ERROR HANDLING +# ============================================================================ + error_handler() { - local retcode="$1" # get dat retcode - # color da error output red :3 - echo -e "\n\n${RED}ERROR: Failure With Return Code: $retcode on Line: $BASH_LINENO at Second: $SECONDS Timestamp: $(date)${NO_COLOR}" - echo -e "${RED}Command:\n\t$BASH_COMMAND\n\n${NO_COLOR}" + local retcode="$1" + echo -e "\n${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NO_COLOR}" + echo -e "${RED}ERROR: Command failed with exit code $retcode${NO_COLOR}" + echo -e "${RED}Line: $BASH_LINENO | Time: ${SECONDS}s | Timestamp: $(date '+%Y-%m-%d %H:%M:%S')${NO_COLOR}" + echo -e "${RED}Command: $BASH_COMMAND${NO_COLOR}" + echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NO_COLOR}\n" + exit "$retcode" } -### todo: environment check/package installa -### todo: make input of both passphrases only happen twice, compared against teach other, and tested -### todo: handle fix perms shit by narrowly changing perms of da private key fiel -### todo: handle file paths better -### todo: cleanup output -#### spacing -#### y better feedback for success/fail of shit -#### clean shit uuuup -### todo: allow file input from cli -### todo: cli options for generate/sign/verify/all -### todo: auto-compress pub files? (cleartext zip, encrypted 7z?) -### todo: maybe figure out how to unify these sigs and files and shit? +# ============================================================================ +# PHASE 1: SYSTEM REQUIREMENTS CHECK +# ============================================================================ -read -p "Enter path to file to sign: " file_to_sign -read -p "Enter Private 50+ Character Passphrase For Checksum Verification: " checksum_passphrase -read -p "Enter Checksum Verification Passphrase Again: " checksum_passphrase_check -checksum_passphrase_len=${#checksum_passphrase} # get length of provided checksum passphrase -# check for match -if [[ "$checksum_passphrase" == "$checksum_passphrase_check" ]]; then - echo "OK: Checksum Verification Passphrases Match" - # check length greateer than or equal to 50 - if [ $checksum_passphrase_len -ge 50 ]; then - echo "OK: Checksum Verification Passphrase is greater or equal to 50 chars long" - # check for pass security using cracklib-check from cracklib-runtime package - cracklib_check=$(echo "$checksum_passphrase" | cracklib-check) - if [[ ! "$cracklib_check" =~ OK$ ]]; then # check if it ends with anythign other than OK - echo -e "\n\nFAIL: Checksum Verification Passphrase NOT Secure Enough!\nReported: $cracklib_check${NO_COLOR}\n\n" - exit 1 - else - echo "OK: Cracklib Reports Password is Secure" - fi - else - echo -e "\n\n${RED}FAIL: Checksum Verification Passphrase NOT Longer Than the Minimum 50 Chars${NO_COLOR}\n\n" - exit 1 +echo -e "\n${BLUE}[1/7] Checking System Requirements${NO_COLOR}" + +# List of required commands +required_commands=("ssh-keygen" "sha256sum" "sha512sum" "cracklib-check" \ + "chown" "chmod" "find" "basename" "cat" "mkdir" \ + "cp" "awk" "readlink" "stat" "du") + +# Check for missing commands +missing_commands=() +for cmd in "${required_commands[@]}"; do + if ! command -v "$cmd" &> /dev/null; then + missing_commands+=("$cmd") fi -else - echo -e "\n\n${RED}FAIL: Checksum Verification Passphrases DO NOT MATCH${NO_COLOR}\n\n" +done + +# Exit if any commands are missing +if [ ${#missing_commands[@]} -gt 0 ]; then + echo -e "${RED}✗ Missing required commands: ${missing_commands[*]}${NO_COLOR}" + echo -e "${YELLOW}Install missing packages and try again${NO_COLOR}" exit 1 fi -read -p "Enter working directory (empty for $default_working_dir): " working_dir -read -p "Enter email to use (empty for $default_email): " email -read -p "Enter public key comment (empty for $default_email): " comment -read -p "Enter algo (empty for $default_algo): " algo -read -p "Enter new key name (Empty for $default_key_name): " key_name ### todo: test/handle -read -p "Enter public files output dir name (Empty for $default_public_files_dir_name): " public_files_dir_name -# handle defaults -## handle default working dir -### todo: check for dir existance first -### todo: check for dir rw perms first -if [ -z "$working_dir" ]; then - echo "Changing directory to $default_working_dir" - working_dir="$default_working_dir" - cd "$working_dir" -else - echo "Changing directory to $working_dir" - cd "$working_dir" +echo -e "${GREEN}✓ All required commands available${NO_COLOR}" + +# ============================================================================ +# PHASE 2: USER INPUT COLLECTION +# ============================================================================ + +echo -e "\n${BLUE}[2/7] Gathering Configuration${NO_COLOR}" + +# Get file to sign +read -p "Enter path to file to sign: " file_to_sign + +# Collect SSH key passphrase (hidden input) +read -s -p "Enter unique 50+ character passphrase for SSH key: " ssh_passphrase +echo +read -s -p "Re-enter SSH key passphrase: " ssh_passphrase_check +echo + +# Collect checksum verification passphrase (hidden input) +read -s -p "Enter unique 50+ character passphrase for checksum verification: " checksum_passphrase +echo +read -s -p "Confirm checksum verification passphrase: " checksum_passphrase_check +echo + +# ============================================================================ +# PASSPHRASE VALIDATION +# ============================================================================ + +# Get passphrase lengths +checksum_passphrase_len=${#checksum_passphrase} +ssh_passphrase_len=${#ssh_passphrase} + +# Validate SSH passphrase +if [[ "$ssh_passphrase" != "$ssh_passphrase_check" ]]; then + echo -e "${RED}✗ SSH passphrases do not match${NO_COLOR}" + exit 1 fi -## handle ddefault email + +if [ $ssh_passphrase_len -lt 50 ]; then + echo -e "${RED}✗ SSH passphrase must be at least 50 characters (current: $ssh_passphrase_len)${NO_COLOR}" + exit 1 +fi + +cracklib_check=$(echo "$ssh_passphrase" | cracklib-check) +if [[ ! "$cracklib_check" =~ OK$ ]]; then + echo -e "${RED}✗ SSH passphrase not secure enough: $cracklib_check${NO_COLOR}" + exit 1 +fi +echo -e "${GREEN}✓ SSH passphrase validated${NO_COLOR}" + +# Validate checksum passphrase +if [[ "$checksum_passphrase" != "$checksum_passphrase_check" ]]; then + echo -e "${RED}✗ Checksum passphrases do not match${NO_COLOR}" + exit 1 +fi + +if [ $checksum_passphrase_len -lt 50 ]; then + echo -e "${RED}✗ Checksum passphrase must be at least 50 characters (current: $checksum_passphrase_len)${NO_COLOR}" + exit 1 +fi + +cracklib_check=$(echo "$checksum_passphrase" | cracklib-check) +if [[ ! "$cracklib_check" =~ OK$ ]]; then + echo -e "${RED}✗ Checksum passphrase not secure enough: $cracklib_check${NO_COLOR}" + exit 1 +fi + +# Ensure the two passphrases are different +if [[ "$checksum_passphrase" == "$ssh_passphrase" ]]; then + echo -e "${RED}✗ Checksum passphrase MUST be different from SSH passphrase${NO_COLOR}" + exit 1 +fi + +echo -e "${GREEN}✓ Checksum passphrase validated${NO_COLOR}" + +# Collect optional configuration (press Enter to use defaults) +read -p "Working directory [default: $default_working_dir]: " working_dir +read -p "Email for signatures [default: $default_email]: " email +read -p "Public key comment [default: $default_email]: " comment +read -p "Key algorithm [default: $default_algo]: " algo +read -p "Key filename [default: $default_key_name]: " key_name +read -p "Public files directory name [default: $default_public_files_dir_name]: " public_files_dir_name + +# ============================================================================ +# PHASE 3: CONFIGURATION VALIDATION +# ============================================================================ + +echo -e "\n${BLUE}[3/7] Validating Configuration${NO_COLOR}" + +# Apply defaults for empty inputs +if [ -z "$working_dir" ]; then + working_dir="$default_working_dir" +fi + if [ -z "$email" ]; then email="$default_email" fi -## handle ddefault pub key comment -### todo: handle empty comment? + if [ -z "$comment" ]; then comment="$default_email" fi -## handle ddefault algo -### todo: check against ssh-keygen + if [ -z "$algo" ]; then algo="$default_algo" fi -## handle default key name + if [ -z "$key_name" ]; then key_priv_path="$working_dir/$default_key_name" else key_priv_path="$working_dir/$key_name" fi -## handle default publid files dir name/path + if [ -z "$public_files_dir_name" ]; then public_files_dir_path="$working_dir/$default_public_files_dir_name" else public_files_dir_path="$working_dir/$public_files_dir_name" fi -# environment checks -## check if file exists and is regular file -## todo: make this use absolute paths -if [ ! -f "$file_to_sign" ]; then - echo "FAIL! $file_to_sign not found or not regular file! Exititng!" +# Validate working directory +if [ ! -d "$working_dir" ]; then + echo -e "${RED}✗ Working directory does not exist: $working_dir${NO_COLOR}" exit 1 fi -# sum housekeeping, makin file pathssss and shit -sig_file_path="$file_to_sign.sig" # path to detached signature file -key_pub_path="$key_priv_path.pub" # path to pub key file -allowed_signers_path="$working_dir/allowed_signers" # path to allowed_signers file -file_to_sign_checksums_path="$file_to_sign.checksums" # checksums file -file_to_sign_checksums_sig_path="$file_to_sign_checksums_path.sig" # checksums file sig file -file_to_sign_basename="$(basename $file_to_sign)" # file_to_sign name only -file_to_sign_contents="$(cat $file_to_sign)" # file_to_sign file contents +if [ ! -w "$working_dir" ]; then + echo -e "${RED}✗ Working directory is not writable: $working_dir${NO_COLOR}" + exit 1 +fi -# generate key pair -## tell user to be sure to use a sdolid passphrase and wait for enter to continue -echo "BE SURE TO SAVE THIS KEY WITH A SINGLE USE DURABLE STRONG PASSPHRASE WHEB PROMPTED" -read -p "enter to continue" # wait for enter to contintue, nothign is read -echo "Generating new key pair $key_priv_path and $key_pub_path with algo $algo with comment/identity $email" -## -t is algo, -C is comment in pubkey -f is path to key file name -ssh-keygen -t "$algo" -C "$comment" -f "$key_priv_path" -## fix perms and pwnership on keyfilez -echo "Changing perms on dis dir and files to user/group $USER" -chown $USER:$USER -R "$working_dir" -find "$working_dir" -type d -exec chmod 700 {} \; -find "$working_dir" -type f -exec chmod 600 {} \; +cd "$working_dir" || exit 1 -# create a local allowed_signers file -echo "Creating alllowed_singers file at $allowed_signers_path with $key_pub_path and identity $email" -## format: -pub_key_text="$(cat $key_pub_path)" # text of public key -echo "$email $pub_key_text" > "$allowed_signers_path" # dont append, just one off here +# Validate algorithm +valid_algos=("rsa" "ecdsa" "ecdsa-sk" "ed25519" "ed25519-sk" "dsa") +if [[ ! " ${valid_algos[@]} " =~ " ${algo} " ]]; then + echo -e "${RED}✗ Invalid algorithm '$algo'${NO_COLOR}" + echo -e "${YELLOW}Valid algorithms: ${valid_algos[*]}${NO_COLOR}" + exit 1 +fi -# generate checksums -## normal ones sha256 and sha512 -### initialize the checksums file new with normal sha256 and sha512 digests -echo -e "sha256 $(sha256sum $file_to_sign)\nsha512 $(sha512sum $file_to_sign)" > "$file_to_sign_checksums_path" -## salted hashes -### salted sha256 -#### normal append first part of line -echo "sha256 (private salt+\`cat file\`): " >> "$file_to_sign_checksums_path" -#### no trailing newline echo to stdin sha256sum, clean up with awk, append to checksums file line -echo -n "${checksum_passphrase}${file_to_sign_contents}" | sha256sum | awk '{print $1}' >> "$file_to_sign_checksums_path" -#### no trailing newline echo append to checksums file, completing the sha256 salted line -echo -n "$file_to_sign_basename" >> "$file_to_sign_checksums_path" -### salted sha512 -#### normal append first part of salted sha512 line -echo "sha512 (private salt+\`cat file\`): " >> "$file_to_sign_checksums_path" -#### no trailing newline echo to stdin sha512sum, clean up with awk, append to checksums file line -echo -n -e "${checksum_passphrase}${file_to_sign_contents}" | sha512sum | awk '{print $1}' >> "$file_to_sign_checksums_path" -#### no trailing newline echo append to checksums file, completing the sha512 salted line and completing the file -echo -n "$file_to_sign_basename" >> "$file_to_sign_checksums_path" +# Check for existing key files (prevent accidental overwrite) +if [ -f "$key_priv_path" ] || [ -f "$key_priv_path.pub" ]; then + echo -e "${RED}✗ Key files already exist: $key_priv_path${NO_COLOR}" + echo -e "${YELLOW}Choose a different key name or remove existing keys${NO_COLOR}" + exit 1 +fi -# sign the files -## sign da file to sign -echo "Signing $file_to_sign with detached signature file $sig_file_path" -### -Y mode (sign) -f private key path -n file (fuile mode) file.txt (file to sign) -ssh-keygen -Y sign -f "$key_priv_path" -n file "$file_to_sign" -## sign checksums file -echo "Signing $file_to_sign_checksums_path with detached signature file $file_to_sign_checksums_sig_path" -### -Y mode (sign) -f private key path -n file (fuile mode) file.txt (file to sign) -ssh-keygen -Y sign -f "$key_priv_path" -n file "$file_to_sign_checksums_path" +# Check for existing output directory (prevent accidental overwrite) +if [ -d "$public_files_dir_path" ]; then + echo -e "${RED}✗ Output directory already exists: $public_files_dir_path${NO_COLOR}" + echo -e "${YELLOW}Choose a different directory name or remove existing directory${NO_COLOR}" + exit 1 +fi +# Convert to absolute path for consistency +file_to_sign="$(readlink -f "$file_to_sign")" -# verify sigs -## file to sign -echo "Verifying signature of $file_to_sign with signature file $sig_file_path for public key $key_pub_path and identitiy $email" -### -Y mode (verify) -f path to allowed_signers file -I email specified in allowed_signers file -n file (file mode) -s path to sig file < file.txt input file to verify -ssh-keygen -Y verify -f "$allowed_signers_path" -I "$email" -n file -s "$sig_file_path" < "$file_to_sign" -## checksums file -echo "Verifying signature of $file_to_sign_checksums_path with signature file $file_to_sign_checksums_sig_path for public key $key_pub_path and identitiy $email" -### -Y mode (verify) -f path to allowed_signers file -I email specified in allowed_signers file -n file (file mode) -s path to sig file < file.txt input file to verify -ssh-keygen -Y verify -f "$allowed_signers_path" -I "$email" -n file -s "$file_to_sign_checksums_sig_path" < "$file_to_sign_checksums_path" +# Validate file exists +if [ ! -f "$file_to_sign" ]; then + echo -e "${RED}✗ File not found: $file_to_sign${NO_COLOR}" + exit 1 +fi -# make public files copy -## create public files dir or fail if exists -### todo: use -p for ez reuse? -echo "Creating public files output dir at $public_files_dir_path" +# Validate file is readable +if [ ! -r "$file_to_sign" ]; then + echo -e "${RED}✗ File not readable: $file_to_sign${NO_COLOR}" + echo -e "${YELLOW}Check file permissions${NO_COLOR}" + exit 1 +fi + +# Check file size (warn if > 100MB as entire file is loaded into memory for checksums) +file_size=$(stat -f%z "$file_to_sign" 2>/dev/null || stat -c%s "$file_to_sign" 2>/dev/null || echo 0) +if [ "$file_size" -gt 104857600 ]; then + file_size_mb=$(( file_size / 1048576 )) + echo -e "${YELLOW}⚠ Warning: Large file (${file_size_mb}MB) will be loaded into memory${NO_COLOR}" + read -p "Continue? [y/N]: " confirm + if [[ ! "$confirm" =~ ^[Yy]$ ]]; then + echo "Operation aborted by user" + exit 0 + fi +fi + +# Define file paths and extract metadata +file_to_sign_basename="$(basename "$file_to_sign")" +file_size_human="$(du -h "$file_to_sign" 2>/dev/null | cut -f1 || echo 'unknown')" +sig_file_path="$file_to_sign.sig" +key_pub_path="$key_priv_path.pub" +allowed_signers_path="$working_dir/allowed_signers" +file_to_sign_checksums_path="$file_to_sign.checksums" +file_to_sign_checksums_sig_path="$file_to_sign_checksums_path.sig" + +# Display validated configuration +echo -e "${GREEN}✓ Configuration validated${NO_COLOR}" +echo -e " File to sign: $file_to_sign_basename ($file_size_human)" +echo -e " Algorithm: $algo" +echo -e " Email: $email" +echo -e " Working directory: $working_dir" +echo -e " Output directory: $public_files_dir_path" + +# ============================================================================ +# PHASE 4: SSH KEY PAIR GENERATION +# ============================================================================ + +echo -e "\n${BLUE}[4/7] Generating SSH Key Pair${NO_COLOR}" + +# Generate SSH key pair with passphrase protection +# Using -N flag to provide passphrase non-interactively +ssh-keygen -t "$algo" -C "$comment" -f "$key_priv_path" -N "$ssh_passphrase" -q 2>/dev/null + +# Verify key files were created successfully +if [ ! -f "$key_priv_path" ] || [ ! -f "$key_pub_path" ]; then + echo -e "${RED}✗ Key generation failed${NO_COLOR}" + exit 1 +fi + +echo -e "${GREEN}✓ SSH key pair generated${NO_COLOR}" + +# Clear passphrase confirmation variables from memory (security) +unset ssh_passphrase_check +unset checksum_passphrase_check + +# Set restrictive permissions on private key (600 = owner read/write only) +chown "$USER:$USER" "$key_priv_path" 2>/dev/null || true +chmod 600 "$key_priv_path" + +# Create allowed_signers file (required for SSH signature verification) +pub_key_text="$(cat "$key_pub_path")" +echo "$email $pub_key_text" > "$allowed_signers_path" + +# ============================================================================ +# PHASE 5: CHECKSUM GENERATION +# ============================================================================ + +echo -e "\n${BLUE}[5/7] Generating Checksums${NO_COLOR}" + +# Load file contents into memory (needed for salted checksums) +file_to_sign_contents="$(cat "$file_to_sign")" + +# Generate normal SHA256 and SHA512 checksums +echo -e "sha256 $(sha256sum "$file_to_sign")\nsha512 $(sha512sum "$file_to_sign")" > "$file_to_sign_checksums_path" + +# Generate salted SHA256 checksum (passphrase + file contents) +echo -n "sha256 (private salt+\`cat file\`): " >> "$file_to_sign_checksums_path" +echo -n "${checksum_passphrase}${file_to_sign_contents}" | sha256sum | awk '{print $1" "}' >> "$file_to_sign_checksums_path" +echo "$file_to_sign_basename" >> "$file_to_sign_checksums_path" + +# Generate salted SHA512 checksum (passphrase + file contents) +echo -n "sha512 (private salt+\`cat file\`): " >> "$file_to_sign_checksums_path" +echo -n "${checksum_passphrase}${file_to_sign_contents}" | sha512sum | awk '{print $1" "}' >> "$file_to_sign_checksums_path" +echo "$file_to_sign_basename" >> "$file_to_sign_checksums_path" + +echo -e "${GREEN}✓ Checksums generated (normal + salted)${NO_COLOR}" + +# Clear sensitive data from memory +unset file_to_sign_contents +unset checksum_passphrase + +# ============================================================================ +# PHASE 6: FILE SIGNING AND VERIFICATION +# ============================================================================ + +echo -e "\n${BLUE}[6/7] Signing Files${NO_COLOR}" + +# Sign the original file +echo "$ssh_passphrase" | ssh-keygen -Y sign -f "$key_priv_path" -n file "$file_to_sign" -q 2>/dev/null + +if [ ! -f "$sig_file_path" ]; then + echo -e "${RED}✗ Failed to create signature for $file_to_sign_basename${NO_COLOR}" + exit 1 +fi + +# Sign the checksums file +echo "$ssh_passphrase" | ssh-keygen -Y sign -f "$key_priv_path" -n file "$file_to_sign_checksums_path" -q 2>/dev/null + +if [ ! -f "$file_to_sign_checksums_sig_path" ]; then + echo -e "${RED}✗ Failed to create signature for checksums file${NO_COLOR}" + exit 1 +fi + +echo -e "${GREEN}✓ Files signed successfully${NO_COLOR}" + +# Verify signatures immediately after creation (sanity check) +echo "Verifying signatures..." +if echo "$ssh_passphrase" | ssh-keygen -Y verify -f "$allowed_signers_path" -I "$email" -n file -s "$sig_file_path" < "$file_to_sign" > /dev/null 2>&1; then + if echo "$ssh_passphrase" | ssh-keygen -Y verify -f "$allowed_signers_path" -I "$email" -n file -s "$file_to_sign_checksums_sig_path" < "$file_to_sign_checksums_path" > /dev/null 2>&1; then + echo -e "${GREEN}✓ Signatures verified successfully${NO_COLOR}" + else + echo -e "${RED}✗ Checksums signature verification failed${NO_COLOR}" + exit 1 + fi +else + echo -e "${RED}✗ File signature verification failed${NO_COLOR}" + exit 1 +fi + +# ============================================================================ +# PHASE 7: PUBLIC FILES PACKAGE CREATION +# ============================================================================ + +echo -e "\n${BLUE}[7/7] Creating Public Files Package${NO_COLOR}" + +# Create output directory mkdir "$public_files_dir_path" -## copy the pub files there -echo "Copying publc key, local allowed_signatures file, signed file, detached signature file, checksums file, and detached checksums signature file to $public_files_dir_path" -cp "$key_pub_path" "$public_files_dir_path" # public key -cp "$allowed_signers_path" "$public_files_dir_path" # allowed signers file -cp "$file_to_sign" "$public_files_dir_path" # signed file -cp "$sig_file_path" "$public_files_dir_path" # main file sig file -cp "$file_to_sign_checksums_path" "$public_files_dir_path" # checksums file -cp "$file_to_sign_checksums_sig_path" "$public_files_dir_path" # checksums sig file -## generate the help txt file and put it in place -### get filenames only from the paths via basename -allowed_signers_path_basename="$(basename $allowed_signers_path)" -sig_file_path_basename="$(basename $sig_file_path)" -checksums_sig_file_basename="$(basename $file_to_sign_checksums_sig_path)" -checksums_file_basename="$(basename $file_to_sign_checksums_path)" -### format help text -help_txt="To Verify Signatures: (Linux)\n\tssh-keygen -Y verify -f \"$allowed_signers_path_basename\" -I \"$email\" -n file -s \"$sig_file_path_basename\" < \"$file_to_sign_basename\"\n\tssh-keygen -Y verify -f \"$allowed_signers_path_basename\" -I \"$email\" -n file -s \"$checksums_sig_file_basename\" < \"$checksums_file_basename\"\n\nTo Verify Normal Checksums (Linux):\n\tsha256sum $file_to_sign_basename\n\tsha256sum $file_to_sign_basename\n\t\tThen compare to values in $checksums_file_basename\n\nTo Verify Authenticated Checksums Via Private Salt (Linux):\n\tprivate_salt="\"\n\techo -n -e \"\${private_salt}\$(cat $file_to_sign_basename)\" | sha256sum\n\techo -n -e \"\${private_salt}\$(cat $file_to_sign_basename)\" | sha512sum\n\t\tThen compare to values in $checksums_file_basename\n" -### maek da file -echo "Creating custom help txt file in $public_files_dir_path/$txt_help_file_name" + +# Copy files to public package +cp "$key_pub_path" "$public_files_dir_path" +cp "$allowed_signers_path" "$public_files_dir_path" +cp "$file_to_sign" "$public_files_dir_path" +cp "$sig_file_path" "$public_files_dir_path" +cp "$file_to_sign_checksums_path" "$public_files_dir_path" +cp "$file_to_sign_checksums_sig_path" "$public_files_dir_path" + +# Generate basenames for help text +allowed_signers_path_basename="$(basename "$allowed_signers_path")" +sig_file_path_basename="$(basename "$sig_file_path")" +checksums_sig_file_basename="$(basename "$file_to_sign_checksums_sig_path")" +checksums_file_basename="$(basename "$file_to_sign_checksums_path")" + +# Create verification instructions file +help_txt="To Verify Signatures (Linux):\n\tssh-keygen -Y verify -f \"$allowed_signers_path_basename\" -I \"$email\" -n file -s \"$sig_file_path_basename\" < \"$file_to_sign_basename\"\n\tssh-keygen -Y verify -f \"$allowed_signers_path_basename\" -I \"$email\" -n file -s \"$checksums_sig_file_basename\" < \"$checksums_file_basename\"\n\nTo Verify Normal Checksums (Linux):\n\tsha256sum $file_to_sign_basename\n\tsha512sum $file_to_sign_basename\n\t\tThen compare to values in $checksums_file_basename\n\nTo Verify Authenticated Checksums Via Private Salt (Linux):\n\tprivate_salt=\"\"\n\techo -n \"\${private_salt}\$(cat $file_to_sign_basename)\" | sha256sum\n\techo -n \"\${private_salt}\$(cat $file_to_sign_basename)\" | sha512sum\n\t\tThen compare to values in $checksums_file_basename" echo -e "$help_txt" > "$public_files_dir_path/$txt_help_file_name" -# declare victory :3 -echo -e "\nall donesies :3\n" \ No newline at end of file +echo -e "${GREEN}✓ Public files package created${NO_COLOR}" + +# ============================================================================ +# COMPLETION SUMMARY +# ============================================================================ + +echo -e "\n${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NO_COLOR}" +echo -e "${GREEN}✓ Operation Completed Successfully${NO_COLOR}" +echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NO_COLOR}" + +echo -e "\n${BLUE}Public Files Package:${NO_COLOR} $public_files_dir_path" +echo -e " • $file_to_sign_basename (signed file)" +echo -e " • $sig_file_path_basename (file signature)" +echo -e " • $checksums_file_basename (checksums file)" +echo -e " • $checksums_sig_file_basename (checksums signature)" +echo -e " • $allowed_signers_path_basename (allowed signers list)" +echo -e " • $(basename "$key_pub_path") (public key)" +echo -e " • $txt_help_file_name (verification instructions)" + +echo -e "\n${YELLOW}Private Files (KEEP SECRET):${NO_COLOR}" +echo -e " • ${RED}$key_priv_path${NO_COLOR} (private key)" +echo -e " • ${RED}Checksum passphrase${NO_COLOR} (for independent verification)" + +echo -e "\n${GREEN}Next Steps:${NO_COLOR}" +echo -e " 1. Distribute the public files package to recipients" +echo -e " 2. Keep your private key and checksum passphrase secure" +echo -e " 3. Recipients can verify signatures using the instructions file" +echo -e " 4. Optionally provide the checksum passphrase for independent verification\n" + +# Final security: clear all passphrases from memory +unset ssh_passphrase \ No newline at end of file