#!/usr/bin/sh #---------------------------------------------------------------------------------------- # /var/install/bin/certs-show-tls-certs - show certificates # # Copyright (c) 2001-2025 The Eisfair Team, team(at)eisfair(dot)org # # Creation: 2003-08-24 jed # Last Update: $Id$ # # Parameters: # # certs-show-tls-certs - show certificate start- and end-date # certs-show-tls-certs [--showcertchain] - show certificate chain # certs-show-tls-certs [--showcertdates] - show certificate start- and end-date # certs-show-tls-certs [--showcertdetails] - show certificate details # certs-show-tls-certs [--showcsrdetails] - show certificate request # certs-show-tls-certs [--showcrldetails] - show certificate revocation list # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. #---------------------------------------------------------------------------------------- # include eislib . /var/install/include/eislib . /var/install/include/jedlib #exec 2>/tmp/show-tls-certs-trace-$$.log #set -x #---------------------------------------------------------------------------------------- # display certification dates #---------------------------------------------------------------------------------------- display_certs_dates () { # print current date echo "Current date : `date +\"%b %d %T %Y %Z\"`" echo ls ${certdir}/*.pem > /dev/null 2> /dev/null if [ $? -eq 0 ] then # files found, go on ... # separator set to newline (\n) to handle file names which contain spaces correctly oldifs="$IFS" IFS=$'\n' filelist=$(find ${certdir} -maxdepth 1 \( -type f -or -type l \) -name "*.pem" -printf '%p\n' | sort) for CNAME in ${filelist} do # get certificate dates if [ -s "${CNAME}" ] then # Show CNAME first echo "Certificate : ${CNAME}" # openssl may print error messages subject=`${openssl_bin} x509 -in "${CNAME}" -noout -subject | cut -d' ' -f2-` startdate=`${openssl_bin} x509 -in "${CNAME}" -noout -startdate | cut -d= -f2` enddate=`${openssl_bin} x509 -in "${CNAME}" -noout -enddate | cut -d= -f2` # print certificate data echo " Subject : ${subject}" echo " Valid from : ${startdate}" echo " Valid until: ${enddate}" echo else mecho --error "File '${CNAME}' doesn't exist or has a file size of 0." echo fi done IFS="${oldifs}" else echo "WARNING: no files found!" fi } #---------------------------------------------------------------------------------------- # get list of certificates # $1 - certificate type #---------------------------------------------------------------------------------------- get_list_of_certs () { case ${1} in crl ) gl_dir=${crldir} gl_ext='pem' ;; csr ) gl_dir=${csrdir} gl_ext='csr' ;; cert|chain|* ) gl_dir=${certdir} gl_ext='pem' ;; esac ls ${gl_dir}/*.${gl_ext} > /dev/null 2> /dev/null if [ $? -eq 0 ] then # files found, go on ... filelist=$(find ${gl_dir} -maxdepth 1 \( -type f -or -type l \) -name "*.${gl_ext}" -printf '%p\n' | sort | \ sed -e 's#(#\\\(#g' -e 's#)#\\\)#g' -e 's# #\\\ #g') # separator set to newline (\n) to handle file names which contain spaces correctly idx=1 oldifs="$IFS" IFS=$'\n' for CNAME in ${filelist} do tmp_cname=`basename "${CNAME}"` if [ -L "${CNAME}" ] then # symbolic link org_file="`readlink -e "${CNAME}"`" if [ -n "${org_file}" ] then tmp_org_file=`basename "${org_file}"` else tmp_org_file='this_is_a_dead_symbolic_link!' fi eval CERTS_NAME_${idx}="${tmp_cname}#${tmp_org_file}" else eval CERTS_NAME_${idx}="${tmp_cname}" fi CERTS_NAME_N=${idx} idx=`expr ${idx} + 1` done IFS="${oldifs}" else # no files found CERTS_NAME_N=0 fi } #---------------------------------------------------------------------------------------- # print header # $1 - certificate type #---------------------------------------------------------------------------------------- print_header () { clrhome mecho --info "Show ${1}-details" mecho case ${dct} in cert|chain ) # rembember: header column width need to be aligned in print_list_of_certs techo --begin 5r 1 35 4 35 techo --row --info "Nbr" "" -info "Certificate Name(s) (.pem)" --info "(->" -info "Symbolic Link to..) (.pem)" ;; crl ) # rembember: header column width need to be aligned in print_list_of_certs techo --begin 5r 1 64 techo --row --info "Nbr" "" --info "Revocation List(s)" ;; csr ) # rembember: header column width need to be aligned in print_list_of_certs techo --begin 5r 1 64 techo --row --info "Nbr" "" --info "Certificate Request(s)" ;; esac } #---------------------------------------------------------------------------------------- # print list of certificates # $1 - certificate type #---------------------------------------------------------------------------------------- print_list_of_certs () { dct=$1 case ${dct} in crl ) pl_len=63 # value+1 must match header column width in print_header pl_ext='pem' ;; csr ) pl_len=63 # value+1 must match header column width in print_header pl_ext='csr' ;; cert|chain|* ) pl_len=34 # value+1 must match header column width in print_header pl_ext='pem' ;; esac print_header ${dct} row=4 if [ ${CERTS_NAME_N} -gt 0 ] then # files found, go on ... dc_exit=0 idx=0 # number of current entry start_idx=1 # first entry of list while [ ${idx} -le ${CERTS_NAME_N} -a ${dc_exit} -eq 0 ] do idx=`expr ${idx} + 1` row=`expr ${row} + 1` eval cname_org='$CERTS_NAME_'${idx} # check for symbolic link echo ${cname_org} | grep -q '#' if [ $? -eq 0 ] then # symbolic link, reformat string cname_tmp="`echo "${cname_org}" | cut -d# -f1`" cname_tmp="`basename "${cname_tmp}" ".${pl_ext}"`" cname_1=`shorten_string "${cname_tmp}" ${pl_len}` cname_tmp="`echo "${cname_org}" | cut -d# -f2`" cname_2="`basename "${cname_tmp}" ".${pl_ext}"`" else # non-symbolic link cname_tmp="`basename "${cname_org}" ".${pl_ext}"`" cname_1="`shorten_string "${cname_tmp}" ${pl_len}`" cname_2='' fi if [ -z "${cname_2}" ] then techo --row ${idx} "" "${cname_1}" else # cehck if a dead symbolic link was found echo "${cname_2}" | grep -q 'dead' if [ $? -eq 0 ] then # dead symbolic link found, print error message techo --row ${idx} "" "${cname_1}" " ->" --error "${cname_2}" else techo --row ${idx} "" "${cname_1}" " ->" --warn "${cname_2}" fi fi if [ "${act_pmode}" = 'tty' ] then if [ ${row} -eq ${maxrownum} -o ${idx} -ge ${CERTS_NAME_N} ] then end_idx=${idx} # last entry of list echo # Select (1-30, ENTER=Return, 0=Exit)? /var/install/bin/ask "Please select (${start_idx}-${end_idx} [${CERTS_NAME_N}], ENTER=Return, 0=Exit)" '' '*' > ${ask_tmpfile} rc=$? cnum=`cat ${ask_tmpfile}` rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi case ${cnum} in 0|q|Q ) # quit dc_exit=1 ;; * ) if is_numeric ${cnum} then # numeric if [ ${cnum} -ge ${start_idx} -a ${cnum} -le ${end_idx} ] then clrhome mecho --info "Show certificate details" mecho print_cert ${cnum} ${dc_type} print_header ${dct} else mecho mecho --error "Error: input not in range, try again!" mecho anykey print_header fi idx=`expr ${start_idx} - 1` else # non-numeric if [ ${idx} -lt ${CERTS_NAME_N} ] then print_header ${dct} start_idx=`expr ${idx} + 1` fi fi ;; esac row=4 if [ ${idx} -ge ${CERTS_NAME_N} ] then # quit dc_exit=1 fi fi fi done techo --end else mecho --warn " no files found!" fi } #---------------------------------------------------------------------------------------- # print certificate # $1 - certificate name # $2 - certificate type #---------------------------------------------------------------------------------------- print_cert () { eval cname='$CERTS_NAME_'${1} echo "${cname}" | grep -q '#' if [ $? -eq 0 ] then cname=`echo "${cname}" | cut -d# -f1` fi mecho case ${2} in chain ) if [ -s "${certdir}/${cname}" ] then /var/install/bin/certs-show-chain "${cname}" if [ $? -ne 0 ] then mecho --error "File '${certdir}/${cname}' has errors" anykey fi else mecho --error "File '${certdir}/${cname}' doesn't exist or has a file size of 0." anykey fi ;; crl ) if [ -s "${crldir}/${cname}" ] then { echo "File name: ${crldir}/${cname}" echo ${openssl_bin} crl -inform pem -in "${crldir}/${cname}" -noout -text } > ${tmpfile} if [ $? -eq 0 ] then /var/install/bin/show-doc.cui ${color} ${frame} --title "Show certificate revocation list" ${tmpfile} else mecho --error "File '${certdir}/${cname}' has errors" anykey fi else mecho --error "File '${crldir}/${cname}' doesn't exist or has a file size of 0." anykey fi ;; csr ) if [ -s "${csrdir}/${cname}" ] then { echo "File name: ${csrdir}/${cname}" echo ${openssl_bin} req -in "${csrdir}/${cname}" -noout -text } > ${tmpfile} if [ $? -eq 0 ] then /var/install/bin/show-doc.cui ${color} ${frame} --title "Show certificate request" ${tmpfile} else mecho --error "File '${certdir}/${cname}' has errors" anykey fi else mecho --error "File '${csrdir}/${cname}' doesn't exist or has a file size of 0." anykey fi ;; cert|* ) if [ -s "${certdir}/${cname}" ] then { echo "File name: ${certdir}/${cname}" echo ${openssl_bin} x509 -in "${certdir}/${cname}" -noout -text } > ${tmpfile} if [ $? -eq 0 ] then /var/install/bin/show-doc.cui ${color} ${frame} --title "Show certificate" ${tmpfile} else mecho --error "File '${certdir}/${cname}' has errors" anykey fi else mecho --error "File '${certdir}/${cname}' doesn't exist or has a file size of 0." anykey fi ;; esac rm -f ${tmpfile} } #---------------------------------------------------------------------------------------- # display cert details # $1 - certificate type #---------------------------------------------------------------------------------------- display_cert_details () { dc_type=${1} get_list_of_certs ${dc_type} print_list_of_certs ${dc_type} anykey } #======================================================================================== # Main #======================================================================================== pgmname=`basename $0` # set path names ssldir=/usr/local/ssl certdir=${ssldir}/certs crldir=${ssldir}/crl csrdir=${ssldir}/csr openssl_bin=/usr/bin/openssl certs_title="Show certificate details" certs_tmp_file=/var/tmp/certs-show-tls-certs.$$ color='' frame='' if $(grep -qE "^MENU=['\"]/var/install/bin/show-menu['\"]" /etc/config.d/setup) then color='--nocolor' frame='--noframe' fi # set configuration file export OPENSSL_CONF=${ssldir}/openssl.cnf tmpfile=/tmp/${pgmname}.$$ ask_tmpfile=/tmp/${pgmname}-ask.$$ act_pmode=`get_printmode` # check if screensize handling is available if [ -n "${_EISLIB_SCREENSIZE_Y}" ] then if check_screensize then # # define maxrownum = _EISLIB_SCREENSIZE # - 3 Header Lines # - 1 Footer Lines # ask line maxrownum=`expr ${_EISLIB_SCREENSIZE_Y} - 4` true else mecho --info "Return to calling script" exit 1 fi else # default if screensize handling is not available maxrownum=18 fi case ${1} in showcertchain|-*showcertchain|showcertdates|-*showcertdates|showcertdetails|-*showcertdetails|showcsrdetails|-*showcsrdetails|showcrldetails|-*showcrldetails ) # use command line option cmd=`echo "${1}" | sed 's/^-*//'` ;; * ) # use program name case ${pgmname} in certs-show-tls-certchain ) cmd='showcertchain' ;; certs-show-tls-certdates ) cmd='showcertdates' ;; certs-show-tls-certdetails ) cmd='showcertdetails' ;; certs-show-tls-csrdetails ) cmd='showcsrdetails' ;; certs-show-tls-crldetails ) cmd='showcrldetails' ;; esac ;; esac case ${cmd} in showcertdates ) display_certs_dates > ${tmpfile} 2>&1 /var/install/bin/show-doc.cui ${color} ${frame} --title "Show TLS certificates" ${tmpfile} rm -f ${tmpfile} ;; showcertdetails ) display_cert_details 'cert' ;; showcertchain ) display_cert_details 'chain' ;; showcsrdetails ) display_cert_details 'csr' ;; showcrldetails ) display_cert_details 'crl' ;; * ) clrhome mecho --info "Show TLS certificates" mecho mecho "preparing list ..." # redirect stderr to tmpfile $0 showcertdates mecho anykey ;; esac exit 0 #======================================================================================== # End #========================================================================================