#!/bin/sh
#  $Id: security_certinfo.sh 144933 2017-02-08 09:50:25Z justin.carveley@oracle.com $
#  Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
#
#  Author: Sarah Bateman
#
#  Prints out CSR and certificate information 
#  and validates a certificate and key pair.
#

# be paranoid about the current path
if [ -d /bin ]; then
  PATH=/bin:$PATH
fi
if [ -d /sbin ]; then
  PATH=/sbin:$PATH
fi
if [ -d /usr/bin ]; then
  PATH=/usr/bin:$PATH
fi
if [ -d /usr/sbin ]; then
  PATH=/usr/sbin:$PATH
fi
if [ -d /etc ]; then
  PATH=/etc:$PATH
fi
export PATH

N=""
C=""
if echo -n | grep n > /dev/null
then
  C="\c"
else
  N="-n"
fi
case "$MACHINEARCH" in
i3li*|ppli*) N="$N -e" ;;
esac
_ss_headlines="--------------------------------------------------------------------------"

if [ -f $TTAMSG/common -a -f $TTAMSG/security_certinfo ]; then
  . $TTAMSG/common
  . $TTAMSG/security_certinfo
else
  echo "Unable to open message file: $TTAMSG/security_certinfo"
  exit 1
fi


OPENSSL_BINARY=openssl
OPENSSL_HELPER=$TTABINDIR/scripts/openssl_lib.sh
CONFIG_FILE=$TTAINSTDIR/etc/data/openssl.cnf

TSPDIR=$TTADATADIR/tsp
TTAKEY_FILE=$TSPDIR/key.pem
TTACERT_FILE=$TSPDIR/cert.pem

TMP_KEY="$TTADATADIR/tmp/tmp.pem"
csrfile=""
certfile=""
keyfile=""
validateopt=""
infoopt="-subject"
noargs=0

usage() 
{
  echo "$lf_certinfo_usage" 1>&2
}

short_usage() {
    echo "$1" 1>&2
    echo "$sf_certinfo_usage" 1>&2
}

#
# Does a "shift" only if there are some parameters left
#
SHIFT='if [ $# -ge 1 ]; then 
    last_shift=$1; 
    shift; 
else 
    short_usage "$l_missing_arg1$last_shift$l_missing_arg2";
    exit 1; 
fi'

#
# Does a quick check on a certificate file and exits if it's not valid. The
# error message depends on $2 which is only filled in if the certificate
# is in a file and NOT from stdin
#
validate_cert()
{
  grep "BEGIN.*CERTIFICATE" $1 >/dev/null 2>/dev/null
  if [ $? != 0 ];then
    if [ -n "$2" ];then
      echo "$l_invalid_cert_1$2$l_invalid_cert_2"
    else
      echo "$l_invalid_cert_3"
    fi
    exit 1
  fi
}

#
# Validate the key file similarly. A key can only come in a file so we don't
# need to customise the error for the stdin case
#
validate_key()
{
  grep "BEGIN.*PRIVATE KEY" $1 >/dev/null 2>/dev/null
  if [ $? != 0 ];then
    echo "$l_invalid_key_1"
    exit 1
  fi
}

#
# Validate the CSR file similarly. 
#
validate_csr()
{
  grep "BEGIN.*REQUEST" $1 >/dev/null 2>/dev/null
  if [ $? != 0 ];then
    echo "$l_invalid_csr_1$2$l_invalid_csr_2"
    exit 1
  fi
}



#
# Parse command-line parameters
#
while [ -n "$1" ]; do
    noargs=1
    case $1 in
        --certfile ) certfile=$2; eval "$SHIFT"; eval "$SHIFT";;
        --keyfile ) keyfile=$2; eval "$SHIFT"; eval "$SHIFT";;
	--csrfile ) csrfile=$2; eval "$SHIFT"; eval "$SHIFT";;
	--full ) infoopt="-text"; eval "$SHIFT";;
   --help ) usage; exit 0;;
	* ) short_usage "$l_invalid_arg1$1$l_invalid_arg2" ; exit 1;;
    esac
done

#
# If we have --keyfile make sure we also have --certfile
#
if [ -n "$keyfile" ]; then
  if [ -z "$certfile" ]; then
    short_usage "$l_keyfile_needs_certfile"
    exit 1
  fi

  # Make sure we check the keyfile against the certfile
  validateopt="-checkkey"
