#!/usr/bin/env bash

# shellcheck shell=bash

# ``````````````````````````````````````````````````````````````````````````````
# Function name: DomainChainCheck()
#
# Description:
#   Check domain certificates chain.
#
# Usage:
#   DomainChainCheck domain
#
# Examples:
#   DomainChainCheck example.com
#

function DomainChainCheck() {

  # shellcheck disable=SC2034
  local _FUNCTION_ID="DomainChainCheck"
  local _STATE=0

  # shellcheck disable=SC2034,SC2154
  _ssl_remote_socket="${_domain_ip}:${_domain_port}"
  # shellcheck disable=SC2154
  _ssl_domain_name="$_domain_name"

  # shellcheck disable=SC2034
  _chain_complete=()

  # shellcheck disable=SC2034
  _chain_verify_subjects_stack=()
  # shellcheck disable=SC2034
  _chain_verify_issuers_stack=()

  _cert_chain_hash=()
  _c_h="0"

  # shellcheck disable=SC2154
  echo | \
  $_openssl s_client -showcerts -verify 5 -servername "$_ssl_domain_name" \
  -connect "$_ssl_remote_socket" 2>&1 | \
  awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ if(/BEGIN CERTIFICATE/){a++}; out="../tmp/cert"a".crt"; print >out}'

  # shellcheck disable=SC2154
  for _c_fd in "${_tmp}"/*.crt ; do

    _chain_verify_subjects_t=$($_openssl x509 -noout -subject -in "$_c_fd")
    _chain_verify_issuers_t=$($_openssl x509 -noout -issuer -in "$_c_fd")
    _key_subject_hash=$($_openssl x509 -noout -subject_hash -in "$_c_fd")
    _key_issuer_hash=$($_openssl x509 -noout -issuer_hash -in "$_c_fd")

    # shellcheck disable=SC2154
    # if [[ "$_openssl_version" == "1.1.1" ]] || \
    #    [[ "$_openssl_version" == "1.1.1a" ]] || \
    #    [[ "$_openssl_version" == "1.1.1b" ]] || \
    #    [[ "$_openssl_version" == "1.1.1c" ]] || \
    #    [[ "$_openssl_version" == "1.1.1d" ]] || \
    #    [[ "$_openssl_version" == "1.1.1e" ]] || \
    #    [[ "$_openssl_version" == "1.1.1f" ]] || \
    #    [[ "$_openssl_version" == "1.1.1g" ]] ; then

      _chain_verify_subjects=$(echo "$_chain_verify_subjects_t" | \
                        grep -o "CN =.*" | \
                        cut -d "=" -f2- | \
                        cut -d "," -f1 | \
                        awk '{$1=$1};1')

      _chain_verify_issuers=$(echo "$_chain_verify_issuers_t" | \
                        grep -o "CN =.*" | \
                        cut -d "=" -f2- | \
                        cut -d "," -f1 | \
                        awk '{$1=$1};1')

    # else
    #
    #   _chain_verify_subjects=$(echo "$_chain_verify_subjects_t" | \
    #                     grep -o "/CN=.*" | \
    #                     cut -d "=" -f2- | \
    #                     cut -d "/" -f1 | \
    #                     awk '{$1=$1};1')
    #
    #   _chain_verify_issuers=$(echo "$_chain_verify_issuers_t" | \
    #                     grep -o "/CN=.*" | \
    #                     cut -d "=" -f2- | \
    #                     cut -d "/" -f1 | \
    #                     awk '{$1=$1};1')
    #
    # fi

    _cert_chain_hash+=("${_c_h}:${_chain_verify_subjects}:${_chain_verify_issuers}:${_key_subject_hash}:${_key_issuer_hash}")

    _c_h=$((_c_h + 1))

  done

  _t_rst=' '
  _x_rst='  '

  _c_id="1"

  for i in "${_cert_chain_hash[@]}" ; do

    _id_num=$(echo "${i}" | awk -v FS="(:|:)" '{print $1}')
    _id_subject=$(echo "${i}" | awk -v FS="(:|:)" '{print $2}')
    _id_issuer=$(echo "${i}" | awk -v FS="(:|:)" '{print $3}')
    _id_subject_hash=$(echo "${i}" | awk -v FS="(:|:)" '{print $4}')
    _id_issuer_hash=$(echo "${i}" | awk -v FS="(:|:)" '{print $5}')

    # shellcheck disable=SC2086,SC2154
    printf '%s         └─\e['${trgb_3021}'m%s:%s %s\e[m' \
           "$_t_rst" "$_id_num" "${_id_subject}" "$_id_subject_hash"

    if [[ "$_id_num" -eq 0 ]] ; then

      if [[ "$_id_subject" == "$_ssl_domain_name" ]] ; then

        # shellcheck disable=SC2086,SC2154
        printf ' \e['${trgb_3300}'m%s\e[m' \
               "★"

      else

        # shellcheck disable=SC2086
        # printf ' \e['${trgb_3100}'m%s\e[m' \
        #        "!"

        # shellcheck disable=SC2086,SC2154
        printf ' \e['${trgb_3300}'m%s\e[m' \
               "★"

      fi

    fi

    if [[ "$_id_num" -ne 0 ]] && \
       [[ "$_id_issuer_hash_last" == "$_id_subject_hash" ]] ; then

      # shellcheck disable=SC2086,SC2154
      printf ' \e['${trgb_3200}'m%s\e[m' \
             "✓"

    elif [[ "$_id_num" -ne 0 ]] ; then

      # shellcheck disable=SC2086,SC2154
      printf ' \e['${trgb_3100}'m%s\e[m' \
             "×"

    fi

    if [[ "$_id_subject_hash" == "$_id_issuer_hash" ]] ; then

      # shellcheck disable=SC2086
      printf ' \e['${trgb_3300}'m%s\e[m' \
               "2x"

    fi

    if [[ "${#_cert_chain_hash[@]}" -eq "$_c_id" ]] ; then

      # shellcheck disable=SC2086,SC2154
      printf '\n%s           └ \e['${trgb_3812}'m%s %s\e[m' \
             "$_t_rst" "$_id_issuer" "$_id_issuer_hash"

      if [[ "$HTRACE_SSL_CERT_CA_CHECK" == "on" ]] ; then

        # shellcheck disable=SC2154
        if [[ -d "$_ssl_ca_path" ]] ; then

          # shellcheck disable=SC2044,SC2154
          for j in $(find "$_ssl_ca_path" -name "*.pem" > /dev/null 2>&1) ; do

            _lstore_state=$(awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' < "$j")
            _lstore_state_c=$(echo "$_lstore_state" | grep "$_id_issuer")

            # shellcheck disable=SC2154
            if [[ -n "$_lstore_state_c" ]] ; then

              _root_certificate_issuer=$(echo "$_lstore_state_c" | \
                         grep -o "CN =.*" | \
                         cut -d "=" -f2- | \
                         cut -d "/" -f1 | \
                         awk '{$1=$1};1')

              # shellcheck disable=SC2086
              printf ' \e['${trgb_3200}'m%s\e[m' \
                     "(in a local trust store)"

            else

              # shellcheck disable=SC2086
              printf ' \e['${trgb_3100}'m%s\e[m' \
                     "(not in a local trust store)"

            fi

          done

        elif [[ -f "$_ssl_ca_path" ]] ; then

          _lstore_state=$(awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' < "$_ssl_ca_path")
          _lstore_state_c=$(echo "$_lstore_state" | grep "$_id_issuer")

          # shellcheck disable=SC2154
          if [[ -n "$_lstore_state_c" ]] ; then

            # shellcheck disable=SC2034
            _root_certificate_issuer=$(echo "$_lstore_state_c" | \
                       grep -o "CN =.*" | \
                       cut -d "=" -f2- | \
                       cut -d "/" -f1 | \
                       awk '{$1=$1};1')

            # shellcheck disable=SC2086
            printf ' \e['${trgb_3200}'m%s\e[m' \
                   "⊙"

          else

            # shellcheck disable=SC2086
            printf ' \e['${trgb_3100}'m%s\e[m' \
                   "⊙"

          fi

        fi

      fi

    else

      # shellcheck disable=SC2086,SC2154
      printf '\n%s           ├   \e['${trgb_3812}'m%s %s\e[m\n' \
             "$_t_rst" "$_id_issuer" "$_id_issuer_hash"

    fi

    _id_issuer_hash_last="$_id_issuer_hash"

    _c_id=$((_c_id + 1))
    _t_rst+="$_x_rst"

  done

  echo

  return $_STATE

}
