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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3283 - (show annotations) (download) (as text)
Tue May 12 11:55:53 2020 UTC (2 years ago) by davidg
File MIME type: application/x-shellscript
File size: 11993 byte(s)
Add initial version of the TCSG4 convertion tools for PKCS12 and PKCS7

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 #
13 #
14 destdir=${HOME}/.globus
15 DATE=`date +%Y%m%d-%H%M%S`
16 progname=`basename "$0"`
17 bckprefix=backup
18 makecsr=0
19 nameformat=
20 certfn=
21
22 # ############################################################################
23 # usage help and instructions
24 #
25 help() { cat <<EOF
26 Usage: tcsg4-install-credential.sh [-d destdir] [-p passfile] [-r|-R] [-f]
27 [-n name] [-b backupprefix] <PKCS12.p12>
28
29 -d destdir write result files to <destdir>
30 if <destdir> contains "globus", also make the
31 symlinks userkey.pem and usercert.pem for GCT tools
32 -p passfile file with the password to use (same for input
33 and for output PKCS#12 and private keys)
34 -r use EEC commonName as basis for new filenames
35 -R use EEC commonName and date as basis for filenames
36 -f do not make backups of existing files
37 -n name set friendly name of the credential in corrected
38 PKCS#12 (.p12) file produced. If unset, is taken
39 from the commonName of the EEC and issuance date
40 -b bckprefix prefix of the filename to use when making backups
41 --csr generate a CSR request file for future use in destdir
42
43 <PKCS12.p12> filename of the blob produced by Sectigo
44
45 Notice: do NOT import the blob from Sectigo directly into
46 anything, since it will corrupt your key chain. Always use
47 the "package-<name>.p12" file created by this script
48
49 EOF
50 return;
51 }
52
53 # ############################################################################
54 #
55 while [ $# -gt 0 ]; do
56 case "$1" in
57 -r | --rename ) nameformat="friendly"; shift 1 ;;
58 -R | --rename-with-date ) nameformat="dated"; shift 1 ;;
59 --csr ) makecsr=1; shift 1 ;;
60 -f | --force ) bckprefix=""; shift 1 ;;
61 -h | --help ) help ; exit 0 ;;
62 -b | --backupprefix ) bckprefix="$2"; shift 2 ;;
63 -n | --name ) friendlyname="$2"; shift 2 ;;
64 -d | --destination ) destdir="$2"; shift 2 ;;
65 -p | --passfile ) passfile="$2" ; shift 2 ;;
66 -* ) echo "Unknown option $1, exiting" >&2 ; exit 1 ;;
67 * ) break ;;
68 esac
69 done
70
71 case $# in
72 0 ) help ; exit 0 ;;
73 1 ) pkfile="$1"; break ;;
74 * ) echo "Too many arguments." >&2 ; exit 1 ;;
75 esac
76
77 # ############################################################################
78 # input validation
79 #
80 if [ ! -r "$pkfile" ]; then echo "Cannot read $pkfile" >&2; exit 1; fi
81
82 case "$pkfile" in
83 *.p12 ) credbase=`basename "$pkfile" .p12` ;;
84 *.pfx ) credbase=`basename "$pkfile" .pfx` ;;
85 * ) echo "Unlikely PKCS#12 file: $pkfile" >&2 ; exit 2 ;;
86 esac
87
88 # ############################################################################
89 # obtain password from somewhere
90 #
91 if [ -n "$passfile" ]; then
92 if [ ! -r "$passfile" ]; then
93 echo "Error: cannot read password from $passfile" >&2 ; exit 1
94 fi
95 PW=`head -1 "$passfile"`
96 else
97 while [ x"$PW" = x"" ]; do
98 echo -ne "Passphrase (existing) for your secret key: "
99 stty -echo ; read PW ; stty echo
100 echo ""
101 done
102 fi
103 if [ -z "$PW" ]; then echo "Empty password is not allowed" >&2; exit 2; fi
104 export PW
105
106 # ############################################################################
107 # extraction of Sectigo blob of crap
108 #
109 tempdir=`mktemp -d tcsg4unpack.XXXXXX`
110
111 if [ ! -d "$tempdir" ]; then
112 echo "Error creating temporary working directory here" >&2
113 exit 1
114 fi
115
116 openssl pkcs12 -nomacver -password env:PW -in "$pkfile" \
117 -passout env:PW -out "$tempdir/crap-$credbase.pem"
118
119 if [ $? -ne 0 ]; then
120 echo "Error: cannot extract data from PKCS12 file $pkfile" >&2
121 echo " PASSPHRASE INCORRECT?" >&2
122 exit 3
123 fi
124
125 if [ ! -s "$tempdir/crap-$credbase.pem" ]; then
126 echo "Error: cannot extract data from PKCS12 file $pkfile" >&2
127 echo " resulting direct-rendered crap file not found" >&2
128 exit 4
129 fi
130
131 if [ `grep -c PRIVATE "$tempdir/crap-$credbase.pem"` -eq 0 ]; then
132 echo "Error: cannot extract data from PKCS12 file $pkfile" >&2
133 echo " resulting crap file has no key material" >&2
134 exit 4
135 fi
136
137 if [ `grep -c CERTIFICATE "$tempdir/crap-$credbase.pem"` -eq 0 ]; then
138 echo "Error: cannot extract data from PKCS12 file $pkfile" >&2
139 echo " resulting crap file has no certificate material" >&2
140 exit 4
141 fi
142
143 # extract
144 awk '
145 BEGIN { icert = 0; }
146 /^-----BEGIN ENCRYPTED PRIVATE KEY-----$/ {
147 print $0 > "'$tempdir/key-$credbase.pem'";
148 do {
149 getline ln;
150 print ln > "'$tempdir/key-$credbase.pem'";
151 } while ( ln != "-----END ENCRYPTED PRIVATE KEY-----" );
152 }
153 /^-----BEGIN CERTIFICATE-----$/ {
154 icert++;
155 print $0 > "'$tempdir/cert-'"icert"'-$credbase.pem'";
156 do {
157 getline ln;
158 print ln > "'$tempdir/cert-'"icert"'-$credbase.pem'";
159 } while ( ln != "-----END CERTIFICATE-----" );
160 }
161 ' "$tempdir/crap-$credbase.pem"
162
163 # ############################################################################
164 # generate per-certificate and key output files
165 #
166 [ -d "$destdir" ] || mkdir -p "$destdir"
167
168 havewrittenchain=0
169 for i in "$tempdir"/cert-*-"$credbase".pem
170 do
171 certcn=`openssl x509 -noout -subject -nameopt oneline,sep_comma_plus \
172 -in "$i" | \
173 sed -e 's/.*CN = \([a-zA-Z0-9\._][- a-zA-Z0-9:\._@]*\).*/\1/'`
174 issuercn=`openssl x509 -noout -issuer -nameopt oneline,sep_comma_plus \
175 -in "$i" | \
176 sed -e 's/.*CN = \([a-zA-Z0-9\._][- a-zA-Z0-9:\._@]*\).*/\1/'`
177
178 certdate=`openssl x509 -noout -text -in "$i" | \
179 awk '/ Not Before:/ { print $4,$3,$6; }'`
180 certisca=`openssl x509 -noout -text -in "$i" | \
181 awk 'BEGIN { ca=0; }
182 /CA:FALSE/ { ca=0; } /CA:TRUE/ { ca=1; }
183 END {print ca;}'`
184
185 if [ "$certcn" = "$issuercn" -o "$issuercn" = "AddTrust External CA Root" ]
186 then
187 continue
188 fi
189
190 if [ $certisca -eq 0 ]; then
191 certfn=`echo "$certcn" | sed -e 's/[^-a-zA-Z0-9_]/_/g'`
192 certfndated=`echo "$certcn issued $certdate" | \
193 sed -e 's/[^-a-zA-Z0-9_]/_/g'`
194 echo "Processing EEC certificate: $certcn"
195 friendlyname="${friendlyname:-$certcn issued $certdate}"
196 echo " (friendly name: $friendlyname)"
197 fi
198
199 if [ $certisca -eq 1 ]; then
200 echo "Processing CA certificate: $certcn"
201 if [ $havewrittenchain -eq 0 ]; then
202 if [ -f "$destdir/chain-$credbase.pem" -a -n "$bckprefix" ]; then
203 mv "$destdir/chain-$credbase.pem" \
204 "$destdir/$bckprefix.$DATE.chain-$credbase.pem"
205 fi
206 havewrittenchain=1
207 echo "" > "$destdir/chain-$credbase.pem"
208 fi
209 cat $i >> "$destdir/chain-$credbase.pem"
210 fi
211
212 if [ $certisca -eq 0 ]; then
213 if [ -n "$pkcs12eec" ]; then
214 echo "Error: there are multiple EEC certificates in the blob" >&2
215 echo " this script cannot handle this case, sorry!" >&2
216 exit 2
217 fi
218 pkcs12eec="$i"
219 if [ -f "$destdir/cert-$credbase.pem" ]; then
220 mv "$destdir/cert-$credbase.pem" "$destdir/$bckprefix.$DATE.cert-$credbase.pem"
221 fi
222 cat $i > "$destdir/cert-$credbase.pem"
223 fi
224
225 done
226
227 echo "Processing EEC secret key"
228 if [ ! -s "$tempdir/key-$credbase.pem" ]; then
229 echo "Error: cannot find secret key file which should have been there" >&2
230 echo " internal error in AWK section (P1)" >&2
231 exit 5
232 fi
233 if [ `grep -c PRIVATE "$tempdir/key-$credbase.pem"` -eq 0 ]; then
234 echo "Error: cannot find key in keyfile which should have been there" >&2
235 echo " internal error in AWK section (P2)" >&2
236 exit 5
237 fi
238
239 if [ -f "$destdir/key-$credbase.pem" -a -n "$bckprefix" ]; then
240 mv "$destdir/key-$credbase.pem" "$destdir/$bckprefix.$DATE.key-$credbase.pem"
241 fi
242 cat "$tempdir/key-$credbase.pem" > "$destdir/key-$credbase.pem"
243
244 # not all filesystems support perms, so ignore errors
245 chmod go-rwx "$destdir/key-$credbase.pem" 2>/dev/null
246 chmod go-rwx "$destdir/cert-$credbase.pem" 2>/dev/null
247
248 echo "Repackaging $friendlyname as PKCS12"
249 if [ -f "$destdir/package-$credbase.p12" -a -n "$bckprefix" ]; then
250 mv "$destdir/package-$credbase.p12" \
251 "$destdir/$bckprefix.$DATE.package-$credbase.p12"
252 fi
253 openssl pkcs12 -export \
254 -passin env:PW -inkey "$tempdir/key-$credbase.pem" \
255 -certfile "$destdir/chain-$credbase.pem" \
256 -name "$friendlyname" -in "$pkcs12eec" \
257 -passout env:PW -out "$destdir/package-$credbase.p12"
258
259 if [ $? -ne 0 ]; then
260 echo "Error: something went wrong creating the normalised package" >&2
261 echo " non-zero return code from openssl in PKCS12 export (X1)" >&2
262 exit 5
263 fi
264 if [ ! -s "$destdir/package-$credbase.p12" ]; then
265 echo "Error: something went wrong creating the normalised package" >&2
266 echo " internal error in PKCS12 export (X2)" >&2
267 exit 5
268 fi
269
270 # not all filesystems support perms, so ignore errors
271 chmod go-rwx "$destdir/package-$credbase.p12" 2>/dev/null
272
273 # ############################################################################
274 # cleanup intermate files and name output properly
275 #
276 rm "$tempdir"/cert-*-$credbase.pem
277 rm "$tempdir"/crap-$credbase.pem
278 rm "$tempdir"/key-$credbase.pem
279 rmdir "$tempdir"
280 if [ $? -ne 0 ]; then
281 echo "Error: cannot remove working directory $tempdir" >&2
282 echo " internal inconsistency or prior error encountered" >&2
283 fi
284
285 # rename, if so required
286 if [ -n "$nameformat" ]; then
287 if [ "$nameformat" = "friendly" ]; then
288 certfn="${certfn:-$credbase}"
289 elif [ "$nameformat" = "dated" ]; then
290 certfn="${certfndated:-$credbase}"
291 else
292 echo "Unknown filename format, error" >&2
293 exit 2
294 fi
295 mv "$destdir/cert-$credbase.pem" "$destdir/cert-$certfn.pem"
296 mv "$destdir/chain-$credbase.pem" "$destdir/chain-$certfn.pem"
297 mv "$destdir/key-$credbase.pem" "$destdir/key-$certfn.pem"
298 mv "$destdir/package-$credbase.p12" "$destdir/package-$certfn.p12"
299 else
300 certfn="$credbase"
301 fi
302
303 # make CSR for future use if requested
304 if [ "$makecsr" -ne 0 ]; then
305 echo "Generating CSR file for future use and renewal"
306 if [ -f "$destdir/request-$credbase.pem" -a -n "$bckprefix" ]; then
307 mv "$destdir/request-$credbase.pem" \
308 "$destdir/$bckprefix.$DATE.request-$credbase.pem"
309 fi
310
311 certsubject=/`openssl x509 -noout -subject -nameopt oneline,sep_comma_plus \
312 -in "$destdir/cert-$certfn.pem" | \
313 sed -e 's/^subject= *//;s/,/\//g;s/ = /=/g'`
314
315 echo " subject: $certsubject"
316
317 openssl req -new \
318 -key "$destdir/key-$certfn.pem" -passin env:PW \
319 -subj "$certsubject" \
320 -out "$destdir/request-$certfn.pem"
321 fi
322
323 # ############################################################################
324 # inform user of result and of globus compatibility
325 #
326 echo "The following files have been created for you:"
327 echo -ne " " ; ls -l1a "$destdir/cert-$certfn.pem"
328 echo -ne " " ; ls -l1a "$destdir/chain-$certfn.pem"
329 [ -f "$destdir/request-$certfn.pem" ] && \
330 ( echo -ne " " ; ls -l1a "$destdir/request-$certfn.pem" )
331 echo -ne " " ; ls -l1a "$destdir/key-$certfn.pem"
332 echo -ne " " ; ls -l1a "$destdir/package-$certfn.p12"
333
334 # globus-ify pertinent dest directories
335 case "$destdir" in
336 *globus* )
337 echo "Making Grid Community Toolkit compatible link in $destdir"
338 if [ -f "$destdir/userkey.pem" -a -n "$bckprefix" ]; then
339 echo " backing up userkey.pem to ""$bckprefix.$DATE.userkey.pem"
340 mv "$destdir/userkey.pem" "$destdir/$bckprefix.$DATE.userkey.pem"
341 fi
342 echo " userkey.pem"
343 ln -sfnT "key-$certfn.pem" "$destdir/userkey.pem"
344 if [ -f "$destdir/usercert.pem" -a -n "$bckprefix" ]; then
345 echo " backing up usercert.pem to $bckprefix.$DATE.usercert.pem"
346 mv "$destdir/usercert.pem" "$destdir/$bckprefix.$DATE.usercert.pem"
347 fi
348 echo " usercert.pem"
349 ln -sfnT "cert-$certfn.pem" "$destdir/usercert.pem"
350 ;;
351 esac
352
353 #
354 #
355 # ############################################################################

Properties

Name Value
svn:executable *

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