fi

#
# If no args are supplied we check the installed key and certifcate
#
if [ -z "$csrfile" -a -z "$certfile" ]; then
    echo ""

    # want to check the key and certifcate
    if [ $noargs = 0 ]; then
      validateopt="-checkkey"
    fi

    # Check that the files exist
    if [ ! -f "$TTACERT_FILE" ]; then
      echo "$l_server_cert_not_installed"
      exit 1
    else
      echo "$l_using_server_cert"
      certfile=$TTACERT_FILE
    fi

    if [ ! -f "$TTAKEY_FILE" ]; then
      echo "$l_server_key_notInstalled"
    else
      echo "$l_using_server_key"
      keyfile=$TTAKEY_FILE
    fi
fi

#
# Ensure protection on the files
#
umask 077




#
# READ THE CSR
#
if [ -n "$csrfile" ]; then


    CFGOPT="-config $CONFIG_FILE"

    # Check that the file exists
    if [ ! -f "$csrfile" ]; then
	echo "$l_csrfile_does_not_exist"
	exit 2
    fi

    # if the config file doesn't exist, don't send anything
    if [ ! -f "$CONFIG_FILE" ]; then
	CFGOPT=""
    fi


    validate_csr "$csrfile" "$csrfile"

    # print out csr information
    
echo $_ss_headlines
echo "$h_ssleay_csr_info"
echo $_ss_headlines

    echo "${l_ssleay_csr_info1}$csrfile${l_ssleay_csr_info2}"    
    $OPENSSL_BINARY req -in $csrfile $infoopt $CFGOPT

    echo ""

fi



#
# READ THE CERTIFICATE AND CHECK THE KEY IF NECESSARY
#
if [ -n "$certfile" ]; then

    # Check that the cert file exists
    if [ ! -f "$certfile" ]; then
	echo "$l_certfile_does_not_exist"
	exit 2
    fi

    # Check that the key file exists
    if [ -n "$keyfile" -a ! -f "$keyfile" ]; then
	echo "$l_keyfile_does_not_exist"
	exit 2
    fi

    # Validate the certificate file and the key file.
    validate_cert "$certfile" "$certfile"
    if [ -n "$validateopt" ]; then
	validate_key "$keyfile" "$keyfile"
    fi

    # print out certificate information
echo $_ss_headlines
echo "$h_ssleay_cert_check"
echo $_ss_headlines


    if [ -n "$keyfile" ]; then
        #we have a key file validate that too.
        `${OPENSSL_HELPER} checkkey --cert=${certfile} --key=${keyfile}` 
        [ $? -eq 0 ] && {
            ${OPENSSL_HELPER} textsummary --cert=${certfile}
        }
    else
        ${OPENSSL_HELPER} textsummary --cert=${certfile}
    fi

    errcode=$?
    
    # print out the correct message depending on the errorcode.
    
    echo ""
    
    if [ $errcode -eq 0 ]; then 
	# a match!
	if [ -n "$validateopt" ]; then
	    echo "$l_ssleay_key_match"
	fi
    elif [ $errcode -eq 7 ]; then 
	# NOT a match
	echo "$l_ssleay_key_mismatch"
	echo "$l_ssleay_wrong_key"
    else
	# various errors due to ssleay
	echo "$l_ssleay_check_failure"
	if [ $errcode -eq 6 ]; then 
	    echo "$l_ssleay_no_key"
	elif [ $errcode -eq 5 ]; then 
	    echo "$l_ssleay_cert_extract"
	elif [ $errcode -eq 4 ]; then 
	    echo "$l_ssleay_bad_cert"
	elif [ $errcode -eq 3 ]; then 
	    echo "$l_ssleay_ctx_failure"
	elif [ $errcode -eq 2 ]; then 
	    echo "$l_ssleay_key_mismatch" 
	elif [ $errcode -eq 1 ]; then 
	    echo "$l_ssleay_bad_options"
	else
	    # unknown error 
	    echo "$l_ssleay_unknown"
	fi
    fi
    echo ""

    rm -f $TMP_KEY

fi


exit 0
