Tizen 2.0 Release
[external/libgnutls26.git] / src / pkcs11.c
1 /*
2  * Copyright (C) 2010 Free Software Foundation, Inc.
3  * Author: Nikos Mavrogiannopoulos
4  *
5  * This file is part of GnuTLS.
6  *
7  * GnuTLS is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuTLS is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 #include <config.h>
21
22 #include <getpass.h>
23
24 #include <gnutls/gnutls.h>
25 #include <gnutls/extra.h>
26 #include <gnutls/pkcs11.h>
27 #include <gnutls/abstract.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include "p11tool.h"
31 #include "certtool-cfg.h"
32 #include "certtool-common.h"
33 #include <unistd.h>
34 #include <string.h>
35 #include <p11common.h>
36
37 void
38 pkcs11_delete (FILE * outfile, const char *url, int batch, unsigned int login,
39                common_info_st * info)
40 {
41   int ret;
42   unsigned int obj_flags = 0;
43
44   if (login)
45     obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN;
46
47   if (!batch)
48     {
49       pkcs11_list (outfile, url, PKCS11_TYPE_ALL, login,
50                    GNUTLS_PKCS11_URL_LIB, info);
51       ret =
52         read_yesno ("Are you sure you want to delete those objects? (y/N): ");
53       if (ret == 0)
54         {
55           exit (1);
56         }
57     }
58
59   ret = gnutls_pkcs11_delete_url (url, obj_flags);
60   if (ret < 0)
61     {
62       fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
63                gnutls_strerror (ret));
64       exit (1);
65     }
66
67   fprintf (outfile, "\n%d objects deleted\n", ret);
68
69   return;
70 }
71
72 /* lists certificates from a token
73  */
74 void
75 pkcs11_list (FILE * outfile, const char *url, int type, unsigned int login,
76              unsigned int detailed, common_info_st * info)
77 {
78   gnutls_pkcs11_obj_t *crt_list;
79   gnutls_x509_crt_t xcrt;
80   unsigned int crt_list_size = 0;
81   int ret;
82   char *output;
83   int i, attrs;
84   unsigned int obj_flags = 0;
85
86   if (login)
87     obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN;
88
89   pkcs11_common ();
90
91   if (url == NULL)
92     url = "pkcs11:";
93
94   if (type == PKCS11_TYPE_TRUSTED)
95     {
96       attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED;
97     }
98   else if (type == PKCS11_TYPE_PK)
99     {
100       attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY;
101     }
102   else if (type == PKCS11_TYPE_CRT_ALL)
103     {
104       attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL;
105     }
106   else if (type == PKCS11_TYPE_PRIVKEY)
107     {
108       attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY;
109     }
110   else
111     {
112       attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL;
113     }
114
115   /* give some initial value to avoid asking for the pkcs11 pin twice.
116    */
117   crt_list_size = 128;
118   crt_list = malloc (sizeof (*crt_list) * crt_list_size);
119   if (crt_list == NULL)
120     {
121       fprintf (stderr, "Memory error\n");
122       exit (1);
123     }
124
125   ret = gnutls_pkcs11_obj_list_import_url (crt_list, &crt_list_size, url,
126                                            attrs, obj_flags);
127   if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
128     {
129       fprintf (stderr, "Error in crt_list_import (1): %s\n",
130                gnutls_strerror (ret));
131       exit (1);
132     }
133
134   if (crt_list_size == 0)
135     {
136       fprintf (stderr, "No matching objects found\n");
137       exit (0);
138     }
139
140   if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
141     {
142       crt_list = realloc (crt_list, sizeof (*crt_list) * crt_list_size);
143       if (crt_list == NULL)
144         {
145           fprintf (stderr, "Memory error\n");
146           exit (1);
147         }
148
149       ret =
150         gnutls_pkcs11_obj_list_import_url (crt_list, &crt_list_size, url,
151                                            attrs, obj_flags);
152       if (ret < 0)
153         {
154           fprintf (stderr, "Error in crt_list_import: %s\n",
155                    gnutls_strerror (ret));
156           exit (1);
157         }
158     }
159
160   for (i = 0; i < crt_list_size; i++)
161     {
162       char buf[128];
163       size_t size;
164
165       ret = gnutls_pkcs11_obj_export_url (crt_list[i], detailed, &output);
166       if (ret < 0)
167         {
168           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
169                    gnutls_strerror (ret));
170           exit (1);
171         }
172
173       fprintf (outfile, "Object %d:\n\tURL: %s\n", i, output);
174
175       fprintf (outfile, "\tType: %s\n",
176                gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_get_type
177                                             (crt_list[i])));
178
179       size = sizeof (buf);
180       ret =
181         gnutls_pkcs11_obj_get_info (crt_list[i], GNUTLS_PKCS11_OBJ_LABEL, buf,
182                                     &size);
183       if (ret < 0)
184         {
185           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
186                    gnutls_strerror (ret));
187           exit (1);
188         }
189       fprintf (outfile, "\tLabel: %s\n", buf);
190
191       size = sizeof (buf);
192       ret =
193         gnutls_pkcs11_obj_get_info (crt_list[i], GNUTLS_PKCS11_OBJ_ID_HEX,
194                                     buf, &size);
195       if (ret < 0)
196         {
197           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
198                    gnutls_strerror (ret));
199           exit (1);
200         }
201       fprintf (outfile, "\tID: %s\n\n", buf);
202
203
204
205       if (attrs == GNUTLS_PKCS11_OBJ_ATTR_ALL
206           || attrs == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY)
207         continue;
208
209       ret = gnutls_x509_crt_init (&xcrt);
210       if (ret < 0)
211         {
212           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
213                    gnutls_strerror (ret));
214           exit (1);
215         }
216
217       ret = gnutls_x509_crt_import_pkcs11 (xcrt, crt_list[i]);
218       if (ret < 0)
219         {
220           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
221                    gnutls_strerror (ret));
222           exit (1);
223         }
224
225 #if 0
226       size = buffer_size;
227       ret = gnutls_x509_crt_export (xcrt, GNUTLS_X509_FMT_PEM, buffer, &size);
228       if (ret < 0)
229         {
230           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
231                    gnutls_strerror (ret));
232           exit (1);
233         }
234
235       fwrite (buffer, 1, size, outfile);
236       fputs ("\n\n", outfile);
237 #endif
238
239       gnutls_x509_crt_deinit (xcrt);
240
241
242     }
243
244   return;
245 }
246
247 void
248 pkcs11_export (FILE * outfile, const char *url, unsigned int login,
249                common_info_st * info)
250 {
251   gnutls_pkcs11_obj_t crt;
252   gnutls_x509_crt_t xcrt;
253   gnutls_pubkey_t pubkey;
254   int ret;
255   size_t size;
256   unsigned int obj_flags = 0;
257
258   if (login)
259     obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN;
260
261   pkcs11_common ();
262
263   if (url == NULL)
264     url = "pkcs11:";
265
266   ret = gnutls_pkcs11_obj_init (&crt);
267   if (ret < 0)
268     {
269       fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
270                gnutls_strerror (ret));
271       exit (1);
272     }
273
274   ret = gnutls_pkcs11_obj_import_url (crt, url, obj_flags);
275   if (ret < 0)
276     {
277       fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
278                gnutls_strerror (ret));
279       exit (1);
280     }
281
282   switch (gnutls_pkcs11_obj_get_type (crt))
283     {
284     case GNUTLS_PKCS11_OBJ_X509_CRT:
285       ret = gnutls_x509_crt_init (&xcrt);
286       if (ret < 0)
287         {
288           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
289                    gnutls_strerror (ret));
290           exit (1);
291         }
292
293       ret = gnutls_x509_crt_import_pkcs11 (xcrt, crt);
294       if (ret < 0)
295         {
296           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
297                    gnutls_strerror (ret));
298           exit (1);
299         }
300
301       size = buffer_size;
302       ret = gnutls_x509_crt_export (xcrt, GNUTLS_X509_FMT_PEM, buffer, &size);
303       if (ret < 0)
304         {
305           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
306                    gnutls_strerror (ret));
307           exit (1);
308         }
309       fwrite (buffer, 1, size, outfile);
310
311       gnutls_x509_crt_deinit (xcrt);
312       break;
313     case GNUTLS_PKCS11_OBJ_PUBKEY:
314       ret = gnutls_pubkey_init (&pubkey);
315       if (ret < 0)
316         {
317           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
318                    gnutls_strerror (ret));
319           exit (1);
320         }
321
322       ret = gnutls_pubkey_import_pkcs11 (pubkey, crt, 0);
323       if (ret < 0)
324         {
325           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
326                    gnutls_strerror (ret));
327           exit (1);
328         }
329
330       size = buffer_size;
331       ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_PEM, buffer, &size);
332       if (ret < 0)
333         {
334           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
335                    gnutls_strerror (ret));
336           exit (1);
337         }
338       fwrite (buffer, 1, size, outfile);
339
340       gnutls_pubkey_deinit (pubkey);
341       break;
342     default:
343       {
344         gnutls_datum data, enc;
345
346         size = buffer_size;
347         ret = gnutls_pkcs11_obj_export (crt, buffer, &size);
348         if (ret < 0)
349           {
350             break;
351           }
352
353         data.data = buffer;
354         data.size = size;
355
356         ret = gnutls_pem_base64_encode_alloc ("DATA", &data, &enc);
357         if (ret < 0)
358           {
359             fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
360                      gnutls_strerror (ret));
361             exit (1);
362           }
363
364         fwrite (enc.data, 1, enc.size, outfile);
365
366         gnutls_free (enc.data);
367         break;
368       }
369     }
370   fputs ("\n\n", outfile);
371
372
373   gnutls_pkcs11_obj_deinit (crt);
374
375   return;
376
377 }
378
379 void
380 pkcs11_token_list (FILE * outfile, unsigned int detailed,
381                    common_info_st * info)
382 {
383   int ret;
384   int i;
385   char *url;
386   char buf[128];
387   size_t size;
388
389   pkcs11_common ();
390
391   for (i = 0;; i++)
392     {
393       ret = gnutls_pkcs11_token_get_url (i, detailed, &url);
394       if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
395         break;
396
397       if (ret < 0)
398         {
399           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
400                    gnutls_strerror (ret));
401           exit (1);
402         }
403
404       fprintf (outfile, "Token %d:\n\tURL: %s\n", i, url);
405
406       size = sizeof (buf);
407       ret =
408         gnutls_pkcs11_token_get_info (url, GNUTLS_PKCS11_TOKEN_LABEL, buf,
409                                       &size);
410       if (ret < 0)
411         {
412           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
413                    gnutls_strerror (ret));
414           exit (1);
415         }
416
417       fprintf (outfile, "\tLabel: %s\n", buf);
418
419       size = sizeof (buf);
420       ret =
421         gnutls_pkcs11_token_get_info (url, GNUTLS_PKCS11_TOKEN_MANUFACTURER,
422                                       buf, &size);
423       if (ret < 0)
424         {
425           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
426                    gnutls_strerror (ret));
427           exit (1);
428         }
429
430       fprintf (outfile, "\tManufacturer: %s\n", buf);
431
432       size = sizeof (buf);
433       ret =
434         gnutls_pkcs11_token_get_info (url, GNUTLS_PKCS11_TOKEN_MODEL, buf,
435                                       &size);
436       if (ret < 0)
437         {
438           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
439                    gnutls_strerror (ret));
440           exit (1);
441         }
442
443       fprintf (outfile, "\tModel: %s\n", buf);
444
445       size = sizeof (buf);
446       ret =
447         gnutls_pkcs11_token_get_info (url, GNUTLS_PKCS11_TOKEN_SERIAL, buf,
448                                       &size);
449       if (ret < 0)
450         {
451           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
452                    gnutls_strerror (ret));
453           exit (1);
454         }
455
456       fprintf (outfile, "\tSerial: %s\n", buf);
457       fprintf (outfile, "\n\n");
458
459       gnutls_free (url);
460
461     }
462
463   return;
464 }
465
466 void
467 pkcs11_write (FILE * outfile, const char *url, const char *label, int trusted,
468               unsigned int login, common_info_st * info)
469 {
470   gnutls_x509_crt_t xcrt;
471   gnutls_x509_privkey_t xkey;
472   int ret;
473   unsigned int flags = 0;
474   unsigned int key_usage = 0;
475   gnutls_datum_t *secret_key;
476
477   if (login)
478     flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN;
479
480   pkcs11_common ();
481
482   if (url == NULL)
483     url = "pkcs11:";
484
485   secret_key = load_secret_key (0, info);
486   if (secret_key != NULL)
487     {
488       ret =
489         gnutls_pkcs11_copy_secret_key (url, secret_key, label, key_usage,
490                                        flags |
491                                        GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE);
492       if (ret < 0)
493         {
494           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
495                    gnutls_strerror (ret));
496           exit (1);
497         }
498     }
499
500   xcrt = load_cert (0, info);
501   if (xcrt != NULL)
502     {
503       if (trusted)
504         flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED|GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO;
505
506       ret = gnutls_pkcs11_copy_x509_crt (url, xcrt, label, flags);
507       if (ret < 0)
508         {
509           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
510                    gnutls_strerror (ret));
511           exit (1);
512         }
513
514       gnutls_x509_crt_get_key_usage (xcrt, &key_usage, NULL);
515     }
516
517   xkey = load_x509_private_key (0, info);
518   if (xkey != NULL)
519     {
520       ret =
521         gnutls_pkcs11_copy_x509_privkey (url, xkey, label, key_usage,
522                                          flags |
523                                          GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE);
524       if (ret < 0)
525         {
526           fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
527                    gnutls_strerror (ret));
528           exit (1);
529         }
530     }
531
532   if (xkey == NULL && xcrt == NULL && secret_key == NULL)
533     {
534       fprintf (stderr,
535                "You must use --load-privkey, --load-certificate or --secret-key to load the file to be copied\n");
536       exit (1);
537     }
538
539   return;
540 }
541
542 void
543 pkcs11_init (FILE * outfile, const char *url, const char *label,
544              common_info_st * info)
545 {
546   int ret;
547   char *pin;
548   char so_pin[32];
549
550   pkcs11_common ();
551
552   if (url == NULL)
553     {
554       fprintf (stderr, "No token URL given to initialize!\n");
555       exit (1);
556     }
557
558   pin = getpass ("Enter Security Officer's PIN: ");
559   if (pin == NULL)
560     exit (1);
561
562   if (strlen(pin) >= sizeof(so_pin))
563     exit (1);
564
565   strcpy (so_pin, pin);
566
567   pin = getpass ("Enter new User's PIN: ");
568   if (pin == NULL)
569     exit (1);
570
571   ret = gnutls_pkcs11_token_init (url, so_pin, label);
572   if (ret < 0)
573     {
574       fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
575                gnutls_strerror (ret));
576       exit (1);
577     }
578
579   ret = gnutls_pkcs11_token_set_pin (url, NULL, pin, GNUTLS_PKCS11_PIN_USER);
580   if (ret < 0)
581     {
582       fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
583                gnutls_strerror (ret));
584       exit (1);
585     }
586
587   return;
588 }
589
590 const char *mech_list[] = {
591   [0] = "CKM_RSA_PKCS_KEY_PAIR_GEN",
592   [1] = "CKM_RSA_PKCS",
593   [2] = "CKM_RSA_9796",
594   [3] = "CKM_RSA_X_509",
595   [4] = "CKM_MD2_RSA_PKCS",
596   [5] = "CKM_MD5_RSA_PKCS",
597   [6] = "CKM_SHA1_RSA_PKCS",
598   [7] = "CKM_RIPEMD128_RSA_PKCS",
599   [8] = "CKM_RIPEMD160_RSA_PKCS",
600   [9] = "CKM_RSA_PKCS_OAEP",
601   [0xa] = "CKM_RSA_X9_31_KEY_PAIR_GEN",
602   [0xb] = "CKM_RSA_X9_31",
603   [0xc] = "CKM_SHA1_RSA_X9_31",
604   [0xd] = "CKM_RSA_PKCS_PSS",
605   [0xe] = "CKM_SHA1_RSA_PKCS_PSS",
606   [0x10] = "CKM_DSA_KEY_PAIR_GEN",
607   [0x11] = "CKM_DSA",
608   [0x12] = "CKM_DSA_SHA1",
609   [0x20] = "CKM_DH_PKCS_KEY_PAIR_GEN",
610   [0x21] = "CKM_DH_PKCS_DERIVE",
611   [0x30] = "CKM_X9_42_DH_KEY_PAIR_GEN",
612   [0x31] = "CKM_X9_42_DH_DERIVE",
613   [0x32] = "CKM_X9_42_DH_HYBRID_DERIVE",
614   [0x33] = "CKM_X9_42_MQV_DERIVE",
615   [0x40] = "CKM_SHA256_RSA_PKCS",
616   [0x41] = "CKM_SHA384_RSA_PKCS",
617   [0x42] = "CKM_SHA512_RSA_PKCS",
618   [0x43] = "CKM_SHA256_RSA_PKCS_PSS",
619   [0x44] = "CKM_SHA384_RSA_PKCS_PSS",
620   [0x45] = "CKM_SHA512_RSA_PKCS_PSS",
621   [0x100] = "CKM_RC2_KEY_GEN",
622   [0x101] = "CKM_RC2_ECB",
623   [0x102] = "CKM_RC2_CBC",
624   [0x103] = "CKM_RC2_MAC",
625   [0x104] = "CKM_RC2_MAC_GENERAL",
626   [0x105] = "CKM_RC2_CBC_PAD",
627   [0x110] = "CKM_RC4_KEY_GEN",
628   [0x111] = "CKM_RC4",
629   [0x120] = "CKM_DES_KEY_GEN",
630   [0x121] = "CKM_DES_ECB",
631   [0x122] = "CKM_DES_CBC",
632   [0x123] = "CKM_DES_MAC",
633   [0x124] = "CKM_DES_MAC_GENERAL",
634   [0x125] = "CKM_DES_CBC_PAD",
635   [0x130] = "CKM_DES2_KEY_GEN",
636   [0x131] = "CKM_DES3_KEY_GEN",
637   [0x132] = "CKM_DES3_ECB",
638   [0x133] = "CKM_DES3_CBC",
639   [0x134] = "CKM_DES3_MAC",
640   [0x135] = "CKM_DES3_MAC_GENERAL",
641   [0x136] = "CKM_DES3_CBC_PAD",
642   [0x140] = "CKM_CDMF_KEY_GEN",
643   [0x141] = "CKM_CDMF_ECB",
644   [0x142] = "CKM_CDMF_CBC",
645   [0x143] = "CKM_CDMF_MAC",
646   [0x144] = "CKM_CDMF_MAC_GENERAL",
647   [0x145] = "CKM_CDMF_CBC_PAD",
648   [0x200] = "CKM_MD2",
649   [0x201] = "CKM_MD2_HMAC",
650   [0x202] = "CKM_MD2_HMAC_GENERAL",
651   [0x210] = "CKM_MD5",
652   [0x211] = "CKM_MD5_HMAC",
653   [0x212] = "CKM_MD5_HMAC_GENERAL",
654   [0x220] = "CKM_SHA_1",
655   [0x221] = "CKM_SHA_1_HMAC",
656   [0x222] = "CKM_SHA_1_HMAC_GENERAL",
657   [0x230] = "CKM_RIPEMD128",
658   [0x231] = "CKM_RIPEMD128_HMAC",
659   [0x232] = "CKM_RIPEMD128_HMAC_GENERAL",
660   [0x240] = "CKM_RIPEMD160",
661   [0x241] = "CKM_RIPEMD160_HMAC",
662   [0x242] = "CKM_RIPEMD160_HMAC_GENERAL",
663   [0x250] = "CKM_SHA256",
664   [0x251] = "CKM_SHA256_HMAC",
665   [0x252] = "CKM_SHA256_HMAC_GENERAL",
666   [0x260] = "CKM_SHA384",
667   [0x261] = "CKM_SHA384_HMAC",
668   [0x262] = "CKM_SHA384_HMAC_GENERAL",
669   [0x270] = "CKM_SHA512",
670   [0x271] = "CKM_SHA512_HMAC",
671   [0x272] = "CKM_SHA512_HMAC_GENERAL",
672   [0x300] = "CKM_CAST_KEY_GEN",
673   [0x301] = "CKM_CAST_ECB",
674   [0x302] = "CKM_CAST_CBC",
675   [0x303] = "CKM_CAST_MAC",
676   [0x304] = "CKM_CAST_MAC_GENERAL",
677   [0x305] = "CKM_CAST_CBC_PAD",
678   [0x310] = "CKM_CAST3_KEY_GEN",
679   [0x311] = "CKM_CAST3_ECB",
680   [0x312] = "CKM_CAST3_CBC",
681   [0x313] = "CKM_CAST3_MAC",
682   [0x314] = "CKM_CAST3_MAC_GENERAL",
683   [0x315] = "CKM_CAST3_CBC_PAD",
684   [0x320] = "CKM_CAST128_KEY_GEN",
685   [0x321] = "CKM_CAST128_ECB",
686   [0x322] = "CKM_CAST128_CBC",
687   [0x323] = "CKM_CAST128_MAC",
688   [0x324] = "CKM_CAST128_MAC_GENERAL",
689   [0x325] = "CKM_CAST128_CBC_PAD",
690   [0x330] = "CKM_RC5_KEY_GEN",
691   [0x331] = "CKM_RC5_ECB",
692   [0x332] = "CKM_RC5_CBC",
693   [0x333] = "CKM_RC5_MAC",
694   [0x334] = "CKM_RC5_MAC_GENERAL",
695   [0x335] = "CKM_RC5_CBC_PAD",
696   [0x340] = "CKM_IDEA_KEY_GEN",
697   [0x341] = "CKM_IDEA_ECB",
698   [0x342] = "CKM_IDEA_CBC",
699   [0x343] = "CKM_IDEA_MAC",
700   [0x344] = "CKM_IDEA_MAC_GENERAL",
701   [0x345] = "CKM_IDEA_CBC_PAD",
702   [0x350] = "CKM_GENERIC_SECRET_KEY_GEN",
703   [0x360] = "CKM_CONCATENATE_BASE_AND_KEY",
704   [0x362] = "CKM_CONCATENATE_BASE_AND_DATA",
705   [0x363] = "CKM_CONCATENATE_DATA_AND_BASE",
706   [0x364] = "CKM_XOR_BASE_AND_DATA",
707   [0x365] = "CKM_EXTRACT_KEY_FROM_KEY",
708   [0x370] = "CKM_SSL3_PRE_MASTER_KEY_GEN",
709   [0x371] = "CKM_SSL3_MASTER_KEY_DERIVE",
710   [0x372] = "CKM_SSL3_KEY_AND_MAC_DERIVE",
711   [0x373] = "CKM_SSL3_MASTER_KEY_DERIVE_DH",
712   [0x374] = "CKM_TLS_PRE_MASTER_KEY_GEN",
713   [0x375] = "CKM_TLS_MASTER_KEY_DERIVE",
714   [0x376] = "CKM_TLS_KEY_AND_MAC_DERIVE",
715   [0x377] = "CKM_TLS_MASTER_KEY_DERIVE_DH",
716   [0x380] = "CKM_SSL3_MD5_MAC",
717   [0x381] = "CKM_SSL3_SHA1_MAC",
718   [0x390] = "CKM_MD5_KEY_DERIVATION",
719   [0x391] = "CKM_MD2_KEY_DERIVATION",
720   [0x392] = "CKM_SHA1_KEY_DERIVATION",
721   [0x3a0] = "CKM_PBE_MD2_DES_CBC",
722   [0x3a1] = "CKM_PBE_MD5_DES_CBC",
723   [0x3a2] = "CKM_PBE_MD5_CAST_CBC",
724   [0x3a3] = "CKM_PBE_MD5_CAST3_CBC",
725   [0x3a4] = "CKM_PBE_MD5_CAST128_CBC",
726   [0x3a5] = "CKM_PBE_SHA1_CAST128_CBC",
727   [0x3a6] = "CKM_PBE_SHA1_RC4_128",
728   [0x3a7] = "CKM_PBE_SHA1_RC4_40",
729   [0x3a8] = "CKM_PBE_SHA1_DES3_EDE_CBC",
730   [0x3a9] = "CKM_PBE_SHA1_DES2_EDE_CBC",
731   [0x3aa] = "CKM_PBE_SHA1_RC2_128_CBC",
732   [0x3ab] = "CKM_PBE_SHA1_RC2_40_CBC",
733   [0x3b0] = "CKM_PKCS5_PBKD2",
734   [0x3c0] = "CKM_PBA_SHA1_WITH_SHA1_HMAC",
735   [0x400] = "CKM_KEY_WRAP_LYNKS",
736   [0x401] = "CKM_KEY_WRAP_SET_OAEP",
737   [0x1000] = "CKM_SKIPJACK_KEY_GEN",
738   [0x1001] = "CKM_SKIPJACK_ECB64",
739   [0x1002] = "CKM_SKIPJACK_CBC64",
740   [0x1003] = "CKM_SKIPJACK_OFB64",
741   [0x1004] = "CKM_SKIPJACK_CFB64",
742   [0x1005] = "CKM_SKIPJACK_CFB32",
743   [0x1006] = "CKM_SKIPJACK_CFB16",
744   [0x1007] = "CKM_SKIPJACK_CFB8",
745   [0x1008] = "CKM_SKIPJACK_WRAP",
746   [0x1009] = "CKM_SKIPJACK_PRIVATE_WRAP",
747   [0x100a] = "CKM_SKIPJACK_RELAYX",
748   [0x1010] = "CKM_KEA_KEY_PAIR_GEN",
749   [0x1011] = "CKM_KEA_KEY_DERIVE",
750   [0x1020] = "CKM_FORTEZZA_TIMESTAMP",
751   [0x1030] = "CKM_BATON_KEY_GEN",
752   [0x1031] = "CKM_BATON_ECB128",
753   [0x1032] = "CKM_BATON_ECB96",
754   [0x1033] = "CKM_BATON_CBC128",
755   [0x1034] = "CKM_BATON_COUNTER",
756   [0x1035] = "CKM_BATON_SHUFFLE",
757   [0x1036] = "CKM_BATON_WRAP",
758   [0x1040] = "CKM_ECDSA_KEY_PAIR_GEN",
759   [0x1041] = "CKM_ECDSA",
760   [0x1042] = "CKM_ECDSA_SHA1",
761   [0x1050] = "CKM_ECDH1_DERIVE",
762   [0x1051] = "CKM_ECDH1_COFACTOR_DERIVE",
763   [0x1052] = "CKM_ECMQV_DERIVE",
764   [0x1060] = "CKM_JUNIPER_KEY_GEN",
765   [0x1061] = "CKM_JUNIPER_ECB128",
766   [0x1062] = "CKM_JUNIPER_CBC128",
767   [0x1063] = "CKM_JUNIPER_COUNTER",
768   [0x1064] = "CKM_JUNIPER_SHUFFLE",
769   [0x1065] = "CKM_JUNIPER_WRAP",
770   [0x1070] = "CKM_FASTHASH",
771   [0x1080] = "CKM_AES_KEY_GEN",
772   [0x1081] = "CKM_AES_ECB",
773   [0x1082] = "CKM_AES_CBC",
774   [0x1083] = "CKM_AES_MAC",
775   [0x1084] = "CKM_AES_MAC_GENERAL",
776   [0x1085] = "CKM_AES_CBC_PAD",
777   [0x2000] = "CKM_DSA_PARAMETER_GEN",
778   [0x2001] = "CKM_DH_PKCS_PARAMETER_GEN",
779   [0x2002] = "CKM_X9_42_DH_PARAMETER_GEN",
780   [0x255] = "CKM_SHA224",
781   [0x256] = "CKM_SHA224_HMAC",
782   [0x257] = "CKM_SHA224_HMAC_GENERAL",
783   [0x46] = "CKM_SHA224_RSA_PKCS",
784   [0x47] = "CKM_SHA224_RSA_PKCS_PSS",
785   [0x396] = "CKM_SHA224_KEY_DERIVATION",
786   [0x550] = "CKM_CAMELLIA_KEY_GEN",
787   [0x551] = "CKM_CAMELLIA_ECB",
788   [0x552] = "CKM_CAMELLIA_CBC",
789   [0x553] = "CKM_CAMELLIA_MAC",
790   [0x554] = "CKM_CAMELLIA_MAC_GENERAL",
791   [0x555] = "CKM_CAMELLIA_CBC_PAD",
792   [0x556] = "CKM_CAMELLIA_ECB_ENCRYPT_DATA",
793   [0x557] = "CKM_CAMELLIA_CBC_ENCRYPT_DATA"
794 };
795
796 void
797 pkcs11_mechanism_list (FILE * outfile, const char *url, unsigned int login,
798                        common_info_st * info)
799 {
800   int ret;
801   int idx;
802   unsigned long mechanism;
803   const char *str;
804
805   pkcs11_common ();
806
807   if (url == NULL)
808     url = "pkcs11:";
809
810   idx = 0;
811   do
812     {
813       ret = gnutls_pkcs11_token_get_mechanism (url, idx++, &mechanism);
814       if (ret >= 0)
815         {
816           str = NULL;
817           if (mechanism <= sizeof (mech_list) / sizeof (mech_list[0]))
818             str = mech_list[mechanism];
819           if (str == NULL)
820             str = "UNKNOWN";
821
822           fprintf (outfile, "[0x%.4lx] %s\n", mechanism, str);
823         }
824     }
825   while (ret >= 0);
826
827
828   return;
829 }