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

Annotation 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 - (hide 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 davidg 3283 #! /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