SOURCES: openssl-c_rehash.sh (NEW) - shell version of c_rehash perl script ...

baggins baggins at pld-linux.org
Mon Nov 3 13:49:57 CET 2008


Author: baggins                      Date: Mon Nov  3 12:49:57 2008 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- shell version of c_rehash perl script (Author: Ben Secrest <blsecres at gmail.com>)

---- Files affected:
SOURCES:
   openssl-c_rehash.sh (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/openssl-c_rehash.sh
diff -u /dev/null SOURCES/openssl-c_rehash.sh:1.1
--- /dev/null	Mon Nov  3 13:49:57 2008
+++ SOURCES/openssl-c_rehash.sh	Mon Nov  3 13:49:51 2008
@@ -0,0 +1,218 @@
+#!/bin/sh
+#
+# Ben Secrest <blsecres at gmail.com>
+#
+# sh c_rehash script, scan all files in a directory
+# and add symbolic links to their hash values.
+#
+# based on the c_rehash perl script distributed with openssl
+#
+# LICENSE: See OpenSSL license
+# ^^acceptable?^^
+#
+
+# default certificate location
+DIR=/etc/openssl
+
+# for filetype bitfield
+IS_CERT=$(( 1 << 0 ))
+IS_CRL=$(( 1 << 1 ))
+
+
+# check to see if a file is a certificate file or a CRL file
+# arguments:
+#       1. the filename to be scanned
+# returns:
+#       bitfield of file type; uses ${IS_CERT} and ${IS_CRL}
+#
+check_file()
+{
+    local IS_TYPE=0
+
+    # make IFS a newline so we can process grep output line by line
+    local OLDIFS=${IFS}
+    IFS=$( printf "\n" )
+
+    # XXX: could be more efficient to have two 'grep -m' but is -m portable?
+    for LINE in $( grep '^-----BEGIN .*-----' ${1} )
+    do
+	if echo ${LINE} \
+	    | grep -q -E '^-----BEGIN (X509 |TRUSTED )?CERTIFICATE-----'
+	then
+	    IS_TYPE=$(( ${IS_TYPE} | ${IS_CERT} ))
+
+	    if [ $(( ${IS_TYPE} & ${IS_CRL} )) -ne 0 ]
+	    then
+	    	break
+	    fi
+	elif echo ${LINE} | grep -q '^-----BEGIN X509 CRL-----'
+	then
+	    IS_TYPE=$(( ${IS_TYPE} | ${IS_CRL} ))
+
+	    if [ $(( ${IS_TYPE} & ${IS_CERT} )) -ne 0 ]
+	    then
+	    	break
+	    fi
+	fi
+    done
+
+    # restore IFS
+    IFS=${OLDIFS}
+
+    return ${IS_TYPE}
+}
+
+
+#
+# use openssl to fingerprint a file
+#    arguments:
+#	1. the filename to fingerprint
+#	2. the method to use (x509, crl)
+#    returns:
+#	none
+#    assumptions:
+#	user will capture output from last stage of pipeline
+#
+fingerprint()
+{
+    ${SSL_CMD} ${2} -fingerprint -noout -in ${1} | sed 's/^.*=//' | tr -d ':'
+}
+
+
+#
+# link_hash - create links to certificate files
+#    arguments:
+#       1. the filename to create a link for
+#	2. the type of certificate being linked (x509, crl)
+#    returns:
+#	0 on success, 1 otherwise
+#
+link_hash()
+{
+    local FINGERPRINT=$( fingerprint ${1} ${2} )
+    local HASH=$( ${SSL_CMD} ${2} -hash -noout -in ${1} )
+    local SUFFIX=0
+    local LINKFILE=''
+    local TAG=''
+
+    if [ ${2} = "crl" ]
+    then
+    	TAG='r'
+    fi
+
+    LINKFILE=${HASH}.${TAG}${SUFFIX}
+
+    while [ -f ${LINKFILE} ]
+    do
+	if [ ${FINGERPRINT} = $( fingerprint ${LINKFILE} ${2} ) ]
+	then
+	    printf "WARNING: Skipping duplicate file ${1}\n" >&2
+	    return 1
+	fi	
+
+	SUFFIX=$(( ${SUFFIX} + 1 ))
+	LINKFILE=${HASH}.${TAG}${SUFFIX}
+    done
+
+    printf "${1} => ${LINKFILE}\n"
+
+    # assume any system with a POSIX shell will either support symlinks or
+    # do something to handle this gracefully
+    ln -s ${1} ${LINKFILE}
+
+    return 0
+}
+
+
+# hash_dir create hash links in a given directory
+hash_dir()
+{
+    printf "Doing ${1}\n"
+
+    cd ${1}
+
+    for FILE in *
+    do
+	# no files in directory at all, no point in continuing
+	if ! [ -f ${FILE} ]
+	then
+	    return 1
+	fi
+
+        if echo ${FILE} | grep -q -E '^[[:xdigit:]]{8}\.r?[[:digit:]]+$' \
+	    	&& [ -h "${FILE}" ]
+        then
+            rm ${FILE}
+        fi
+    done
+
+    for FILE in *.pem
+    do
+	# no pem files so FILE gets set to the unexpanded *.pem
+	if ! [ -f ${FILE} ]
+	then
+	    break
+	fi
+
+	check_file ${FILE}
+        local FILE_TYPE=${?}
+	local TYPE_STR=''
+
+        if [ $(( ${FILE_TYPE} & ${IS_CERT} )) -ne 0 ]
+        then
+            TYPE_STR='x509'
+        elif [ $(( ${FILE_TYPE} & ${IS_CRL} )) -ne 0 ]
+        then
+            TYPE_STR='crl'
+        else
+            printf "WARNING: ${FILE} does not contain a certificate or CRL: skipping\n" >&2
+	    continue
+        fi
+
+	link_hash ${FILE} ${TYPE_STR}
+    done
+}
+
+
+# choose the name of an ssl application
+if [ -n "${OPENSSL}" ]
+then
+    SSL_CMD=${OPENSSL}
+else
+    SSL_CMD=openssl
+    OPENSSL=${SSL_CMD}
+    export ${OPENSSL}
+fi
+
+# fix paths
+PATH=${PATH}:${DIR}/bin
+export PATH
+
+# confirm existance/executability of ssl command
+if ! [ -x $( which ${SSL_CMD} ) ]
+then
+    printf "${0}: rehashing skipped ('openssl' program not available)\n" >&2
+    exit 0
+fi
+
+# determine which directories to process
+# XXX: can't handle directories with spaces in names
+# XXX: ...use \n as dir separator and manipulate IFS?
+if [ ${#} -gt 0 ]
+then
+    DIRLIST=${*}
+elif [ -n "${SSL_CERT_DIR}" ]
+then
+    DIRLIST=$( echo ${SSL_CERT_DIR} | tr ':' ' ' )
+else
+    DIRLIST=${DIR}/certs
+fi
+
+# process directories
+for CERT_DIR in ${DIRLIST}
+do
+    if [ -d ${CERT_DIR} -a -w ${CERT_DIR} ]
+    then
+        hash_dir ${CERT_DIR}
+    fi
+done
================================================================


More information about the pld-cvs-commit mailing list