/[pdpsoft]/nl.nikhef.pdp.tcs/nl.nikhef.pdp.tcs.tcsg4-tools/trunk/tcsg4-install-servercert.sh
ViewVC logotype

Contents of /nl.nikhef.pdp.tcs/nl.nikhef.pdp.tcs.tcsg4-tools/trunk/tcsg4-install-servercert.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3330 - (show annotations) (download) (as text)
Mon Jul 5 08:35:52 2021 UTC (4 months, 3 weeks ago) by davidg
File MIME type: application/x-shellscript
File size: 10537 byte(s)
Create a PKCS#12 bundle for server certs - consolidated wildcard fixes

1 #! /bin/sh
2 #
3 # @(#)$Id$
4 # rev 2
5 #
6 # TCS G4 client certificate format management tool for POSIX systems
7 # including installation to Grid Community Toolkit (formerly Globus)
8 # user credential directory formats
9 #
10 # Requirements: sh, awk, sed, openssl, date, mktemp, ls,
11 # mkdir, rmdir, mv, basename, grep, chmod
12 # in addition requires curl if you use URLs for the PKCS#7 input
13 #
14 # Copyright 2020 David Groep, Nikhef, Amsterdam
15 #
16 # Licensed under the Apache License, Version 2.0 (the "License");
17 # you may not use this file except in compliance with the License.
18 # You may obtain a copy of the License at
19 #
20 # http://www.apache.org/licenses/LICENSE-2.0
21 #
22 # Unless required by applicable law or agreed to in writing, software
23 # distributed under the License is distributed on an "AS IS" BASIS,
24 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 # See the License for the specific language governing permissions and
26 # limitations under the License.
27 #
28 #
29 destdir=.
30 DATE=`date +%Y%m%d-%H%M%S`
31 progname=`basename "$0"`
32 bckprefix=backup
33 makecsr=0
34 nameformat=friendly
35 certfn=
36 profile=""
37 customer=surfnet
38
39 # ############################################################################
40 # usage help and instructions
41 #
42 help() { cat <<EOF
43 Usage: tcsg4-install-servercert.sh [-d destdir] [-r|-R] [-f]
44 [-b backupprefix] <PKCS7.p7b>
45
46 -d destdir write result files to <destdir>
47 -r use EEC commonName as basis for new filenames
48 --no-rename use the base filename of the P7B file for new filenames
49 -R use EEC commonName and date as basis for filenames
50 -f do not make backups of existing files
51 -b bckprefix prefix of the filename to use when making backups
52 -C customer name of the Sectigo customer (default: surfnet)
53
54 <PKCS7.p7b> filename of the blob produced by Sectigo
55 or URL to the PKCS#7 blob from the success email
56 (https://cer.../ssl?action=download&sslId=1234567&format=bin)
57 remember to "quote" the URL to preserve the ampersands
58 or Self-Enrollment ID number (numeric)
59
60 EOF
61 return;
62 }
63
64 # ############################################################################
65 #
66 while [ $# -gt 0 ]; do
67 case "$1" in
68 -r | --rename ) nameformat="friendly"; shift 1 ;;
69 -x | --no-rename ) nameformat=""; shift 1 ;;
70 -R | --rename-with-date ) nameformat="dated"; shift 1 ;;
71 -f | --force ) bckprefix=""; shift 1 ;;
72 -h | --help ) help ; exit 0 ;;
73 -b | --backupprefix ) bckprefix="$2"; shift 2 ;;
74 -C | --customer ) customer="$2"; shift 2 ;;
75 -d | --destination ) destdir="$2"; shift 2 ;;
76 -* ) echo "Unknown option $1, exiting" >&2 ; exit 1 ;;
77 * ) break ;;
78 esac
79 done
80
81 case $# in
82 0 ) help ; exit 0 ;;
83 1 ) pkfile="$1"; break ;;
84 * ) echo "Too many arguments." >&2 ; exit 1 ;;
85 esac
86
87 # ############################################################################
88 # retrieve PKCS#7 from URL, if URL given (beware of quoting the ampersand)
89 # or from order number
90 #
91 [ "$pkfile" -gt 0 ] > /dev/null 2>&1
92 if [ $? -eq 0 ]; then
93 # this was a pure number, so an order ID
94 echo "Recognised order ID $pkfile, downloading"
95 pkfile="https://cert-manager.com/customer/${customer}/ssl?action=download&sslId=${pkfile}&format=bin"
96 fi
97
98 case "$pkfile" in
99 https://*format=bin | https://*format=base64 )
100 sslid=`echo "$pkfile"|sed -e's/.*sslId=\([0-9]*\).*/\1/'`
101 [ "$sslid" -gt 0 ] >/dev/null 2>&1
102 if [ $? -ne 0 ]; then
103 echo "URL provided is not a Sectigo SSL PKCS#7 enrollment result" >&2
104 exit 1
105 fi
106 curl -s -o "sectigo-order-$sslid.p7b" "$pkfile"
107 if [ $? -ne 0 ]; then
108 echo "URL cannot be downloaded ($pkfile)" >&2
109 exit 1
110 fi
111 case "$pkfile" in
112 *format=base64 )
113 mv "sectigo-order-$sslid.p7b" "sectigo-order-$sslid.p7b.pem"
114 openssl pkcs7 \
115 -inform pem -in "sectigo-order-$sslid.p7b.pem" \
116 -outform der -out "sectigo-order-$sslid.p7b"
117 ;;
118 esac
119 if [ ! -s "sectigo-order-$sslid.p7b" ]; then
120 echo "URL download result empty in sectigo-order-$sslid.p7b " >&2
121 echo " (source $pkfile)" >&2
122 exit 1
123 fi
124 pkfile="sectigo-order-$sslid.p7b"
125 ;;
126 esac
127
128
129 # ############################################################################
130 # input validation
131 #
132 if [ ! -r "$pkfile" ]; then echo "Cannot read $pkfile" >&2; exit 1; fi
133
134 case "$pkfile" in
135 *.p7b ) credbase=`basename "$pkfile" .p7b` ;;
136 * ) echo "Unlikely PKCS#12 file: $pkfile" >&2 ; exit 2 ;;
137 esac
138
139 # ############################################################################
140 # extraction of Sectigo blob of p7b
141 #
142 tempdir=`mktemp -d tcsg4unpack.XXXXXX`
143
144 if [ ! -d "$tempdir" ]; then
145 echo "Error creating temporary working directory here" >&2
146 exit 1
147 fi
148
149 openssl pkcs7 -inform der -in "$pkfile" -print_certs \
150 -out "$tempdir/p7b-$credbase.pem"
151
152 if [ $? -ne 0 ]; then
153 echo "Error: cannot extract data from PKCS7 file $pkfile" >&2
154 echo " PASSPHRASE INCORRECT?" >&2
155 exit 3
156 fi
157
158 if [ ! -s "$tempdir/p7b-$credbase.pem" ]; then
159 echo "Error: cannot extract data from PKCS7 file $pkfile" >&2
160 echo " resulting direct-rendered p7b file not found" >&2
161 exit 4
162 fi
163
164 if [ `grep -c CERTIFICATE "$tempdir/p7b-$credbase.pem"` -eq 0 ]; then
165 echo "Error: cannot extract data from PKCS7 file $pkfile" >&2
166 echo " resulting p7b file has no certificate material" >&2
167 exit 4
168 fi
169
170 # extract
171 awk '
172 BEGIN { icert = 0; }
173 /^-----BEGIN CERTIFICATE-----$/ {
174 icert++;
175 print $0 > "'$tempdir/cert-'"icert"'-$credbase.pem'";
176 do {
177 getline ln;
178 print ln > "'$tempdir/cert-'"icert"'-$credbase.pem'";
179 } while ( ln != "-----END CERTIFICATE-----" );
180 }
181 ' "$tempdir/p7b-$credbase.pem"
182
183 # ############################################################################
184 # generate per-certificate and key output files
185 #
186 [ -d "$destdir" ] || mkdir -p "$destdir"
187
188 havewrittenchain=0
189 for i in "$tempdir"/cert-*-"$credbase".pem
190 do
191 certcn=`openssl x509 -noout -subject -nameopt oneline,sep_comma_plus \
192 -in "$i" | \
193 sed -e 's/.*CN = \([a-zA-Z0-9\._\*][- a-zA-Z0-9:\*\._@]*\).*/\1/'`
194 issuercn=`openssl x509 -noout -issuer -nameopt oneline,sep_comma_plus \
195 -in "$i" | \
196 sed -e 's/.*CN = \([a-zA-Z0-9\._][- a-zA-Z0-9:\._@]*\).*/\1/'`
197
198 certdate=`openssl x509 -noout -text -in "$i" | \
199 awk '/ Not Before:/ { print $4,$3,$6; }'`
200 certisca=`openssl x509 -noout -text -in "$i" | \
201 awk 'BEGIN { ca=0; }
202 /CA:FALSE/ { ca=0; } /CA:TRUE/ { ca=1; }
203 END {print ca;}'`
204
205 if [ "$certcn" = "$issuercn" -o "$issuercn" = "AddTrust External CA Root" ]
206 then
207 continue
208 fi
209
210 # these CAs as intermediate subjects are known useless
211 case "$certcn" in
212 "AAA Certificate Services" ) continue ;;
213 "USERTrust RSA Certification Authority" ) continue ;;
214 * ) ;;
215 esac
216
217 if [ $certisca -eq 0 ]; then
218 certfn=`echo "$certcn" | sed -e 's/\*/WILDCARD/g;s/[^-a-zA-Z0-9_\.]/_/g'`
219 certfndated=`echo "$certcn issued $certdate" | \
220 sed -e 's/[^-a-zA-Z0-9_]/_/g'`
221 echo "Processing EEC certificate: $certcn"
222 friendlyname="${friendlyname:-$certcn issued $certdate}"
223 echo " (friendly name: $friendlyname)"
224 fi
225
226 if [ $certisca -eq 1 ]; then
227 echo "Processing CA certificate: $certcn"
228 if [ $havewrittenchain -eq 0 ]; then
229 if [ -f "$destdir/chain-$credbase.pem" -a -n "$bckprefix" ]; then
230 mv "$destdir/chain-$credbase.pem" \
231 "$destdir/$bckprefix.$DATE.chain-$credbase.pem"
232 fi
233 havewrittenchain=1
234 echo -ne "" > "$destdir/chain-$credbase.pem"
235 fi
236 cat $i >> "$destdir/chain-$credbase.pem"
237 fi
238
239 if [ $certisca -eq 0 ]; then
240 if [ -f "$destdir/cert-$credbase.pem" ]; then
241 mv "$destdir/cert-$credbase.pem" "$destdir/$bckprefix.$DATE.cert-$credbase.pem"
242 fi
243 cat $i > "$destdir/cert-$credbase.pem"
244
245 case "$issuercn" in
246 GEANT\ OV\ *) profile="ov" ;;
247 GEANT\ EV\ *) profile="ev" ;;
248 GEANT\ eScience\ *) profile="igtfov" ;;
249 * ) profile="" ;;
250 esac
251 fi
252
253 done
254
255 # ############################################################################
256 # cleanup intermate files and name output properly
257 #
258 rm "$tempdir"/cert-*-$credbase.pem
259 rm "$tempdir"/p7b-$credbase.pem
260 rmdir "$tempdir"
261 if [ $? -ne 0 ]; then
262 echo "Error: cannot remove working directory $tempdir" >&2
263 echo " internal inconsistency or prior error encountered" >&2
264 fi
265
266 # rename, if so required
267 if [ -n "$nameformat" ]; then
268 if [ "$nameformat" = "friendly" ]; then
269 certfn="${certfn:-$credbase}"
270 elif [ "$nameformat" = "dated" ]; then
271 certfn="${certfndated:-$credbase}"
272 else
273 echo "Unknown filename format, error" >&2
274 exit 2
275 fi
276 mv "$destdir/cert-$credbase.pem" "$destdir/cert-$certfn.pem"
277 mv "$destdir/chain-$credbase.pem" "$destdir/chain-$certfn.pem"
278 else
279 certfn="$credbase"
280 fi
281
282 # ############################################################################
283 # create the nginx compatible single file: cert+chain concatenated
284 #
285 cat "$destdir/cert-$certfn.pem" "$destdir/chain-$certfn.pem" \
286 > "$destdir/nginx-$certfn.pem"
287
288 # ############################################################################
289 # create a PKCS#12 (p12/pfx) bundle for ISS/MS and appliances
290 #
291 openssl pkcs12 -export -nodes \
292 -inkey key-$certfn.pem -in cert-$certfn.pem \
293 -name "SSL $profile certificate $certfn" \
294 -certfile chain-$certfn.pem \
295 -passout pass: \
296 -out bundle-$certfn.p12
297 chmod 0600 bundle-$certfn.p12
298
299 # ############################################################################
300 # make per-profile copies in case of key re-use for same host new profile
301 #
302 if [ "$profile" != "" ]; then
303 [ -f "$destdir/cert-$certfn.pem" ] && cp -p "$destdir/cert-$certfn.pem" "$destdir/$profile-cert-$certfn.pem"
304 [ -f "$destdir/chain-$certfn.pem" ] && cp -p "$destdir/chain-$certfn.pem" "$destdir/$profile-chain-$certfn.pem"
305 [ -f "$destdir/nginx-$certfn.pem" ] && cp -p "$destdir/nginx-$certfn.pem" "$destdir/$profile-nginx-$certfn.pem"
306 fi
307
308 # ############################################################################
309 # inform user of result and of globus compatibility
310 #
311 echo "The following files have been created for you:"
312 echo -ne " " ; ls -l1a "$destdir/cert-$certfn.pem"
313 echo -ne " " ; ls -l1a "$destdir/chain-$certfn.pem"
314
315 #
316 #
317 # ############################################################################

Properties

Name Value
svn:executable *

grid.support@nikhef.nl
ViewVC Help
Powered by ViewVC 1.1.28