mirror of
https://github.com/Matir/skel.git
synced 2026-05-25 13:19:07 -07:00
165 lines
4.8 KiB
Bash
Executable File
165 lines
4.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# A robust wrapper for ssh-keygen to sign and verify files.
|
|
|
|
# --- Color Codes for Output ---
|
|
COLOR_RED='\033[0;31m'
|
|
COLOR_GREEN='\033[0;32m'
|
|
COLOR_NONE='\033[0m' # No Color
|
|
|
|
# --- Default values ---
|
|
DEFAULT_SIGNING_KEY="$HOME/.ssh/id_signing"
|
|
DEFAULT_ALLOWED_SIGNERS="$HOME/.ssh/allowed_signers"
|
|
DEFAULT_IDENTITY="david@systemoverlord.com"
|
|
DEFAULT_NAMESPACE="file"
|
|
|
|
# --- Usage Message ---
|
|
usage() {
|
|
cat << EOF
|
|
Usage: $(basename "$0") <sign|verify> [OPTIONS] [FILE]
|
|
|
|
A wrapper for 'ssh-keygen -Y' to simplify file signing and verification.
|
|
|
|
COMMANDS:
|
|
sign Sign a file. The path to the file to be signed is provided as a positional argument.
|
|
verify Verify a signature. The original file content is read from stdin.
|
|
|
|
OPTIONS:
|
|
-f <file> For 'sign': Path to the private key for signing.
|
|
Defaults to '$DEFAULT_SIGNING_KEY' if it exists.
|
|
For 'verify': Path to the allowed_signers file.
|
|
Defaults to '$DEFAULT_ALLOWED_SIGNERS'.
|
|
-n <namespace> Signature namespace.
|
|
Defaults to '$DEFAULT_NAMESPACE'.
|
|
-I <identity> For 'verify': The identity to check the signature against.
|
|
Defaults to '$DEFAULT_IDENTITY'.
|
|
-s <sig_file> For 'verify': Path to the signature file to verify (e.g., file.sig). REQUIRED for verify.
|
|
-h, --help Show this help message.
|
|
|
|
EXAMPLE USAGE:
|
|
# Sign a file using the default key
|
|
$(basename "$0") sign release.tar.gz
|
|
|
|
# Sign a file with a specific key
|
|
$(basename "$0") sign -f ~/.ssh/id_ed25519_my_signing_key release.tar.gz
|
|
|
|
# Verify a signature using default allowed_signers and identity
|
|
cat release.tar.gz | $(basename "$0") verify -s release.tar.gz.sig
|
|
|
|
# Verify a signature with a specific allowed_signers file and identity
|
|
cat release.tar.gz | $(basename "$0") verify -f ./my_signers -I other@example.com -s release.tar.gz.sig
|
|
|
|
EOF
|
|
exit 1
|
|
}
|
|
|
|
# --- Helper for error messages ---
|
|
error() {
|
|
echo -e "${COLOR_RED}Error: $1${COLOR_NONE}" >&2
|
|
exit 1
|
|
}
|
|
|
|
# --- Main Script Logic ---
|
|
|
|
if [[ "$1" != "sign" && "$1" != "verify" ]]; then
|
|
usage
|
|
fi
|
|
|
|
SUBCOMMAND=$1
|
|
shift # Consume the subcommand
|
|
|
|
# --- Argument Parsing and Validation ---
|
|
|
|
# Separate arguments from the file to be signed
|
|
declare -a remaining_args
|
|
file_to_sign=""
|
|
while [[ "$#" -gt 0 ]]; do
|
|
# If we see a non-flag argument, assume it's the file to sign.
|
|
# This works because the file to sign is the only positional argument.
|
|
if [[ "$1" != -* ]] && [[ -z "$file_to_sign" ]]; then
|
|
file_to_sign="$1"
|
|
else
|
|
remaining_args+=("$1")
|
|
fi
|
|
shift
|
|
done
|
|
|
|
# --- Build command based on subcommand ---
|
|
declare -a CMD_ARGS
|
|
CMD_ARGS=("ssh-keygen" "-Y" "$SUBCOMMAND")
|
|
|
|
# Append all the flag-based arguments (-f, -n, -I, -s)
|
|
CMD_ARGS+=("${remaining_args[@]}")
|
|
|
|
# Scan for provided flags to handle defaults correctly
|
|
f_provided=false
|
|
n_provided=false
|
|
I_provided=false
|
|
s_provided=false
|
|
for arg in "${remaining_args[@]}"; do
|
|
[[ "$arg" == "-f" ]] && f_provided=true
|
|
[[ "$arg" == "-n" ]] && n_provided=true
|
|
[[ "$arg" == "-I" ]] && I_provided=true
|
|
[[ "$arg" == "-s" ]] && s_provided=true
|
|
done
|
|
|
|
if [[ "$SUBCOMMAND" == "sign" ]]; then
|
|
if [[ -z "$file_to_sign" ]]; then
|
|
error "Path to file to be signed is required for 'sign' command."
|
|
fi
|
|
|
|
# Set default signing key if -f was not provided
|
|
if ! $f_provided; then
|
|
if [[ ! -f "$DEFAULT_SIGNING_KEY" ]]; then
|
|
error "Default signing key not found at '$DEFAULT_SIGNING_KEY'. Specify one with -f."
|
|
fi
|
|
CMD_ARGS+=("-f" "$DEFAULT_SIGNING_KEY")
|
|
fi
|
|
|
|
# Set default namespace if -n was not provided
|
|
if ! $n_provided; then
|
|
CMD_ARGS+=("-n" "$DEFAULT_NAMESPACE")
|
|
fi
|
|
|
|
# The file to sign MUST be the last argument for ssh-keygen
|
|
CMD_ARGS+=("$file_to_sign")
|
|
|
|
elif [[ "$SUBCOMMAND" == "verify" ]]; then
|
|
if [[ -n "$file_to_sign" ]]; then
|
|
error "The 'verify' command reads from stdin and does not accept a positional file argument. Found '$file_to_sign'."
|
|
fi
|
|
if ! $s_provided; then
|
|
error "Signature file must be provided with -s for 'verify' command."
|
|
fi
|
|
|
|
# Set default allowed_signers if -f was not provided
|
|
if ! $f_provided; then
|
|
if [[ ! -f "$DEFAULT_ALLOWED_SIGNERS" ]]; then
|
|
error "Default allowed signers file not found at '$DEFAULT_ALLOWED_SIGNERS'. Specify one with -f."
|
|
fi
|
|
CMD_ARGS+=("-f" "$DEFAULT_ALLOWED_SIGNERS")
|
|
fi
|
|
|
|
# Set default identity if -I was not provided
|
|
if ! $I_provided; then
|
|
CMD_ARGS+=("-I" "$DEFAULT_IDENTITY")
|
|
fi
|
|
|
|
# Set default namespace if -n was not provided
|
|
if ! $n_provided; then
|
|
CMD_ARGS+=("-n" "$DEFAULT_NAMESPACE")
|
|
fi
|
|
fi
|
|
|
|
# --- Execute and Report ---
|
|
|
|
# We capture the output and stderr to show it to the user
|
|
if output=$("${CMD_ARGS[@]}" 2>&1); then
|
|
echo -e "${COLOR_GREEN}Success:${COLOR_NONE}"
|
|
echo "$output"
|
|
exit 0
|
|
else
|
|
echo -e "${COLOR_RED}Command Failed:${COLOR_NONE}"
|
|
echo "$output" >&2
|
|
exit 1
|
|
fi
|