-
Notifications
You must be signed in to change notification settings - Fork 7
/
certutil
executable file
·263 lines (243 loc) · 5.36 KB
/
certutil
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#!/bin/sh
#ident $Id$
#
# certutil -- manage trusted X.509 certificates
# inspired by Netscape PKCS #11 toolkit
# contributed by Jarkko Turkulainen <jt@wapit.com>
#
#
# INTRODUCTION
#
# certutil can be used with various OpenSSL routines and tools
# that utilize OpenSSL. Example:
#
# $ openssl s_client -CApath certdir
#
# where certdir is a directory created by certutil. Other well known
# programs that use the same format are stunnel, sendmail and pam_ldap
#
#
#
# HOWTO
#
# 1. Initialize certificate database
#
# Simply by adding a new certificate. If the certificate directory
# doesn't exist, the script asks for creating a one. Example:
#
# $ certutil -a -n "First Cert" -i cert.pem -d /home/jt/mycerts
# ./certutil: cannot access /home/jt/mycerts, create? [y/N] y
#
#
# 2. Add new certificate
#
# $ certutil -a -n "My Cert" -i cert.pem [-d certdir]
#
# Note that nickname (-n) must exist. certdir is optional - if it's
# not given, $PWD is used. The directory must have a file named certs.dat.
# If that file doesn't exist, the script refuses to do anything. If your
# certs.dat file is corrupted, "rm -rf" the whole dir and start from
# the scratch. cert.pem is the actual sertificate.
#
# 3. Delete certificate
#
# $ certutil -r -n "My Cert" [-d certdir]
#
# This command removes the certificate named "My Cert". certdir is
# optional, see 2.
#
# 4. List sertificates
#
# $ certutil -l [-d certdir]
#
# And again, certdir is optional.
#
# 5. View certificate properties
#
# $ certutil -v -n "My Cert" [-d certdir]
#
#
# Print usage
usage() {
cat << EOF
Usage: $0 -l [-d dir]
-a -n name -i file [-d dir]
-r -n name [-d dir]
-v -n name [-d dir]
Commands:
-l -- List sertificates (requires a valid dir)
-a -- Add sertificate and create dir if necessary
-r -- Remove sertificate (requires a valid dir)
-v -- View sertificate (requires a valid dir)
Parameters:
dir -- Certificate directory, or \$PWD if not given
name -- Nickname of the certificate
file -- Certificate file in PEM format
EOF
exit 1
}
# Check path
check_path() {
# check the directory
if [ ! -d $CDIR -a $ADD -eq 1 ]; then
echo -n "$0: cannot access $CDIR, create? [y/N] "
read LINE
case $LINE in
y|Y)
mkdir $CDIR
chmod 700 $CDIR
touch $CDIR/certs.dat
chmod 600 $CDIR/certs.dat
;;
*)
exit 1
;;
esac
fi
# check certs.dat
if [ ! -e $CDIR/certs.dat ]; then
echo "$0: please specify a valid cert directory"
exit 1
fi
}
# Add certificates
add_cert() {
check_path
if [ ! -e $FILE ]; then
echo "$0: cannot find $FILE"
exit 1
fi
HASH=`openssl x509 -in $FILE -hash -noout 2>/dev/null`.0
if [ $? -ne 0 ]; then
echo "$0: unable to load certificate $FILE"
exit 1
fi
if grep "^$CNAME|" $CDIR/certs.dat 1>/dev/null 2>&1; then
echo "$0: nickname already in use"
exit 1
fi
if [ -e $CDIR/$HASH ]; then
echo "$0: certificate already in directory"
echo `openssl x509 -in $CDIR/$HASH -subject -noout`
exit 1
else
cp $FILE $CDIR/$HASH
chmod 600 $CDIR/$HASH
echo "$CNAME|$HASH" >> $CDIR/certs.dat
chmod 600 $CDIR/certs.dat
fi
}
# List certificates
#
# (this is too slow...)
#
list_cert() {
check_path
echo
echo "Certificates in directory $CDIR"
echo
printf "%-30s%s\n" nickname subject/issuer
echo "----------------------------------------------------------------------------"
cat $CDIR/certs.dat | while read LINE; do
NICK=`echo $LINE | cut -d "|" -f 1`
HASH=`echo $LINE | cut -d "|" -f 2`
SUBJECT=`openssl x509 -in $CDIR/$HASH -subject -noout`
ISSUER=`openssl x509 -in $CDIR/$HASH -issuer -noout`
printf "%-30s%s\n" "$NICK" "$SUBJECT"
printf "%-30s%s\n\n" "" "$ISSUER"
done
}
# Remove certificates
remove_cert() {
check_path
(
cat $CDIR/certs.dat | while read LINE; do
NICK=`echo $LINE | cut -d "|" -f 1`
HASH=`echo $LINE | cut -d "|" -f 2`
if [ "$CNAME" = "$NICK" ]; then
rm $CDIR/$HASH
else
echo $LINE
fi
done
) > /tmp/$$
mv /tmp/$$ $CDIR/certs.dat
chmod 600 $CDIR/certs.dat
}
# View certificate
view_cert() {
check_path
cat $CDIR/certs.dat | while read LINE; do
NICK=`echo $LINE | cut -d "|" -f 1`
HASH=`echo $LINE | cut -d "|" -f 2`
if [ "$CNAME" = "$NICK" ]; then
openssl x509 -in $CDIR/$HASH -text
return 1
fi
done
}
# Parse option string
ADD=0
REMOVE=0
LIST=0
VIEW=0
while getopts "arlvd:n:i:" OPT; do
case $OPT in
a)
ADD=1
;;
r)
REMOVE=1
;;
l)
LIST=1
;;
v)
VIEW=1
;;
d)
CDIR=$OPTARG
;;
n)
CNAME=$OPTARG
;;
i)
FILE=$OPTARG
;;
*)
usage
;;
esac
done
# Default options
CDIR=${CDIR:=.}
# Check command line options
if [ $ADD -eq 1 -a $REMOVE -eq 0 -a $LIST -eq 0 -a $VIEW -eq 0 ]; then
if [ -n "$CNAME" -a -n "$FILE" ]; then
add_cert
else
echo "$0: missing certificate name or file"
usage
fi
elif [ $REMOVE -eq 1 -a $ADD -eq 0 -a $LIST -eq 0 -a $VIEW -eq 0 ]; then
if [ -n "$CNAME" ]; then
remove_cert
else
echo "$0: missing certificate name"
usage
fi
elif [ $LIST -eq 1 -a $ADD -eq 0 -a $REMOVE -eq 0 -a $VIEW -eq 0 ]; then
list_cert
elif [ $VIEW -eq 1 -a $ADD -eq 0 -a $REMOVE -eq 0 -a $LIST -eq 0 ]; then
if [ -n "$CNAME" ]; then
if view_cert; then
echo "$0: cert named \"$CNAME\" not found"
exit 1
fi
else
echo "$0: missing certificate name"
usage
fi
else
usage
fi