Skip to content

Instantly share code, notes, and snippets.

@gabrielfalcao
Created November 21, 2025 18:21
Show Gist options
  • Select an option

  • Save gabrielfalcao/36e327069048412c6cec0906decbaa84 to your computer and use it in GitHub Desktop.

Select an option

Save gabrielfalcao/36e327069048412c6cec0906decbaa84 to your computer and use it in GitHub Desktop.
automatically download, install and trust DoD Root certificate on MacOS
#!/usr/bin/env bash
set -e
set -o pipefail
set -u
export IFS=$'\n'
unset IFS
declare -- cert_filename="DoD-Root-CA-3.cer"
declare -A cert_checksums=(
["crc32"]="8789d796"
["sha1sum"]="d73ca91102a2204a36459ed32213b467d7ce97fb"
["sha256sum"]="b107b33f453e5510f68e513110c6f6944bacc263df0137f821c1b3c2f8f863d2"
["sha384sum"]="3bf0696644c55d33fc3f9470c575b3186dcf50e0d9f4111f8a6ea9e0c2cbb61efd0d4768afb5db2ff88581366087d546"
["sha512sum"]="8f6b9d8c4d77fa32bc95b86a41215b7449058aa23d50bf823fdc969c492f6e765e6ef9cfd990b153acbe7681137658cf29480d8b085582fb26c97bc9f96c7ea9"
)
declare -- base_url="https://mobileconnect.cce.af.mil"
declare -- static_index_url="https://mobileconnect.cce.af.mil/cert"
declare -- js_app_url=""
declare -- default_cert_download_url="https://nps.edu/documents/111151326/111164251/DoD-Root-CA-3.cer/2b94718d-5f88-8eaf-3bda-92e0fc548412?t=1619469888977"
declare -- stderr=$(mktemp)
script_name="$(basename "${BASH_SOURCE[0]}")"
script_path="$(2>/dev/random 1>/dev/random cd $(dirname "${BASH_SOURCE[0]}") && pwd)"
this_script_path="${script_path}/${script_name}"
declare -a argv=($@)
declare argc=${#argv[@]}
declare -A cli_args_option_list=()
declare -A cli_args_flag_list=()
declare -a cli_args_value_list=()
declare -a valid_argument_types=('flag' 'option' 'value')
declare -- error_prefix_color_rgb="255;0;66"
declare -- error_color_rgb="255;62;92"
declare -- warn_prefix_color_rgb="255;106;50"
declare -- warn_color_rgb="255;161;50"
declare -- info_prefix_color_rgb="0;66;255"
declare -- info_color_rgb="62;92;255"
declare -- debug_prefix_color_rgb="50;255;106"
declare -- debug_color_rgb="50;255;161"
on_exit() {
rm -f "static.html" "app.js"
repl sane
}
on_ctrlc() {
repl no echo
1>&2 echo -e "\x1b[1;38;2;${error_color_rgb}m\rAborted with Ctrl-C\x1b[0m"
repl sane
exit 1
}
trap on_exit exit
trap on_ctrlc hup
trap on_ctrlc int
trap on_ctrlc bus
trap on_ctrlc segv
trap on_ctrlc sys
repl() {
local -a stty_args=()
case "$1" in -*no*stdin | no*stdin | -*no*echo | no*echo | capture) args+=('-echo') ;; *) args+=('sane') ;; esac
2>/dev/random 1>/dev/random stty ${stty_args[@]}
}
usage() {
repl no echo
1>&2 echo -e "$(basename $0) <ARGUMENT>"
repl sane
}
exit_error() {
error "${@}"
exit 1
}
warn_prefixed() {
local -- prefix="$1"
shift
local -- message="$@"
1>&2 echo -e "\x1b[1;38;2;${warn_prefix_color_rgb}m${prefix}\x1b[1;38;2;${warn_color_rgb}m ${message}\x1b[0m"
}
warn() {
local -- linenum="${BASH_LINENO[0]}"
warn_prefixed "[warn] [${script_name}:${linenum}]" "${@}"
}
error() {
local -- linenum="${BASH_LINENO[0]}"
error_prefixed "[error] [${script_name}:${linenum}]" "${@}"
}
error_prefixed() {
local -- prefix="$1"
shift
local -- message="$@"
1>&2 echo -e "\x1b[1;38;2;${error_prefix_color_rgb}m${prefix}\x1b[1;38;2;${error_color_rgb}m ${message}\x1b[0m"
}
info() {
local -- linenum="${BASH_LINENO[0]}"
info_prefixed "[info] [${script_name}:${linenum}]" "${@}"
}
info_prefixed() {
local -- prefix="$1"
shift
local -- message="$@"
1>&2 echo -e "\x1b[1;38;2;${info_prefix_color_rgb}m${prefix}\x1b[1;38;2;${info_color_rgb}m ${message}\x1b[0m"
}
debug_prefixed() {
local -- prefix="$1"
shift
local -- message="$@"
1>&2 echo -e "\x1b[1;38;2;${debug_prefix_color_rgb}m${prefix}\x1b[1;38;2;${debug_color_rgb}m ${message}\x1b[0m"
}
debug() {
local -- linenum="${BASH_LINENO[0]}"
debug_prefixed "[debug] [${script_name}:${linenum}]" "${@}"
}
trace() {
if [ -z "${BASH_TRACE}" ] && [ "${BASH_LOGLEVEL}" != "trace" ]; then
return 0
fi
local -- linenum="${BASH_LINENO[0]}"
local -- funcname="${FUNCNAME[1]}"
debug_prefixed "[${FUNCNAME[0]} ${script_name}::${funcname}:${linenum}]" "${@}"
}
process_argv() {
repl no echo
repl sane
}
get_certificate_url() {
if [ ! -e "app.js" ]; then
if [ ! -e "static.html" ]; then
info_prefixed "[certificate url]" "querying \x1b[1;38;5;231mmobileconnect.cce.af.mil"
2>${stderr} curl "${static_index_url}" > static.html
fi
js_app_pathname=$(sed -n -E 's/^.*script.*src="([^"]*main[.][^"]*[.]js)".*$/\1/gp' static.html)
if [ -z "${js_app_pathname}" ]; then
1>&2 echo -e "[error] could not determine url of js app"
exit 1
fi
if grep -E '^https?://' <<< "${js_app_pathname}"; then
js_app_url="${js_app_pathname}"
elif grep -E '^/' <<< "${js_app_pathname}"; then
js_app_url="${base_url}${js_app_pathname}"
else
js_app_url="${static_index_url}${js_app_pathname}"
fi
info_prefixed "[certificate url]" "checking javascript app data \x1b[1;38;5;231mmobileconnect.cce.af.mil"
2>${stderr} curl "${js_app_url}" > app.js
fi
regex='^.*href:"(https:\/\/[^"]+DoD-Root-CA-3[.]cer[^"]+)".*$'
if latest_download_url=$(sed -n -E "s/${regex}/\n\1\n/gp" app.js | sort -u | sed -E '/^\s*$/d'); then
echo "${latest_download_url}"
else
1>&2 echo -e "[warning] could parse latest certificate url from ${static_index_url}, using default url"
echo "${default_cert_download_url}"
fi
}
download_certificate() {
download_url=$(get_certificate_url)
info_prefixed "[downloading certificate]" "${cert_filename}"
2>${stderr} curl "${download_url}" > ${cert_filename}
info_prefixed "[checking integrity]"
local -A passed=()
local -A failed=()
for algo in ${!cert_checksums[@]}; do
local -- expected_value=${cert_checksums["$algo"]}
if check_integrity=$(which ${algo}); then
rgb_color="\x1b[1;38;2;$(( 0x${expected_value:0:2} ));$(( 0x${expected_value:2:2} ));$(( 0x${expected_value:4:2} ))m"
info_prefixed "[checking integrity]" "${rgb_color}${algo}"
if calc=$($check_integrity "${cert_filename}" | awk '{print $1}'); then
if [ "${calc}" == "${cert_checksums[${algo}]}" ]; then
passed+=(["${algo}"]="${calc}")
else
failed+=(["${algo}"]="${calc}")
fi
fi
else
warn_prefixed "[checking integrity]" "could not find ${algo} binary in \$PATH"
continue
fi
done
if [ ${#failed[@]} -gt 0 ]; then
for algo in ${!failed[@]}; do
error_prefixed "[checking integrity]" "${algo} checksum mismatch: expected ${cert_checksums[${algo}]@Q} got ${failed[${algo}]@Q}"
done
else
info_prefixed "[checking integrity]" "succeeded: \x1b[1;38;5;231m${!passed[@]}"
fi
}
main() {
download_certificate
info "installing ${cert_filename} in keychain"
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "${cert_filename}"
info "trusting ${cert_filename} in keychain"
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "${cert_filename}"
}
if [ "${0}" == "${BASH_SOURCE[0]}" ]; then
if process_argv ${argv[@]}; then
main
fi
else
1>&2 echo -e "${BASH_SOURCE[0]} appears to being used as a library by ${0@Q}"
fi
repl sane
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment