]> git.pld-linux.org Git - packages/openssl.git/blob - openssl-c_rehash.sh
- up to 0.9.8n
[packages/openssl.git] / openssl-c_rehash.sh
1 #!/bin/sh
2 #
3 # Ben Secrest <blsecres@gmail.com>
4 #
5 # sh c_rehash script, scan all files in a directory
6 # and add symbolic links to their hash values.
7 #
8 # based on the c_rehash perl script distributed with openssl
9 #
10 # LICENSE: See OpenSSL license
11 # ^^acceptable?^^
12 #
13
14 # default certificate location
15 DIR=/etc/openssl
16
17 # for filetype bitfield
18 IS_CERT=$(( 1 << 0 ))
19 IS_CRL=$(( 1 << 1 ))
20
21
22 # check to see if a file is a certificate file or a CRL file
23 # arguments:
24 #       1. the filename to be scanned
25 # returns:
26 #       bitfield of file type; uses ${IS_CERT} and ${IS_CRL}
27 #
28 check_file()
29 {
30     local IS_TYPE=0
31
32     # make IFS a newline so we can process grep output line by line
33     local OLDIFS=${IFS}
34     IFS=$( printf "\n" )
35
36     # XXX: could be more efficient to have two 'grep -m' but is -m portable?
37     for LINE in $( grep '^-----BEGIN .*-----' ${1} )
38     do
39         if echo ${LINE} \
40             | grep -q -E '^-----BEGIN (X509 |TRUSTED )?CERTIFICATE-----'
41         then
42             IS_TYPE=$(( ${IS_TYPE} | ${IS_CERT} ))
43
44             if [ $(( ${IS_TYPE} & ${IS_CRL} )) -ne 0 ]
45             then
46                 break
47             fi
48         elif echo ${LINE} | grep -q '^-----BEGIN X509 CRL-----'
49         then
50             IS_TYPE=$(( ${IS_TYPE} | ${IS_CRL} ))
51
52             if [ $(( ${IS_TYPE} & ${IS_CERT} )) -ne 0 ]
53             then
54                 break
55             fi
56         fi
57     done
58
59     # restore IFS
60     IFS=${OLDIFS}
61
62     return ${IS_TYPE}
63 }
64
65
66 #
67 # use openssl to fingerprint a file
68 #    arguments:
69 #       1. the filename to fingerprint
70 #       2. the method to use (x509, crl)
71 #    returns:
72 #       none
73 #    assumptions:
74 #       user will capture output from last stage of pipeline
75 #
76 fingerprint()
77 {
78     ${SSL_CMD} ${2} -fingerprint -noout -in ${1} | sed 's/^.*=//' | tr -d ':'
79 }
80
81
82 #
83 # link_hash - create links to certificate files
84 #    arguments:
85 #       1. the filename to create a link for
86 #       2. the type of certificate being linked (x509, crl)
87 #    returns:
88 #       0 on success, 1 otherwise
89 #
90 link_hash()
91 {
92     local FINGERPRINT=$( fingerprint ${1} ${2} )
93     local HASH=$( ${SSL_CMD} ${2} -hash -noout -in ${1} )
94     local SUFFIX=0
95     local LINKFILE=''
96     local TAG=''
97
98     if [ ${2} = "crl" ]
99     then
100         TAG='r'
101     fi
102
103     LINKFILE=${HASH}.${TAG}${SUFFIX}
104
105     while [ -f ${LINKFILE} ]
106     do
107         if [ ${FINGERPRINT} = $( fingerprint ${LINKFILE} ${2} ) ]
108         then
109             printf "WARNING: Skipping duplicate file ${1}\n" >&2
110             return 1
111         fi      
112
113         SUFFIX=$(( ${SUFFIX} + 1 ))
114         LINKFILE=${HASH}.${TAG}${SUFFIX}
115     done
116
117     printf "${1} => ${LINKFILE}\n"
118
119     # assume any system with a POSIX shell will either support symlinks or
120     # do something to handle this gracefully
121     ln -s ${1} ${LINKFILE}
122
123     return 0
124 }
125
126
127 # hash_dir create hash links in a given directory
128 hash_dir()
129 {
130     printf "Doing ${1}\n"
131
132     cd ${1}
133
134     for FILE in *
135     do
136         # no files in directory at all, no point in continuing
137         if ! [ -f ${FILE} ]
138         then
139             return 1
140         fi
141
142         if echo ${FILE} | grep -q -E '^[[:xdigit:]]{8}\.r?[[:digit:]]+$' \
143                 && [ -h "${FILE}" ]
144         then
145             rm ${FILE}
146         fi
147     done
148
149     for FILE in *.pem
150     do
151         # no pem files so FILE gets set to the unexpanded *.pem
152         if ! [ -f ${FILE} ]
153         then
154             break
155         fi
156
157         check_file ${FILE}
158         local FILE_TYPE=${?}
159         local TYPE_STR=''
160
161         if [ $(( ${FILE_TYPE} & ${IS_CERT} )) -ne 0 ]
162         then
163             TYPE_STR='x509'
164         elif [ $(( ${FILE_TYPE} & ${IS_CRL} )) -ne 0 ]
165         then
166             TYPE_STR='crl'
167         else
168             printf "WARNING: ${FILE} does not contain a certificate or CRL: skipping\n" >&2
169             continue
170         fi
171
172         link_hash ${FILE} ${TYPE_STR}
173     done
174 }
175
176
177 # choose the name of an ssl application
178 if [ -n "${OPENSSL}" ]
179 then
180     SSL_CMD=${OPENSSL}
181 else
182     SSL_CMD=openssl
183     OPENSSL=${SSL_CMD}
184     export ${OPENSSL}
185 fi
186
187 # fix paths
188 PATH=${PATH}:${DIR}/bin
189 export PATH
190
191 # confirm existance/executability of ssl command
192 if ! [ -x $( which ${SSL_CMD} ) ]
193 then
194     printf "${0}: rehashing skipped ('openssl' program not available)\n" >&2
195     exit 0
196 fi
197
198 # determine which directories to process
199 old_IFS=$IFS
200 if [ ${#} -gt 0 ]
201 then
202     IFS=':'
203     DIRLIST=${*}
204 elif [ -n "${SSL_CERT_DIR}" ]
205 then
206     DIRLIST=$SSL_CERT_DIR
207 else
208     DIRLIST=${DIR}/certs
209 fi
210
211 IFS=':'
212
213 # process directories
214 for CERT_DIR in ${DIRLIST}
215 do
216     if [ -d ${CERT_DIR} -a -w ${CERT_DIR} ]
217     then
218         IFS=$old_IFS
219         hash_dir ${CERT_DIR}
220         IFS=':'
221     fi
222 done
This page took 0.036943 seconds and 3 git commands to generate.