diff options
| author | Jan Pokorný <jpokorny@redhat.com> | 2013-04-11 15:59:05 +0200 |
|---|---|---|
| committer | Jan Pokorný <jpokorny@redhat.com> | 2013-04-11 15:59:05 +0200 |
| commit | 2f06a5c56d00a8f460c241a072a983488de5345b (patch) | |
| tree | 778e5ba05d2ae6b1c7b6e4dffcfb5ed5fe2ce855 /scripts | |
| parent | f06b4321e6eddfc71cfd20ebb4c891099e44c1d8 (diff) | |
| download | dotfiles-2f06a5c56d00a8f460c241a072a983488de5345b.tar.gz dotfiles-2f06a5c56d00a8f460c241a072a983488de5345b.tar.xz dotfiles-2f06a5c56d00a8f460c241a072a983488de5345b.zip | |
Scripts/cert-check: massive update
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
Diffstat (limited to 'scripts')
| -rwxr-xr-x | scripts/certs/cert-check | 142 |
1 files changed, 112 insertions, 30 deletions
diff --git a/scripts/certs/cert-check b/scripts/certs/cert-check index cf9c8a6..09b1a0f 100755 --- a/scripts/certs/cert-check +++ b/scripts/certs/cert-check @@ -13,52 +13,134 @@ # twice in two substituted commands and neither env. variable nor # file descriptor sharing is suitable (stdin can be read only once, # generally, there is a race between the two?) +# - wget vs. certificates? switch to curl? -set -eu +set -u +set +e -WGET="wget -nv" CA_BUNDLE=/etc/pki/tls/certs/ca-bundle.crt +HOMEBUNDLE=~/.pki/tls/certs/ca-bundle.crt +#WGET="wget -nv --ca-certificate <(cat "${CA_BUNDLE}" "${HOMEBUNDLE}")" +WGET="wget -nv" + +guess_inform() { + case "{1##*.}" in + crt) echo DER;; + pem|*) echo PEM;; + esac +} + +cert_pick_file() { + echo "Trying file" >&2 + local inform=$(guess_inform "$1") + [ -f "$1" ] && openssl x509 -inform "${inform}" -in "$1" +} + +# when CA cert is hosted on https server signed by this very CA +cert_pick_url_selfsigned() { + [[ "$1" =~ https://.* ]] || return 1 + echo "Trying self-signed" >&2 + local ret= + local start=${1##https://} + local host=${start%%/*} + local machine=${host%%:*} + local port=${host#*:} + [ "${port}" = "" ] && port=443 + local cont=${start#*/} + local inform=$(guess_inform "${cont}") + ( echo -e "GET /${cont} /HTTP 1.0\n"; sleep 2 ) \ + | openssl s_client -connect "${machine}:${port}" -crlf 2>/dev/null \ + | sed -ne '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' \ + | ( local tmpfile=$(mktemp /tmp/.XXXXXX) + cat >${tmpfile} + openssl verify -CAfile \ + <(awk '/-BEGIN CERTIFICATE-/{if(++i > 2){print; exit;}}{if(i == 2){print;}}' ${tmpfile} \ + | cat "${CA_BUNDLE}" "${HOMEBUNDLE}" -) \ + <(awk '/-BEGIN CERTIFICATE-/{if(++i > 2){exit;}}{if(i == 1){print;}}' ${tmpfile}) >&2; + ret=$? + [ $ret -eq 0 ] \ + && openssl x509 -inform "${inform}" -in ${tmpfile} + rm -- ${tmpfile} + return $ret ) +} + +cert_pick_url() { + echo "Trying URL.." >&2 + local inform=$(guess_inform "$1") + (if ! ${WGET} "$1" -O- && [[ "$1" =~ https://.* ]]; then + local start=${1##https://} + local host=${start%%/*} + local machine=${host%%:*} + local port=${host#*:} + [ "${port}" = "${machine}" ] && port=443 + ( echo ">>> recursion" >&2 + main "${machine}" "${port}" \ + || main -nocrl "${machine}" "${port}" + echo "<<< recursion" >&2 ) >&2 \ + && ${WGET} --no-check-certificate "$1" -O- + fi) | openssl x509 -inform "${inform}" +} -_download_cert() { +cert_pick_from_server() { + echo "Trying from server.." >&2 local server=$1 local port=443 # https - [ $# -ge 2 ] && $port=$2 - # sleep so as to prevent premature socket close + [ $# -ge 2 ] && port=$2 ( echo; sleep 2 ) \ - | openssl s_client -connect "${server}:${port}" -crlf 2>/dev/null + | openssl s_client -connect "${server}:${port}" -crlf 2>/dev/null \ + | sed -ne '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' \ + | awk '/-BEGIN CERTIFICATE-/{if(++i > 1){exit;}}{print;}' +} + +cert_pick() { + cert_pick_file "$@" \ + || cert_pick_url_selfsigned "$@" \ + || cert_pick_url "$@" \ + || cert_pick_from_server "$@" } cert_check() { - local ret= crl=1 - [ "$1" = "-nocrl" ] && shift && crl=0 - ( [ -f "$1" ] && cat -- "$1" || _download_cert "$@" ) \ - | sed -ne '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' \ - | ( cat >/tmp/.$$; - openssl verify $([ $crl -ne 0 ] && echo '-crl_check') -CAfile \ - <(awk '/-BEGIN CERTIFICATE-/{if(++i > 1){exit;}}{print;}' /tmp/.$$ \ - | openssl x509 -noout -text \ - | sed -n 's|.*URI:\(.\+\.cr[tl]\)|\1|p' \ - | xargs -I '{}' bash -c " case '{}' in \ - *crt) ${WGET} -O- '{}' | openssl x509 -inform DER -outform PEM;; \ - *crl) ${WGET} -O- '{}' | openssl crl -inform DER -outform PEM;; \ - *) echo 'Sorry, {} not supported' >&2; \ - esac" \ - | cat "${CA_BUNDLE}" -) \ - <(awk '/-BEGIN CERTIFICATE-/{if(++i > 1){exit;}}{print;}' /tmp/.$$); - ret=$? - rm -- /tmp/.$$ - return $ret ) + local ret= tmpfile=$(mktemp /tmp/.XXXXXX) + cat >${tmpfile} + openssl verify $([ "$1" != "0" ] && echo '-crl_check') -CAfile \ + <( openssl x509 -noout -text -in ${tmpfile} \ + | sed -n 's|.*URI:\(.\+\.cr[tl]\)|\1|p' \ + | xargs -I '{}' bash -c " case '{}' in \ + *crt) ${WGET} -O- '{}' | openssl x509 -inform DER -outform PEM;; \ + *crl) ${WGET} -O- '{}' | openssl crl -inform DER -outform PEM;; \ + *) echo 'Sorry, {} not supported' >&2; \ + esac" \ + | cat "${CA_BUNDLE}" "${HOMEBUNDLE}" - 2>/dev/null ) \ + ${tmpfile} >&2 + ret=$? + [ $ret -eq 0 ] && cat ${tmpfile} + rm -- ${tmpfile} + echo "$ret" >&2 + return $ret } colorize() { - test -t 1 \ - && sed \ + # last line = exitcode + ( ( test -t 1 || [ $# -ge 1 ] ) \ + && sed -u \ + -e 's|\(^Trying.*$\)|\x1b[33m\1\x1b[0m|' \ + -e 's|\(^Adding.*$\)|\x1b[33m\1\x1b[0m|' \ -e 's|\(^error\s\+.*\)|\x1b[31m\1\x1b[0m|' \ -e 's|\(^\S\+:.*\)|\x1b[32m\1\x1b[0m|' \ -e 's|\(^\S\+\s\+\S\+\s\+URL:.*\)|\x1b[36m\1\x1b[0m|' \ - || cat + || cat ) | awk 'FNR == 1 { last=$1; while (getline) { print last; last=$0; } exit last}' +} + +pseudo_return() { + return $1 +} + +main() { + local crl=1 + [ "$1" = "-nocrl" ] && shift && crl=0 + cert_pick "$@" | cert_check $crl } [[ "${BASH_SOURCE[0]}" != "${0}" ]] || \ - [ $# -lt 1 ] && echo "usage: $0 [-nocrl] file-or-server [port=443]" \ - || cert_check "$@" |& colorize + ( [ $# -lt 1 ] && echo "usage: $0 [-nocrl] file-or-url-or-server [server-port=443]" \ + || ( main "$@"; echo $? ) |& colorize 1 && set +u || ( ret=$?; set +u; pseudo_return $ret )) |
