Last active
May 24, 2018 17:40
-
-
Save taikedz/ac16d37822b8ad525a40522518793fda to your computer and use it in GitHub Desktop.
Manipulate a Java key store with a simple purpose-driven tool, rather than remember all those `keytool` options...
This file contains 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 characters
#!/bin/bash | |
# This tool has since been integrated to https://github.com/taikedz/CertMaker | |
set -euo pipefail | |
scr="$(basename "$0")" | |
printhelp() { | |
cat <<EOF | |
Manipulate a Java Key Store using 'keytool' (which has too many options to remember for infrequent use ...) | |
There are typically 3 options to $scr: | |
-k KEYSTORE : the keystore to operate on | |
-a ALIAS : the alias to use for the operation, where appropriate | |
-f TARGETFILE : the file that will be read from or written to, changing depending on the command | |
$scr generate -k KEYSTORE -a ALIAS | |
create a new key store, with a key alias | |
$scr csr -k KEYSTORE -a ALIAS -f CSRFILE | |
derive a CSR from the KEYSTORE from the ALIAS entry | |
$scr add-ca -k KEYSTORE -a ALIAS -f CACERT | |
add a CA certificate file CACERT to the KEYSTORE under ALIAS | |
$scr add-cert -k KEYSTORE -a ALIAS -f CERT | |
add a certificate file CERT to the KEYSTORE under ALIAS | |
$scr add-key -k KEYSTORE -a ALIAS -f KEYFILE | |
add a key file KEYFILE to the KEYSTORE under ALIAS | |
The key file must be either in PEM or PKCS12 format | |
$scr delete -k KEYSTORE -a ALIAS | |
delete an alias ALIAS from the KEYSTORE | |
$scr view -k KEYSTORE [-a ALIAS] | |
view the contents of the keystore, or optionally the contents under the keystore alias | |
EOF | |
} | |
jks:dispatch() { | |
action="$1"; shift | |
case "$action" in | |
generate) | |
jks:gen ;; | |
csr) | |
jks:csr ;; | |
add-ca) | |
jks:add:cacert ;; | |
add-cert) | |
jks:add:cert ;; | |
add-key) | |
jks:add:key ;; | |
delete) | |
jks:delete ;; | |
view) | |
jks:view ;; | |
*) | |
out:fail "Unknown action '$action'" ;; | |
esac | |
} | |
jks:args() { | |
local flag | |
for flag in "$@" | |
do | |
case "$flag" in | |
-k) | |
keystore="$(args:get -k "${SCRIPT_ARGS[@]}")" | |
;; | |
-f) | |
targetfile="$(args:get -f "${SCRIPT_ARGS[@]}")" | |
;; | |
-a) | |
ksalias="$(args:get -a "${SCRIPT_ARGS[@]}")" | |
;; | |
esac | |
done | |
} | |
jks:gen() { | |
jks:args -k -a || out:fail "Keystore and Alias are required" | |
keytool -genkey -alias "$ksalias" -keyalg RSA -keystore "$keystore" -deststoretype pkcs12 | |
} | |
jks:csr() { | |
jks:args -k -a -f || out:fail "Keystore, Alias and Output CSR file are required" | |
keytool -certreq -keyalg RSA -alias "$ksalias" -keystore "$keystore" -file "$targetfile" | |
} | |
jks:add:cacert() { | |
jks:args -k -a -f || out:fail "Keystore, Alias and CA cert are required" | |
keytool -import -alias "$ksalias" -keystore "$keystore" -trustcacerts -file "$targetfile" | |
} | |
jks:add:cert() { | |
jks:args -k -a -f || out:fail "Keystore, Alias and Cert are required" | |
keytool -import -alias "$ksalias" -keystore "$keystore" -file "$targetfile" | |
} | |
jks:ensure_pkcs12() { | |
if [[ "$targetfile" =~ \.*\.p12 ]]; then | |
cat "$targetfile" | |
elif grep -qP "PRIVATE KEY" "$targetfile"; then | |
local certfile="${targetfile%.*}.cer" | |
[[ -f "$certfile" ]] || out:fail "You must provide the certificate file as $certfile" | |
openssl pkcs12 -export -inkey "$targetfile" -in "$certfile" | |
else | |
out:fail "PEM or PKCS12 file required!" | |
fi | |
} | |
jks:add:key() { | |
# Annoyingly, keytool needs a PKCS12 store for importing - it can't simply add a key | |
jks:args -k -a -f || out:fail "Keystore, Alias and Key file (.pem or .p12) are required" | |
local p12data | |
p12data="$(jks:ensure_pkcs12)" # Should fail on its own here if bad file | |
keytool -importkeystore -srckeystore <(echo "$p12data") -destkeystore "$keystore" -srcstoretype pkcs12 | |
} | |
jks:delete() { | |
jks:args -k -a || out:fail "Keystore and Alias are required" | |
keytool -delete -alias "$ksalias" -keystore "$keystore" | |
} | |
jks:view() { | |
jks:args -k || out:fail "Keystore is required" | |
jks:args -a || : | |
if [[ -n "${ksalias:-}" ]]; then | |
keytool -list -alias "$ksalias" -keystore "$keystore" | |
else | |
keytool -list -keystore "$keystore" | |
fi | |
} | |
out:warn() { | |
echo -e "\033[33;1m$*\033[0m" >&2 | |
} | |
out:fail() { | |
echo -e "\033[31;1m$*\033[0m" >&2 | |
echo "Try running '$0 --help'" | |
exit 1 | |
} | |
args:get() { | |
local get token | |
flag="$1" ; shift | |
get=false | |
for token in "$@"; do | |
if [[ "$get" = true ]]; then | |
echo "$token" | |
return 0 | |
elif [[ "$flag" = "$token" ]]; then | |
get=true | |
continue | |
fi | |
# else, nowt | |
done | |
return 1 | |
} | |
main() { | |
if [[ -z "$*" ]] || [[ "$*" =~ --help ]]; then | |
printhelp | |
exit | |
fi | |
SCRIPT_ARGS=("$@") | |
jks:dispatch "$@" | |
} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment