Skip to content

Instantly share code, notes, and snippets.

@nicolas-goudry
Last active January 15, 2024 14:32
Show Gist options
  • Save nicolas-goudry/45d5c06d2760af1ee7c27e85ef88d982 to your computer and use it in GitHub Desktop.
Save nicolas-goudry/45d5c06d2760af1ee7c27e85ef88d982 to your computer and use it in GitHub Desktop.
Bash script to generate truststore from server certificate
#!/usr/bin/env bash
# Exit on error
set -e
# Variables
SCRIPT_NAME="$(basename "$0")"
DEFAULT_PASSWORD="password"
DEFAULT_OUTFILE="store.jks"
# Color codes
NC="\e[0m"
BOLD="\e[1m"
DIM="\e[2m"
R="\e[31m"
# Utility function to output error message
error() {
>&2 echo -e "${R}ERROR: $*${NC}"
}
# Utility function to exit script with optional error message
die() {
if test "$#" -gt 0; then
error "$*"
fi
exit 1
}
# Output help usage
usage() {
echo
echo "Retrieve the SSL certificate from a given server and generates a Java Key Store"
echo "file from it, which can be used as a trust store with kcadm.sh."
echo
echo -e "${BOLD}Usage:${NC}"
echo
echo -e " ${DIM}\$${NC} $SCRIPT_NAME [OPTIONS]"
echo
echo -e "${BOLD}Options:${NC}"
echo
echo " -H, --host Server hostname"
echo " -p, --port Server port"
echo -e " -o, --output Key Store output name ${DIM}default: $DEFAULT_OUTFILE${NC}"
echo -e " -P, --password Key Store password ${DIM}default: $DEFAULT_PASSWORD${NC}"
echo " -h, --help Show this help message"
echo
}
# Check that openssl command is available
check_openssl() {
if test -z "$(command -v openssl)"; then
die "missing openssl binary"
fi
}
check_args() {
local has_error=false
if test -z "$HOST"; then
has_error=true
error "missing hostname"
fi
if test -z "$PORT"; then
has_error=true
error "missing port"
fi
if test ${#PASSWORD} -lt 6; then
has_error=true
error "password must be 6 characters minimum"
fi
if test "$has_error" = "true"; then
usage
die
fi
}
OUTFILE="$DEFAULT_OUTFILE"
PASSWORD="$DEFAULT_PASSWORD"
# Read script flags
while getopts 'hH:p:o:P:-:' OPT; do
# support long options: https://stackoverflow.com/a/28466267/519360
if test "$OPT" = "-"; then # long option: reformulate OPT and OPTARG
OPT="${OPTARG%%=*}" # extract long option name
# shellcheck disable=SC2295
OPTARG="${OPTARG#$OPT}" # extract long option argument (may be empty)
OPTARG="${OPTARG#=}" # if long option argument, remove assigning `=`
fi
# Handle flags
case "$OPT" in
H | host ) HOST="$OPTARG" ;;
p | port ) PORT="$OPTARG" ;;
o | output ) OUTFILE="$OPTARG" ;;
P | password ) PASSWORD="$OPTARG" ;;
h | help ) usage; exit 0 ;;
??* ) die "illegal option --${OPT}" ;; # bad long option
? ) exit 1 ;; # bad short option (error reported via getopts)
esac
done
main() {
check_openssl
check_args
FILE=$(mktemp)
openssl s_client \
-showcerts \
-connect "$HOST:$PORT" </dev/null 2>/dev/null \
| sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > "$FILE"
keytool -import -trustcacerts -noprompt \
-alias "$HOST" \
-file "$FILE" \
-keystore "$OUTFILE" \
-storepass "$PASSWORD"
rm -f "$FILE"
}
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment