testpkcs11: do not ignore the failure to write a trusted CA
[gnutls:gnutls.git] / tests / suite / testpkcs11
1 #!/bin/sh
2
3 # Copyright (C) 2013 Nikos Mavrogiannopoulos
4 #
5 # This file is part of GnuTLS.
6 #
7 # GnuTLS is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by the
9 # Free Software Foundation; either version 3 of the License, or (at
10 # your option) any later version.
11 #
12 # GnuTLS is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 # General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with GnuTLS; if not, write to the Free Software Foundation,
19 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
21 srcdir="${srcdir:-.}"
22 P11TOOL="${P11TOOL:-../../src/p11tool$EXEEXT}"
23 CERTTOOL="${CERTTOOL:-../../src/certtool$EXEEXT}"
24 DIFF="${DIFF:-diff -b -B}"
25 SERV="${SERV:-../../src/gnutls-serv$EXEEXT} -q"
26 CLI="${CLI:-../../src/gnutls-cli$EXEEXT}"
27 RETCODE=0
28
29 if ! test -z "${VALGRIND}";then
30 VALGRIND="${LIBTOOL:-libtool} --mode=execute ${VALGRIND} --leak-check=no"
31 fi
32
33 TMPFILE=$srcdir/testpkcs11.debug
34 CERTTOOL_PARAM="--stdout-info"
35
36 if test "${WINDIR}" != "";then
37   exit 77
38 fi 
39
40 P11TOOL="$VALGRIND $P11TOOL --batch"
41
42 . $srcdir/../scripts/common.sh
43
44 PORT="${PORT:-$RPORT}"
45
46 rm -f $TMPFILE
47
48 exit_error () {
49         echo "Check $TMPFILE for additional debugging information"
50         echo ""
51         echo ""
52         tail $TMPFILE
53         exit 1
54 }
55
56 # $1: token
57 # $2: PIN
58 # $3: filename
59 # $srcdir/pkcs11-certs/client.key
60 write_privkey () {
61         export GNUTLS_PIN=$2
62
63         filename=$3
64         token=$1
65         echo -n "* Writing a client private key... "
66         $P11TOOL $ADDITIONAL_PARAM --login --write --label gnutls-client2 --load-privkey "$filename" "$token" >>$TMPFILE 2>&1
67         if test $? = 0;then
68                 echo ok
69         else
70                 echo failed
71                 exit_error
72         fi
73
74 }
75
76 # $1: token
77 # $2: PIN
78 # $3: filename
79 write_serv_privkey () {
80         export GNUTLS_PIN=$2
81
82         filename=$3
83         token=$1
84         echo -n "* Writing the server private key... "
85         $P11TOOL $ADDITIONAL_PARAM --login --write --label serv-key --load-privkey "$filename" "$token" >>$TMPFILE 2>&1
86         if test $? = 0;then
87                 echo ok
88         else
89                 echo failed
90                 exit_error
91         fi
92
93 }
94
95 # $1: token
96 # $2: PIN
97 # $3: filename
98 write_serv_cert () {
99         export GNUTLS_PIN=$2
100
101         filename=$3
102         token=$1
103         echo -n "* Writing the server certificate... "
104         $P11TOOL $ADDITIONAL_PARAM --login --write --no-mark-private --label serv-cert --load-certificate "$filename" "$token" >>$TMPFILE 2>&1
105         if test $? = 0;then
106                 echo ok
107         else
108                 echo failed
109                 exit_error
110         fi
111
112 }
113
114 # $1: token
115 # $2: PIN
116 # $3: bits
117 generate_rsa_privkey () {
118         export GNUTLS_PIN=$2
119         token=$1
120         bits=$3
121
122         echo -n "* Generating RSA private key ($bits)... "
123         $P11TOOL $ADDITIONAL_PARAM --login --label gnutls-client --generate-rsa --bits $bits "$token" --outfile tmp-client.pub >>$TMPFILE 2>&1
124         if test $? = 0;then
125                 echo ok
126         else
127                 echo failed
128                 exit 1
129         fi
130 }
131
132 # $1: token
133 # $2: PIN
134 # $3: bits
135 generate_temp_rsa_privkey () {
136         export GNUTLS_PIN=$2
137         token=$1
138         bits=$3
139
140         echo -n "* Generating RSA private key ($bits)... "
141         $P11TOOL $ADDITIONAL_PARAM --login --label temp-rsa-$bits --generate-rsa --bits $bits "$token" --outfile tmp-client.pub >>$TMPFILE 2>&1
142         if test $? = 0;then
143                 RETCODE=0
144                 echo ok
145         else
146                 echo failed
147                 RETCODE=1
148         fi
149
150 #       if test $RETCODE = 0;then
151 #               echo -n "* Testing private key flags... "
152 #               $P11TOOL $ADDITIONAL_PARAM --login --list-keys "$token;object=gnutls-client2;object-type=private" >tmp-client-2.pub 2>>$TMPFILE
153 #               if test $? != 0;then
154 #                       echo failed
155 #                       exit_error
156 #               fi
157 #
158 #               grep CKA_WRAP tmp-client-2.pub >>$TMPFILE 2>&1
159 #               if test $? != 0;then
160 #                       echo "failed (no CKA_WRAP)"
161 #                       exit_error
162 #               else
163 #                       echo ok
164 #               fi
165 #       fi
166 }
167
168 # $1: token
169 # $2: PIN
170 delete_temp_privkey () {
171         export GNUTLS_PIN=$2
172         token=$1
173         type=$3
174
175         test "$RETCODE" = "0" || return
176
177         echo -n "* Deleting private key... "
178         $P11TOOL $ADDITIONAL_PARAM --login --delete "$token;object=temp-$type;object-type=private" >>$TMPFILE 2>&1
179
180         if test $? != 0;then
181                 echo failed
182                 RETCODE=1
183                 return
184         fi
185
186         RETCODE=0
187         echo ok
188 }
189
190 # $1: token
191 # $2: PIN
192 # $3: bits
193 export_pubkey_of_privkey () {
194         export GNUTLS_PIN=$2
195         token=$1
196         bits=$3
197
198         echo -n "* Exporting public key of generated private key... "
199         $P11TOOL $ADDITIONAL_PARAM --login --export-pubkey "$token;object=gnutls-client;object-type=private" --outfile tmp-client-2.pub >>$TMPFILE 2>&1
200         if test $? != 0;then
201                 echo failed
202                 exit 1
203         fi
204
205         $DIFF tmp-client.pub tmp-client-2.pub
206         if test $? != 0;then
207                 echo keys differ
208                 exit 1
209         fi
210
211         echo ok
212 }
213
214 # $1: token
215 # $2: PIN
216 # $3: bits
217 generate_temp_ecc_privkey () {
218         export GNUTLS_PIN=$2
219         token=$1
220         bits=$3
221
222         echo -n "* Generating ECC private key ($bits)... "
223         $P11TOOL $ADDITIONAL_PARAM --login --label temp-ecc-$bits --generate-ecc --bits $bits "$token" --outfile tmp-client.pub >>$TMPFILE 2>&1
224         if test $? = 0;then
225                 RETCODE=0
226                 echo ok
227         else
228                 echo failed
229                 RETCODE=1
230         fi
231 }
232
233 # $1: token
234 # $2: PIN
235 # $3: cakey: $srcdir/pkcs11-certs/ca.key
236 # $4: cacert: $srcdir/pkcs11-certs/ca.crt
237 #
238 # Tests writing a certificate which corresponds to the given key,
239 # as well as the CA certificate, and tries to export them.
240 write_certificate_test () {
241         export GNUTLS_PIN=$2
242         token=$1
243         cakey=$3
244         cacert=$4
245         pubkey=$5
246
247         echo -n "* Generating client certificate... "
248         $CERTTOOL $CERTTOOL_PARAM $ADDITIONAL_PARAM  --generate-certificate --load-ca-privkey "$cakey"  --load-ca-certificate "$cacert"  \
249         --template $srcdir/pkcs11-certs/client-tmpl --load-privkey "$token;object=gnutls-client;object-type=private" \
250         --load-pubkey "$pubkey" --outfile tmp-client.crt >>$TMPFILE 2>&1
251
252         if test $? = 0;then
253                 echo ok
254         else
255                 echo failed
256                 exit_error
257         fi
258
259         echo -n "* Writing client certificate... "
260         $P11TOOL $ADDITIONAL_PARAM --login --write --label gnutls-client --load-certificate tmp-client.crt "$token" >>$TMPFILE 2>&1
261         if test $? = 0;then
262                 echo ok
263         else
264                 echo failed
265                 exit_error
266         fi
267
268         echo -n "* Writing certificate of client's CA... "
269         $P11TOOL $ADDITIONAL_PARAM --login --mark-trusted --mark-ca --write --label gnutls-ca --load-certificate "$cacert" "$token" >>$TMPFILE 2>&1
270         ret=$?
271         if test $ret != 0;then
272                 $P11TOOL $ADDITIONAL_PARAM --so-login --mark-ca --write --mark-trusted --label gnutls-ca --load-certificate "$cacert" "$token" >>$TMPFILE 2>&1
273                 ret=$?
274         fi
275
276         if test $ret = 0;then
277                 echo ok
278         else
279                 echo failed
280                 exit_error
281         fi
282
283         echo -n "* Testing certificate flags... "
284         $P11TOOL $ADDITIONAL_PARAM --login --list-all-certs "$token;object=gnutls-ca;object-type=cert" |grep Flags|head -n 1 >tmp-client-2.pub 2>>$TMPFILE
285         if test $? != 0;then
286                 echo failed
287                 exit_error
288         fi
289
290         grep CKA_TRUSTED tmp-client-2.pub >>$TMPFILE 2>&1
291         if test $? != 0;then
292                 echo "failed (no CKA_TRUSTED)"
293                 #exit_error
294         fi
295
296         grep "CKA_CERTIFICATE_CATEGORY=CA" tmp-client-2.pub >>$TMPFILE 2>&1
297         if test $? != 0;then
298                 echo "failed (no CKA_CERTIFICATE_CATEGORY=CA)"
299                 #exit_error
300         fi
301
302         echo ok
303
304
305         echo -n "* Trying to obtain back the cert... "
306         $P11TOOL $ADDITIONAL_PARAM --export "$token;object=gnutls-ca;object-type=cert" --outfile crt1.tmp >>$TMPFILE 2>&1
307         $DIFF crt1.tmp $srcdir/pkcs11-certs/ca.crt
308         if test $? != 0;then
309                 echo "failed. Exported certificate differs (crt1.tmp)!"
310                 exit_error
311         fi
312         rm -f crt1.tmp
313         if test $? = 0;then
314                 echo ok
315         else
316                 echo failed
317                 exit_error
318         fi
319
320         echo -n "* Trying to obtain the full chain... "
321         $P11TOOL $ADDITIONAL_PARAM --login --export-chain "$token;object=gnutls-client;object-type=cert"|$CERTTOOL $CERTTOOL_PARAM  -i --outfile crt1.tmp >>$TMPFILE 2>&1
322
323         cat tmp-client.crt $srcdir/pkcs11-certs/ca.crt|$CERTTOOL $CERTTOOL_PARAM  -i >crt2.tmp
324         $DIFF crt1.tmp crt2.tmp
325         if test $? != 0;then
326                 echo "failed. Exported certificate chain differs!"
327                 exit_error
328         fi
329         rm -f crt1.tmp crt2.tmp
330         if test $? = 0;then
331                 echo ok
332         else
333                 echo failed
334                 exit_error
335         fi
336 }
337
338
339 # $1: token
340 # $2: PIN
341 # $3: certfile
342 # $4: keyfile
343 # $5: cafile
344 #
345 # Tests using a certificate and key pair using gnutls-serv and gnutls-cli.
346 use_certificate_test () {
347         export GNUTLS_PIN=$2
348         token=$1
349         certfile=$3
350         keyfile=$4
351         cafile=$5
352         txt=$6
353
354         echo -n "* Using PKCS #11 with gnutls-cli ($txt)... "
355         # start server
356         launch_pkcs11_server $$ "$ADDITIONAL_PARAM" --echo --priority NORMAL --x509certfile="$certfile" \
357                 --x509keyfile="$keyfile" --x509cafile="$cafile" \
358                 --require-client-cert >>$TMPFILE 2>&1 &
359
360         PID=$!
361         wait_server $PID
362
363         # connect to server using SC
364         $VALGRIND $CLI $ADDITIONAL_PARAM -p $PORT localhost --priority NORMAL --x509cafile="$cafile" </dev/null >>$TMPFILE 2>&1 && \
365                 fail $PID "Connection should have failed!"
366
367         $VALGRIND $CLI $ADDITIONAL_PARAM -p $PORT localhost --priority NORMAL --x509certfile="$certfile" \
368         --x509keyfile="$keyfile" --x509cafile="$cafile" </dev/null >>$TMPFILE 2>&1 || \
369                 fail $PID "Connection (with files) should have succeeded!"
370
371         $VALGRIND $CLI $ADDITIONAL_PARAM -p $PORT localhost --priority NORMAL --x509certfile="$token;object=gnutls-client;object-type=cert" \
372                 --x509keyfile="$token;object=gnutls-client;object-type=private" \
373                 --x509cafile="$cafile" </dev/null >>$TMPFILE 2>&1 || \
374                 fail $PID "Connection (with SC) should have succeeded!"
375
376         kill $PID
377         wait
378
379         echo ok
380 }
381
382
383
384 echo "Testing PKCS11 support"
385
386 # erase SC
387
388 type=$1
389
390 if test -z "$type";then
391         echo "usage: $0: [pkcs15|softhsm|sc-hsm]"
392         if test -x "/usr/bin/softhsm" || test -x "/usr/bin/softhsm2-util";then
393                 echo "assuming 'softhsm'"
394                 echo ""
395                 type=softhsm
396         else
397                 exit 1
398         fi
399
400 fi
401
402 . $srcdir/testpkcs11.$type
403
404 export GNUTLS_PIN=12345678
405 export GNUTLS_SO_PIN=00000000
406
407 init_card $GNUTLS_PIN $GNUTLS_SO_PIN
408
409 # find token name
410 TOKEN=`$P11TOOL $ADDITIONAL_PARAM --list-tokens pkcs11:token=Nikos|grep URL|grep token=GnuTLS-Test|sed 's/\s*URL\: //g'`
411
412 echo "* Token: $TOKEN"
413 if test x"$TOKEN" = x;then
414         echo "Could not find generated token"
415         exit_error
416 fi
417
418 #write a given privkey
419 write_privkey $TOKEN $GNUTLS_PIN "$srcdir/pkcs11-certs/client.key"
420
421 generate_temp_ecc_privkey $TOKEN $GNUTLS_PIN 256
422 delete_temp_privkey $TOKEN $GNUTLS_PIN ecc-256
423
424 generate_temp_ecc_privkey $TOKEN $GNUTLS_PIN 384
425 delete_temp_privkey $TOKEN $GNUTLS_PIN ecc-384
426
427 generate_temp_rsa_privkey $TOKEN $GNUTLS_PIN 2048
428 delete_temp_privkey $TOKEN $GNUTLS_PIN rsa-2048
429
430 generate_rsa_privkey $TOKEN $GNUTLS_PIN 1024
431 export_pubkey_of_privkey $TOKEN $GNUTLS_PIN
432
433 write_certificate_test $TOKEN $GNUTLS_PIN "$srcdir/pkcs11-certs/ca.key" "$srcdir/pkcs11-certs/ca.crt" tmp-client.pub
434
435 write_serv_privkey $TOKEN $GNUTLS_PIN "$srcdir/pkcs11-certs/server.key"
436 write_serv_cert $TOKEN $GNUTLS_PIN "$srcdir/pkcs11-certs/server.crt"
437
438 use_certificate_test $TOKEN $GNUTLS_PIN "$TOKEN;object=serv-cert;object-type=cert" "$TOKEN;object=serv-key;object-type=private" "$srcdir/pkcs11-certs/ca.crt" "full URLs"
439
440 use_certificate_test $TOKEN $GNUTLS_PIN "$TOKEN;object=serv-cert" "$TOKEN;object=serv-key" "$srcdir/pkcs11-certs/ca.crt" "abbrv URLs"
441
442 if test $RETCODE = 0;then
443         echo "* All smart cards tests succeeded"
444 fi
445 rm -f tmp-client.crt tmp-client.pub tmp-client-2.pub $TMPFILE
446
447 exit 0