Merge branch 'upstream' into tizen
[platform/upstream/gnutls.git] / src / pkcs11.c
1 /*
2  * Copyright (C) 2010-2012 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/pkcs11.h>
26 #include <gnutls/abstract.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include "p11tool.h"
30 #include "certtool-cfg.h"
31 #include "certtool-common.h"
32 #include <unistd.h>
33 #include <string.h>
34 #include <stdint.h>
35 #include <common.h>
36
37 #ifdef _WIN32
38 # define sleep(x) Sleep(x*1000)
39 #endif
40
41 static
42 char *get_single_token_url(common_info_st * info);
43
44 #define FIX(url, out, det, info) \
45         if (url == NULL) { \
46                 url = get_single_token_url(info); \
47                 if (url == NULL) { \
48                         fprintf(stderr, "warning: no token URL was provided for this operation; the available tokens are:\n\n"); \
49                         pkcs11_token_list(out, det, info, 1); \
50                         exit(1); \
51                 } \
52         }
53
54 #define CHECK_LOGIN_FLAG(flag) \
55         if (flag == 0) \
56                 fprintf(stderr, \
57                         "warning: --login was not specified and it may be required for this operation.\n")
58
59 void
60 pkcs11_delete(FILE * outfile, const char *url,
61               unsigned int login_flags, common_info_st * info)
62 {
63         int ret;
64         unsigned int obj_flags = 0;
65
66         if (login_flags) obj_flags = login_flags;
67
68         if (info->batch == 0) {
69                 pkcs11_list(outfile, url, PKCS11_TYPE_ALL, login_flags,
70                             GNUTLS_PKCS11_URL_LIB, info);
71                 ret =
72                     read_yesno
73                     ("Are you sure you want to delete those objects? (y/N): ",
74                      0);
75                 if (ret == 0) {
76                         exit(1);
77                 }
78         }
79
80         ret = gnutls_pkcs11_delete_url(url, obj_flags);
81         if (ret < 0) {
82                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
83                         gnutls_strerror(ret));
84                 exit(1);
85         }
86
87         fprintf(outfile, "\n%d objects deleted\n", ret);
88
89         return;
90 }
91
92 /* lists certificates from a token
93  */
94 void
95 pkcs11_list(FILE * outfile, const char *url, int type, unsigned int flags,
96             unsigned int detailed, common_info_st * info)
97 {
98         gnutls_pkcs11_obj_t *crt_list;
99         unsigned int crt_list_size = 0, i, j;
100         int ret, otype;
101         char *output, *str;
102         int attrs, print_exts = 0;
103         gnutls_x509_ext_st *exts;
104         unsigned exts_size;
105         unsigned int obj_flags = flags;
106
107         pkcs11_common(info);
108
109         FIX(url, outfile, detailed, info);
110
111         gnutls_pkcs11_token_get_flags(url, &flags);
112         if (flags & GNUTLS_PKCS11_TOKEN_TRUSTED)
113                 print_exts = 1;
114
115         if (type == PKCS11_TYPE_TRUSTED) {
116                 attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED;
117         } else if (type == PKCS11_TYPE_PK) {
118                 attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY;
119         } else if (type == PKCS11_TYPE_CRT_ALL) {
120                 attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL;
121                 if (print_exts != 0) print_exts++;
122         } else if (type == PKCS11_TYPE_PRIVKEY) {
123                 attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY;
124         } else if (type == PKCS11_TYPE_INFO) {
125                 attrs = GNUTLS_PKCS11_OBJ_ATTR_MATCH;
126         } else {
127                 attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL;
128         }
129
130         /* give some initial value to avoid asking for the pkcs11 pin twice.
131          */
132         ret =
133             gnutls_pkcs11_obj_list_import_url2(&crt_list, &crt_list_size,
134                                                url, attrs, obj_flags);
135         if (ret < 0) {
136                 fprintf(stderr, "Error in crt_list_import (1): %s\n",
137                         gnutls_strerror(ret));
138                 exit(1);
139         }
140
141         if (crt_list_size == 0) {
142                 fprintf(stderr, "No matching objects found\n");
143                 exit(2);
144         }
145
146         for (i = 0; i < crt_list_size; i++) {
147                 char buf[128];
148                 size_t size;
149                 unsigned int oflags;
150
151                 ret =
152                     gnutls_pkcs11_obj_export_url(crt_list[i], detailed,
153                                                  &output);
154                 if (ret < 0) {
155                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
156                                 __LINE__, gnutls_strerror(ret));
157                         exit(1);
158                 }
159
160                 if (info->only_urls) {
161                         fprintf(outfile, "%s\n", output);
162                         gnutls_free(output);
163                         continue;
164                 } else {
165                         fprintf(outfile, "Object %d:\n\tURL: %s\n", i, output);
166                         gnutls_free(output);
167                 }
168
169                 otype = gnutls_pkcs11_obj_get_type(crt_list[i]);
170                 fprintf(outfile, "\tType: %s\n",
171                         gnutls_pkcs11_type_get_name(otype));
172
173                 size = sizeof(buf);
174                 ret =
175                     gnutls_pkcs11_obj_get_info(crt_list[i],
176                                                GNUTLS_PKCS11_OBJ_LABEL,
177                                                buf, &size);
178                 if (ret < 0) {
179                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
180                                 __LINE__, gnutls_strerror(ret));
181                         exit(1);
182                 }
183                 fprintf(outfile, "\tLabel: %s\n", buf);
184
185                 oflags = 0;
186                 ret = gnutls_pkcs11_obj_get_flags(crt_list[i], &oflags);
187                 if (ret < 0) {
188                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
189                                 __LINE__, gnutls_strerror(ret));
190                         exit(1);
191                 }
192                 str = gnutls_pkcs11_obj_flags_get_str(oflags);
193                 if (str != NULL) {
194                         fprintf(outfile, "\tFlags: %s\n", str);
195                         gnutls_free(str);
196                 }
197
198                 size = sizeof(buf);
199                 ret =
200                     gnutls_pkcs11_obj_get_info(crt_list[i],
201                                                GNUTLS_PKCS11_OBJ_ID_HEX,
202                                                buf, &size);
203                 if (ret < 0) {
204                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
205                                 __LINE__, gnutls_strerror(ret));
206                         exit(1);
207                 }
208                 fprintf(outfile, "\tID: %s\n", buf);
209
210                 if (otype == GNUTLS_PKCS11_OBJ_X509_CRT && print_exts > 0) {
211                         ret = gnutls_pkcs11_obj_get_exts(crt_list[i], &exts, &exts_size, 0);
212                         if (ret >= 0 && exts_size > 0) {
213                                 gnutls_datum_t txt;
214
215                                 if (print_exts > 1) {
216                                         fprintf(outfile, "\tAttached extensions:\n");
217                                         ret = gnutls_x509_ext_print(exts, exts_size, 0, &txt);
218                                         if (ret >= 0) {
219                                                 fprintf(outfile, "%s", (char*)txt.data);
220                                                 gnutls_free(txt.data);
221                                         }
222                                 } else {
223                                         fprintf(outfile, "\tAttached extensions:");
224                                         for (j=0;j<exts_size;j++) {
225                                                 fprintf(outfile, "%s%s", exts[j].oid, (j!=exts_size-1)?",":" ");
226                                         }
227                                 }
228                                 for (j=0;j<exts_size;j++) {
229                                         gnutls_x509_ext_deinit(&exts[j]);
230                                 }
231                                 gnutls_free(exts);
232                                 fprintf(outfile, "\n");
233                         }
234                 }
235
236                 fprintf(outfile, "\n");
237         }
238
239         return;
240 }
241
242 #define TEST_DATA "Test data to sign"
243
244 void
245 pkcs11_test_sign(FILE * outfile, const char *url, unsigned int flags,
246             common_info_st * info)
247 {
248         gnutls_privkey_t privkey;
249         gnutls_pubkey_t pubkey;
250         int ret;
251         gnutls_datum_t data, sig = {NULL, 0};
252         int pk;
253
254         pkcs11_common(info);
255
256         FIX(url, outfile, 0, info);
257
258         data.data = (void*)TEST_DATA;
259         data.size = sizeof(TEST_DATA)-1;
260
261         ret = gnutls_privkey_init(&privkey);
262         if (ret < 0) {
263                 fprintf(stderr, "Error in %s:%d: %s\n", __func__,
264                         __LINE__, gnutls_strerror(ret));
265                 exit(1);
266         }
267
268         ret = gnutls_pubkey_init(&pubkey);
269         if (ret < 0) {
270                 fprintf(stderr, "Error in %s:%d: %s\n", __func__,
271                         __LINE__, gnutls_strerror(ret));
272                 exit(1);
273         }
274
275         ret = gnutls_privkey_import_url(privkey, url, flags);
276         if (ret < 0) {
277                 fprintf(stderr, "Cannot import private key: %s\n",
278                         gnutls_strerror(ret));
279                 exit(1);
280         }
281
282         ret = gnutls_pubkey_import_privkey(pubkey, privkey, GNUTLS_KEY_DIGITAL_SIGNATURE, flags);
283         if (ret < 0) {
284                 fprintf(stderr, "Cannot import public key: %s\n",
285                         gnutls_strerror(ret));
286                 exit(1);
287         }
288
289         ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, &data, &sig);
290         if (ret < 0) {
291                 fprintf(stderr, "Cannot sign data: %s\n",
292                         gnutls_strerror(ret));
293                 exit(1);
294         }
295
296         pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);
297
298         fprintf(stderr, "Verifying against private key parameters... ");
299         ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA1),
300                 0, &data, &sig);
301         if (ret < 0) {
302                 fprintf(stderr, "Cannot verify signed data: %s\n",
303                         gnutls_strerror(ret));
304                 exit(1);
305         }
306
307         fprintf(stderr, "ok\n");
308
309         /* now try to verify against a public key within the token */
310         gnutls_pubkey_deinit(pubkey);
311         ret = gnutls_pubkey_init(&pubkey);
312         if (ret < 0) {
313                 fprintf(stderr, "Error in %s:%d: %s\n", __func__,
314                         __LINE__, gnutls_strerror(ret));
315                 exit(1);
316         }
317
318         ret = gnutls_pubkey_import_url(pubkey, url, flags);
319         if (ret < 0) {
320                 fprintf(stderr, "Cannot find a corresponding public key object in token: %s\n",
321                         gnutls_strerror(ret));
322                 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
323                         exit(0);
324                 exit(1);
325         }
326
327         fprintf(stderr, "Verifying against public key in the token... ");
328         ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA1),
329                 0, &data, &sig);
330         if (ret < 0) {
331                 fprintf(stderr, "Cannot verify signed data: %s\n",
332                         gnutls_strerror(ret));
333                 exit(1);
334         }
335
336         fprintf(stderr, "ok\n");
337
338         gnutls_free(sig.data);
339         gnutls_pubkey_deinit(pubkey);
340         gnutls_privkey_deinit(privkey);
341 }
342
343 void
344 pkcs11_export(FILE * outfile, const char *url, unsigned int flags,
345               common_info_st * info)
346 {
347         gnutls_pkcs11_obj_t obj;
348         gnutls_datum_t t;
349         int ret;
350         unsigned int obj_flags = flags;
351
352         pkcs11_common(info);
353
354         FIX(url, outfile, 0, info);
355
356         ret = gnutls_pkcs11_obj_init(&obj);
357         if (ret < 0) {
358                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
359                         gnutls_strerror(ret));
360                 exit(1);
361         }
362
363         ret = gnutls_pkcs11_obj_import_url(obj, url, obj_flags);
364         if (ret < 0) {
365                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
366                         gnutls_strerror(ret));
367                 exit(1);
368         }
369
370         ret = gnutls_pkcs11_obj_export3(obj, info->outcert_format, &t);
371         if (ret < 0) {
372                 fprintf(stderr, "Error in %s:%d: %s\n", __func__,
373                                 __LINE__, gnutls_strerror(ret));
374                 exit(1);
375         }
376
377         fwrite(t.data, 1, t.size, outfile);
378         gnutls_free(t.data);
379
380         if (info->outcert_format == GNUTLS_X509_FMT_PEM)
381                 fputs("\n\n", outfile);
382
383         gnutls_pkcs11_obj_deinit(obj);
384
385         return;
386 }
387
388 void
389 pkcs11_export_chain(FILE * outfile, const char *url, unsigned int flags,
390               common_info_st * info)
391 {
392         gnutls_pkcs11_obj_t obj;
393         gnutls_x509_crt_t xcrt;
394         gnutls_datum_t t;
395         int ret;
396         unsigned int obj_flags = flags;
397
398         pkcs11_common(info);
399
400         FIX(url, outfile, 0, info);
401
402         ret = gnutls_pkcs11_obj_init(&obj);
403         if (ret < 0) {
404                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
405                         gnutls_strerror(ret));
406                 exit(1);
407         }
408
409         ret = gnutls_pkcs11_obj_import_url(obj, url, obj_flags);
410         if (ret < 0) {
411                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
412                         gnutls_strerror(ret));
413                 exit(1);
414         }
415
416         /* make a crt */
417         ret = gnutls_x509_crt_init(&xcrt);
418         if (ret < 0) {
419                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
420                         gnutls_strerror(ret));
421                 exit(1);
422         }
423
424         ret = gnutls_x509_crt_import_pkcs11(xcrt, obj);
425         if (ret < 0) {
426                 fprintf(stderr, "Error in %s:%d: %s\n", __func__,
427                                 __LINE__, gnutls_strerror(ret));
428                 exit(1);
429         }
430
431         ret = gnutls_pkcs11_obj_export3(obj, GNUTLS_X509_FMT_PEM, &t);
432         if (ret < 0) {
433                 fprintf(stderr, "Error in %s:%d: %s\n", __func__,
434                                 __LINE__, gnutls_strerror(ret));
435                 exit(1);
436         }
437         fwrite(t.data, 1, t.size, outfile);
438         fputs("\n\n", outfile);
439         gnutls_free(t.data);
440
441         gnutls_pkcs11_obj_deinit(obj);
442         
443         do {
444                 ret = gnutls_pkcs11_get_raw_issuer(url, xcrt, &t, GNUTLS_X509_FMT_PEM, 0);
445                 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
446                         break;
447                 if (ret < 0) {
448                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
449                                         __LINE__, gnutls_strerror(ret));
450                         exit(1);
451                 }
452                 
453                 fwrite(t.data, 1, t.size, outfile);
454                 fputs("\n\n", outfile);
455
456                 gnutls_x509_crt_deinit(xcrt);
457
458                 ret = gnutls_x509_crt_init(&xcrt);
459                 if (ret < 0) {
460                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
461                                         __LINE__, gnutls_strerror(ret));
462                         exit(1);
463                 }
464
465                 ret = gnutls_x509_crt_import(xcrt, &t, GNUTLS_X509_FMT_PEM);
466                 if (ret < 0) {
467                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
468                                         __LINE__, gnutls_strerror(ret));
469                         exit(1);
470                 }
471
472                 gnutls_free(t.data);
473                 
474                 ret = gnutls_x509_crt_check_issuer(xcrt, xcrt);
475                 if (ret != 0) {
476                         /* self signed */
477                         break;
478                 }
479                 
480         } while(1);
481         
482         return;
483 }
484
485 /* If there is a single token only present, return its URL.
486  */
487 static
488 char *get_single_token_url(common_info_st * info)
489 {
490         int ret;
491         char *url = NULL, *t = NULL;
492
493         pkcs11_common(info);
494
495         ret = gnutls_pkcs11_token_get_url(0, 0, &url);
496         if (ret < 0)
497                 return NULL;
498
499         ret = gnutls_pkcs11_token_get_url(1, 0, &t);
500         if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
501                 gnutls_free(url);
502                 gnutls_free(t);
503                 return NULL;
504         }
505
506         return url;
507 }
508
509 static
510 void print_type(FILE *outfile, unsigned flags)
511 {
512         unsigned print = 0;
513
514         fputs("\tType: ", outfile);
515         if (flags & GNUTLS_PKCS11_TOKEN_HW) {
516                 fputs("Hardware token", outfile);
517                 print++;
518         }
519
520         if (flags & GNUTLS_PKCS11_TOKEN_TRUSTED) {
521                 if (print != 0)
522                         fputs(", ", outfile);
523                 fputs("Trust module", outfile);
524                 print++;
525         }
526
527         if (print == 0)
528                 fputs("Generic token", outfile);
529         fputc('\n', outfile);
530 }
531
532 void
533 pkcs11_token_list(FILE * outfile, unsigned int detailed,
534                   common_info_st * info, unsigned brief)
535 {
536         int ret;
537         int i;
538         char *url;
539         char buf[128];
540         size_t size;
541         unsigned flags;
542
543         pkcs11_common(info);
544
545         for (i = 0;; i++) {
546                 ret = gnutls_pkcs11_token_get_url(i, detailed, &url);
547                 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
548                         break;
549
550                 if (ret < 0) {
551                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
552                                 __LINE__, gnutls_strerror(ret));
553                         exit(1);
554                 }
555
556                 if (brief != 0) {
557                         fprintf(outfile, "%s\n", url);
558                         goto cont;
559                 } else {
560                         fprintf(outfile, "Token %d:\n\tURL: %s\n", i, url);
561                 }
562
563                 size = sizeof(buf);
564                 ret =
565                     gnutls_pkcs11_token_get_info(url,
566                                                  GNUTLS_PKCS11_TOKEN_LABEL,
567                                                  buf, &size);
568                 if (ret < 0) {
569                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
570                                 __LINE__, gnutls_strerror(ret));
571                         exit(1);
572                 }
573
574                 fprintf(outfile, "\tLabel: %s\n", buf);
575
576                 ret = gnutls_pkcs11_token_get_flags(url, &flags);
577                 if (ret < 0) {
578                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
579                                 __LINE__, gnutls_strerror(ret));
580                 } else {
581                         print_type(outfile, flags);
582                 }
583
584                 size = sizeof(buf);
585                 ret =
586                     gnutls_pkcs11_token_get_info(url,
587                                                  GNUTLS_PKCS11_TOKEN_MANUFACTURER,
588                                                  buf, &size);
589                 if (ret < 0) {
590                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
591                                 __LINE__, gnutls_strerror(ret));
592                         exit(1);
593                 }
594
595                 fprintf(outfile, "\tManufacturer: %s\n", buf);
596
597                 size = sizeof(buf);
598                 ret =
599                     gnutls_pkcs11_token_get_info(url,
600                                                  GNUTLS_PKCS11_TOKEN_MODEL,
601                                                  buf, &size);
602                 if (ret < 0) {
603                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
604                                 __LINE__, gnutls_strerror(ret));
605                         exit(1);
606                 }
607
608                 fprintf(outfile, "\tModel: %s\n", buf);
609
610                 size = sizeof(buf);
611                 ret =
612                     gnutls_pkcs11_token_get_info(url,
613                                                  GNUTLS_PKCS11_TOKEN_SERIAL,
614                                                  buf, &size);
615                 if (ret < 0) {
616                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
617                                 __LINE__, gnutls_strerror(ret));
618                         exit(1);
619                 }
620
621                 fprintf(outfile, "\tSerial: %s\n", buf);
622
623                 size = sizeof(buf);
624                 ret =
625                     gnutls_pkcs11_token_get_info(url,
626                                                  GNUTLS_PKCS11_TOKEN_MODNAME,
627                                                  buf, &size);
628                 if (ret >= 0) {
629                         fprintf(outfile, "\tModule: %s\n", buf);
630                 }
631                 fprintf(outfile, "\n\n");
632  cont:
633                 gnutls_free(url);
634
635         }
636
637         return;
638 }
639
640 void
641 pkcs11_write(FILE * outfile, const char *url, const char *label,
642              const char *id, unsigned flags, common_info_st * info)
643 {
644         gnutls_x509_crt_t xcrt;
645         gnutls_x509_privkey_t xkey;
646         gnutls_pubkey_t xpubkey;
647         int ret;
648         gnutls_datum_t *secret_key;
649         unsigned key_usage = 0;
650         unsigned char raw_id[128];
651         size_t raw_id_size;
652         gnutls_datum_t cid = {NULL, 0};
653
654         pkcs11_common(info);
655
656         FIX(url, outfile, 0, info);
657         CHECK_LOGIN_FLAG(flags);
658
659         if (label == NULL && info->batch == 0) {
660                 label = read_str("warning: The object's label was not specified.\nLabel: ");
661         }
662
663         if (id != NULL) {
664                 raw_id_size = sizeof(raw_id);
665                 ret = gnutls_hex2bin(id, strlen(id), raw_id, &raw_id_size);
666                 if (ret < 0) {
667                         fprintf(stderr, "Error converting hex: %s\n", gnutls_strerror(ret));
668                         exit(1);
669                 }
670                 cid.data = raw_id;
671                 cid.size = raw_id_size;
672         }
673
674         secret_key = load_secret_key(0, info);
675         if (secret_key != NULL) {
676                 ret =
677                     gnutls_pkcs11_copy_secret_key(url, secret_key, label,
678                                                   info->key_usage,
679                                                   flags |
680                                                   GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE);
681                 if (ret < 0) {
682                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
683                                 __LINE__, gnutls_strerror(ret));
684                         exit(1);
685                 }
686         }
687
688         xcrt = load_cert(0, info);
689         if (xcrt != NULL) {
690                 ret = gnutls_pkcs11_copy_x509_crt2(url, xcrt, label, &cid, flags);
691                 if (ret < 0) {
692                         fprintf(stderr, "Error writing certificate: %s\n", gnutls_strerror(ret));
693                         if (((flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_CA) ||
694                              (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED)) && 
695                             (flags & GNUTLS_PKCS11_OBJ_FLAG_LOGIN_SO) == 0)
696                                 fprintf(stderr, "note: some tokens may require security officer login for this operation\n");
697                         exit(1);
698                 }
699
700                 gnutls_x509_crt_get_key_usage(xcrt, &key_usage, NULL);
701         }
702
703         xkey = load_x509_private_key(0, info);
704         if (xkey != NULL) {
705                 ret =
706                     gnutls_pkcs11_copy_x509_privkey2(url, xkey, label,
707                                                      &cid, key_usage|info->key_usage,
708                                                      flags |
709                                                      GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE);
710                 if (ret < 0) {
711                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
712                                 __LINE__, gnutls_strerror(ret));
713                         exit(1);
714                 }
715         }
716
717         xpubkey = load_pubkey(0, info);
718         if (xpubkey != NULL) {
719                 ret =
720                     gnutls_pkcs11_copy_pubkey(url, xpubkey, label,
721                                                      &cid,
722                                                      0, flags);
723                 if (ret < 0) {
724                         fprintf(stderr, "Error in %s:%d: %s\n", __func__,
725                                 __LINE__, gnutls_strerror(ret));
726                         exit(1);
727                 }
728         }
729
730         if (xkey == NULL && xcrt == NULL && secret_key == NULL && xpubkey == NULL) {
731                 fprintf(stderr,
732                         "You must use --load-privkey, --load-certificate, --load-pubkey or --secret-key to load the file to be copied\n");
733                 exit(1);
734         }
735
736         return;
737 }
738
739 void
740 pkcs11_generate(FILE * outfile, const char *url, gnutls_pk_algorithm_t pk,
741                 unsigned int bits,
742                 const char *label, const char *id, int detailed,
743                 unsigned int flags, common_info_st * info)
744 {
745         int ret;
746         gnutls_datum_t pubkey;
747         gnutls_datum_t cid = {NULL, 0};
748         unsigned char raw_id[128];
749         size_t raw_id_size;
750
751         pkcs11_common(info);
752
753         FIX(url, outfile, detailed, info);
754         CHECK_LOGIN_FLAG(flags);
755
756         if (id != NULL) {
757                 raw_id_size = sizeof(raw_id);
758                 ret = gnutls_hex2bin(id, strlen(id), raw_id, &raw_id_size);
759                 if (ret < 0) {
760                         fprintf(stderr, "Error converting hex: %s\n", gnutls_strerror(ret));
761                         exit(1);
762                 }
763                 cid.data = raw_id;
764                 cid.size = raw_id_size;
765         }
766
767         if (outfile == stderr || outfile == stdout) {
768                 fprintf(stderr, "warning: no --outfile was specified and the generated public key will be printed on screen.\n");
769         }
770
771         if (label == NULL && info->batch == 0) {
772                 label = read_str("warning: Label was not specified.\nLabel: ");
773         }
774
775         ret =
776             gnutls_pkcs11_privkey_generate3(url, pk, bits, label, &cid,
777                                             GNUTLS_X509_FMT_PEM, &pubkey,
778                                             info->key_usage,
779                                             flags);
780         if (ret < 0) {
781                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
782                         gnutls_strerror(ret));
783                 if (bits != 1024 && pk == GNUTLS_PK_RSA)
784                         fprintf(stderr,
785                                 "note: several smart cards do not support arbitrary size keys; try --bits 1024 or 2048.\n");
786                 exit(1);
787         }
788
789         fwrite(pubkey.data, 1, pubkey.size, outfile);
790         gnutls_free(pubkey.data);
791
792         return;
793 }
794
795 void
796 pkcs11_export_pubkey(FILE * outfile, const char *url, int detailed, unsigned int flags, common_info_st * info)
797 {
798         int ret;
799         gnutls_datum_t pubkey;
800         gnutls_pkcs11_privkey_t pkey;
801
802         pkcs11_common(info);
803
804         FIX(url, outfile, detailed, info);
805         CHECK_LOGIN_FLAG(flags);
806
807         if (outfile == stderr || outfile == stdout) {
808                 fprintf(stderr, "warning: no --outfile was specified and the public key will be printed on screen.\n");
809                 sleep(3);
810         }
811
812         ret = gnutls_pkcs11_privkey_init(&pkey);
813         if (ret < 0) {
814                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
815                         gnutls_strerror(ret));
816                 exit(1);
817         }
818
819         ret = gnutls_pkcs11_privkey_import_url(pkey, url, 0);
820         if (ret < 0) {
821                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
822                         gnutls_strerror(ret));
823                 exit(1);
824         }
825
826         ret =
827             gnutls_pkcs11_privkey_export_pubkey(pkey,
828                                                 GNUTLS_X509_FMT_PEM, &pubkey,
829                                                 flags);
830         if (ret < 0) {
831                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
832                         gnutls_strerror(ret));
833                 exit(1);
834         }
835         gnutls_pkcs11_privkey_deinit(pkey);
836
837         fwrite(pubkey.data, 1, pubkey.size, outfile);
838         gnutls_free(pubkey.data);
839
840         return;
841 }
842
843 void
844 pkcs11_init(FILE * outfile, const char *url, const char *label,
845             common_info_st * info)
846 {
847         int ret;
848         const char *pin;
849         char so_pin[32];
850
851         pkcs11_common(info);
852
853         if (url == NULL) {
854                 fprintf(stderr, "error: no token URL given to initialize!\n");
855                 exit(1);
856         }
857
858         if (info->so_pin != NULL)
859                 pin = info->so_pin;
860         else {
861                 pin = getenv("GNUTLS_SO_PIN");
862                 if (pin == NULL && info->batch == 0)
863                         pin = getpass("Enter Security Officer's PIN: ");
864                 if (pin == NULL)
865                         exit(1);
866         }
867
868         if (strlen(pin) >= sizeof(so_pin) || pin[0] == '\n')
869                 exit(1);
870
871         strcpy(so_pin, pin);
872
873         if (info->so_pin != NULL) {
874                 pin = info->pin;
875         } else {
876                 pin = getenv("GNUTLS_PIN");
877                 if (pin == NULL && info->batch == 0)
878                         pin = getpass("Enter new User's PIN: ");
879                 if (pin == NULL)
880                         exit(1);
881         }
882
883         if (pin[0] == '\n')
884                 exit(1);
885
886         ret = gnutls_pkcs11_token_init(url, so_pin, label);
887         if (ret < 0) {
888                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
889                         gnutls_strerror(ret));
890                 exit(1);
891         }
892
893         ret = gnutls_pkcs11_token_set_pin(url, NULL, pin, GNUTLS_PIN_USER);
894         if (ret < 0) {
895                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
896                         gnutls_strerror(ret));
897                 exit(1);
898         }
899
900         return;
901 }
902
903 const char *mech_list[] = {
904         [0] = "CKM_RSA_PKCS_KEY_PAIR_GEN",
905         [1] = "CKM_RSA_PKCS",
906         [2] = "CKM_RSA_9796",
907         [3] = "CKM_RSA_X_509",
908         [4] = "CKM_MD2_RSA_PKCS",
909         [5] = "CKM_MD5_RSA_PKCS",
910         [6] = "CKM_SHA1_RSA_PKCS",
911         [7] = "CKM_RIPEMD128_RSA_PKCS",
912         [8] = "CKM_RIPEMD160_RSA_PKCS",
913         [9] = "CKM_RSA_PKCS_OAEP",
914         [0xa] = "CKM_RSA_X9_31_KEY_PAIR_GEN",
915         [0xb] = "CKM_RSA_X9_31",
916         [0xc] = "CKM_SHA1_RSA_X9_31",
917         [0xd] = "CKM_RSA_PKCS_PSS",
918         [0xe] = "CKM_SHA1_RSA_PKCS_PSS",
919         [0x10] = "CKM_DSA_KEY_PAIR_GEN",
920         [0x11] = "CKM_DSA",
921         [0x12] = "CKM_DSA_SHA1",
922         [0x20] = "CKM_DH_PKCS_KEY_PAIR_GEN",
923         [0x21] = "CKM_DH_PKCS_DERIVE",
924         [0x30] = "CKM_X9_42_DH_KEY_PAIR_GEN",
925         [0x31] = "CKM_X9_42_DH_DERIVE",
926         [0x32] = "CKM_X9_42_DH_HYBRID_DERIVE",
927         [0x33] = "CKM_X9_42_MQV_DERIVE",
928         [0x40] = "CKM_SHA256_RSA_PKCS",
929         [0x41] = "CKM_SHA384_RSA_PKCS",
930         [0x42] = "CKM_SHA512_RSA_PKCS",
931         [0x43] = "CKM_SHA256_RSA_PKCS_PSS",
932         [0x44] = "CKM_SHA384_RSA_PKCS_PSS",
933         [0x45] = "CKM_SHA512_RSA_PKCS_PSS",
934         [0x100] = "CKM_RC2_KEY_GEN",
935         [0x101] = "CKM_RC2_ECB",
936         [0x102] = "CKM_RC2_CBC",
937         [0x103] = "CKM_RC2_MAC",
938         [0x104] = "CKM_RC2_MAC_GENERAL",
939         [0x105] = "CKM_RC2_CBC_PAD",
940         [0x110] = "CKM_RC4_KEY_GEN",
941         [0x111] = "CKM_RC4",
942         [0x120] = "CKM_DES_KEY_GEN",
943         [0x121] = "CKM_DES_ECB",
944         [0x122] = "CKM_DES_CBC",
945         [0x123] = "CKM_DES_MAC",
946         [0x124] = "CKM_DES_MAC_GENERAL",
947         [0x125] = "CKM_DES_CBC_PAD",
948         [0x130] = "CKM_DES2_KEY_GEN",
949         [0x131] = "CKM_DES3_KEY_GEN",
950         [0x132] = "CKM_DES3_ECB",
951         [0x133] = "CKM_DES3_CBC",
952         [0x134] = "CKM_DES3_MAC",
953         [0x135] = "CKM_DES3_MAC_GENERAL",
954         [0x136] = "CKM_DES3_CBC_PAD",
955         [0x140] = "CKM_CDMF_KEY_GEN",
956         [0x141] = "CKM_CDMF_ECB",
957         [0x142] = "CKM_CDMF_CBC",
958         [0x143] = "CKM_CDMF_MAC",
959         [0x144] = "CKM_CDMF_MAC_GENERAL",
960         [0x145] = "CKM_CDMF_CBC_PAD",
961         [0x200] = "CKM_MD2",
962         [0x201] = "CKM_MD2_HMAC",
963         [0x202] = "CKM_MD2_HMAC_GENERAL",
964         [0x210] = "CKM_MD5",
965         [0x211] = "CKM_MD5_HMAC",
966         [0x212] = "CKM_MD5_HMAC_GENERAL",
967         [0x220] = "CKM_SHA_1",
968         [0x221] = "CKM_SHA_1_HMAC",
969         [0x222] = "CKM_SHA_1_HMAC_GENERAL",
970         [0x230] = "CKM_RIPEMD128",
971         [0x231] = "CKM_RIPEMD128_HMAC",
972         [0x232] = "CKM_RIPEMD128_HMAC_GENERAL",
973         [0x240] = "CKM_RIPEMD160",
974         [0x241] = "CKM_RIPEMD160_HMAC",
975         [0x242] = "CKM_RIPEMD160_HMAC_GENERAL",
976         [0x250] = "CKM_SHA256",
977         [0x251] = "CKM_SHA256_HMAC",
978         [0x252] = "CKM_SHA256_HMAC_GENERAL",
979         [0x260] = "CKM_SHA384",
980         [0x261] = "CKM_SHA384_HMAC",
981         [0x262] = "CKM_SHA384_HMAC_GENERAL",
982         [0x270] = "CKM_SHA512",
983         [0x271] = "CKM_SHA512_HMAC",
984         [0x272] = "CKM_SHA512_HMAC_GENERAL",
985         [0x300] = "CKM_CAST_KEY_GEN",
986         [0x301] = "CKM_CAST_ECB",
987         [0x302] = "CKM_CAST_CBC",
988         [0x303] = "CKM_CAST_MAC",
989         [0x304] = "CKM_CAST_MAC_GENERAL",
990         [0x305] = "CKM_CAST_CBC_PAD",
991         [0x310] = "CKM_CAST3_KEY_GEN",
992         [0x311] = "CKM_CAST3_ECB",
993         [0x312] = "CKM_CAST3_CBC",
994         [0x313] = "CKM_CAST3_MAC",
995         [0x314] = "CKM_CAST3_MAC_GENERAL",
996         [0x315] = "CKM_CAST3_CBC_PAD",
997         [0x320] = "CKM_CAST128_KEY_GEN",
998         [0x321] = "CKM_CAST128_ECB",
999         [0x322] = "CKM_CAST128_CBC",
1000         [0x323] = "CKM_CAST128_MAC",
1001         [0x324] = "CKM_CAST128_MAC_GENERAL",
1002         [0x325] = "CKM_CAST128_CBC_PAD",
1003         [0x330] = "CKM_RC5_KEY_GEN",
1004         [0x331] = "CKM_RC5_ECB",
1005         [0x332] = "CKM_RC5_CBC",
1006         [0x333] = "CKM_RC5_MAC",
1007         [0x334] = "CKM_RC5_MAC_GENERAL",
1008         [0x335] = "CKM_RC5_CBC_PAD",
1009         [0x340] = "CKM_IDEA_KEY_GEN",
1010         [0x341] = "CKM_IDEA_ECB",
1011         [0x342] = "CKM_IDEA_CBC",
1012         [0x343] = "CKM_IDEA_MAC",
1013         [0x344] = "CKM_IDEA_MAC_GENERAL",
1014         [0x345] = "CKM_IDEA_CBC_PAD",
1015         [0x350] = "CKM_GENERIC_SECRET_KEY_GEN",
1016         [0x360] = "CKM_CONCATENATE_BASE_AND_KEY",
1017         [0x362] = "CKM_CONCATENATE_BASE_AND_DATA",
1018         [0x363] = "CKM_CONCATENATE_DATA_AND_BASE",
1019         [0x364] = "CKM_XOR_BASE_AND_DATA",
1020         [0x365] = "CKM_EXTRACT_KEY_FROM_KEY",
1021         [0x370] = "CKM_SSL3_PRE_MASTER_KEY_GEN",
1022         [0x371] = "CKM_SSL3_MASTER_KEY_DERIVE",
1023         [0x372] = "CKM_SSL3_KEY_AND_MAC_DERIVE",
1024         [0x373] = "CKM_SSL3_MASTER_KEY_DERIVE_DH",
1025         [0x374] = "CKM_TLS_PRE_MASTER_KEY_GEN",
1026         [0x375] = "CKM_TLS_MASTER_KEY_DERIVE",
1027         [0x376] = "CKM_TLS_KEY_AND_MAC_DERIVE",
1028         [0x377] = "CKM_TLS_MASTER_KEY_DERIVE_DH",
1029         [0x380] = "CKM_SSL3_MD5_MAC",
1030         [0x381] = "CKM_SSL3_SHA1_MAC",
1031         [0x390] = "CKM_MD5_KEY_DERIVATION",
1032         [0x391] = "CKM_MD2_KEY_DERIVATION",
1033         [0x392] = "CKM_SHA1_KEY_DERIVATION",
1034         [0x3a0] = "CKM_PBE_MD2_DES_CBC",
1035         [0x3a1] = "CKM_PBE_MD5_DES_CBC",
1036         [0x3a2] = "CKM_PBE_MD5_CAST_CBC",
1037         [0x3a3] = "CKM_PBE_MD5_CAST3_CBC",
1038         [0x3a4] = "CKM_PBE_MD5_CAST128_CBC",
1039         [0x3a5] = "CKM_PBE_SHA1_CAST128_CBC",
1040         [0x3a6] = "CKM_PBE_SHA1_RC4_128",
1041         [0x3a7] = "CKM_PBE_SHA1_RC4_40",
1042         [0x3a8] = "CKM_PBE_SHA1_DES3_EDE_CBC",
1043         [0x3a9] = "CKM_PBE_SHA1_DES2_EDE_CBC",
1044         [0x3aa] = "CKM_PBE_SHA1_RC2_128_CBC",
1045         [0x3ab] = "CKM_PBE_SHA1_RC2_40_CBC",
1046         [0x3b0] = "CKM_PKCS5_PBKD2",
1047         [0x3c0] = "CKM_PBA_SHA1_WITH_SHA1_HMAC",
1048         [0x400] = "CKM_KEY_WRAP_LYNKS",
1049         [0x401] = "CKM_KEY_WRAP_SET_OAEP",
1050         [0x1000] = "CKM_SKIPJACK_KEY_GEN",
1051         [0x1001] = "CKM_SKIPJACK_ECB64",
1052         [0x1002] = "CKM_SKIPJACK_CBC64",
1053         [0x1003] = "CKM_SKIPJACK_OFB64",
1054         [0x1004] = "CKM_SKIPJACK_CFB64",
1055         [0x1005] = "CKM_SKIPJACK_CFB32",
1056         [0x1006] = "CKM_SKIPJACK_CFB16",
1057         [0x1007] = "CKM_SKIPJACK_CFB8",
1058         [0x1008] = "CKM_SKIPJACK_WRAP",
1059         [0x1009] = "CKM_SKIPJACK_PRIVATE_WRAP",
1060         [0x100a] = "CKM_SKIPJACK_RELAYX",
1061         [0x1010] = "CKM_KEA_KEY_PAIR_GEN",
1062         [0x1011] = "CKM_KEA_KEY_DERIVE",
1063         [0x1020] = "CKM_FORTEZZA_TIMESTAMP",
1064         [0x1030] = "CKM_BATON_KEY_GEN",
1065         [0x1031] = "CKM_BATON_ECB128",
1066         [0x1032] = "CKM_BATON_ECB96",
1067         [0x1033] = "CKM_BATON_CBC128",
1068         [0x1034] = "CKM_BATON_COUNTER",
1069         [0x1035] = "CKM_BATON_SHUFFLE",
1070         [0x1036] = "CKM_BATON_WRAP",
1071         [0x1040] = "CKM_ECDSA_KEY_PAIR_GEN",
1072         [0x1041] = "CKM_ECDSA",
1073         [0x1042] = "CKM_ECDSA_SHA1",
1074         [0x1050] = "CKM_ECDH1_DERIVE",
1075         [0x1051] = "CKM_ECDH1_COFACTOR_DERIVE",
1076         [0x1052] = "CKM_ECMQV_DERIVE",
1077         [0x1060] = "CKM_JUNIPER_KEY_GEN",
1078         [0x1061] = "CKM_JUNIPER_ECB128",
1079         [0x1062] = "CKM_JUNIPER_CBC128",
1080         [0x1063] = "CKM_JUNIPER_COUNTER",
1081         [0x1064] = "CKM_JUNIPER_SHUFFLE",
1082         [0x1065] = "CKM_JUNIPER_WRAP",
1083         [0x1070] = "CKM_FASTHASH",
1084         [0x1080] = "CKM_AES_KEY_GEN",
1085         [0x1081] = "CKM_AES_ECB",
1086         [0x1082] = "CKM_AES_CBC",
1087         [0x1083] = "CKM_AES_MAC",
1088         [0x1084] = "CKM_AES_MAC_GENERAL",
1089         [0x1085] = "CKM_AES_CBC_PAD",
1090         [0x2000] = "CKM_DSA_PARAMETER_GEN",
1091         [0x2001] = "CKM_DH_PKCS_PARAMETER_GEN",
1092         [0x2002] = "CKM_X9_42_DH_PARAMETER_GEN",
1093         [0x1200] = "CKM_GOSTR3410_KEY_PAIR_GEN",
1094         [0x1201] = "CKM_GOSTR3410",
1095         [0x1202] = "CKM_GOSTR3410_WITH_GOSTR3411",
1096         [0x1203] = "CKM_GOSTR3410_KEY_WRAP",
1097         [0x1204] = "CKM_GOSTR3410_DERIVE",
1098         [0x1210] = "CKM_GOSTR3411",
1099         [0x1211] = "CKM_GOSTR3411_HMAC",
1100         [0x255] = "CKM_SHA224",
1101         [0x256] = "CKM_SHA224_HMAC",
1102         [0x257] = "CKM_SHA224_HMAC_GENERAL",
1103         [0x46] = "CKM_SHA224_RSA_PKCS",
1104         [0x47] = "CKM_SHA224_RSA_PKCS_PSS",
1105         [0x396] = "CKM_SHA224_KEY_DERIVATION",
1106         [0x550] = "CKM_CAMELLIA_KEY_GEN",
1107         [0x551] = "CKM_CAMELLIA_ECB",
1108         [0x552] = "CKM_CAMELLIA_CBC",
1109         [0x553] = "CKM_CAMELLIA_MAC",
1110         [0x554] = "CKM_CAMELLIA_MAC_GENERAL",
1111         [0x555] = "CKM_CAMELLIA_CBC_PAD",
1112         [0x556] = "CKM_CAMELLIA_ECB_ENCRYPT_DATA",
1113         [0x557] = "CKM_CAMELLIA_CBC_ENCRYPT_DATA"
1114 };
1115
1116 void
1117 pkcs11_mechanism_list(FILE * outfile, const char *url, unsigned int flags,
1118                       common_info_st * info)
1119 {
1120         int ret;
1121         int idx;
1122         unsigned long mechanism;
1123         const char *str;
1124
1125         pkcs11_common(info);
1126
1127         FIX(url, outfile, 0, info);
1128
1129         idx = 0;
1130         do {
1131                 ret =
1132                     gnutls_pkcs11_token_get_mechanism(url, idx++,
1133                                                       &mechanism);
1134                 if (ret >= 0) {
1135                         str = NULL;
1136                         if (mechanism <=
1137                             sizeof(mech_list) / sizeof(mech_list[0]))
1138                                 str = mech_list[mechanism];
1139                         if (str == NULL)
1140                                 str = "UNKNOWN";
1141
1142                         fprintf(outfile, "[0x%.4lx] %s\n", mechanism, str);
1143                 }
1144         }
1145         while (ret >= 0);
1146
1147
1148         return;
1149 }
1150
1151 void
1152 pkcs11_get_random(FILE * outfile, const char *url, unsigned bytes,
1153                   common_info_st * info)
1154 {
1155         int ret;
1156         uint8_t *output;
1157
1158         pkcs11_common(info);
1159
1160         FIX(url, outfile, 0, info);
1161
1162         output = malloc(bytes);
1163         if (output == NULL) {
1164                 fprintf(stderr, "Memory error\n");
1165                 exit(1);
1166         }
1167
1168         ret = gnutls_pkcs11_token_get_random(url, output, bytes);
1169         if (ret < 0) {
1170                 fprintf(stderr, "gnutls_pkcs11_token_get_random: %s\n",
1171                         gnutls_strerror(ret));
1172                 exit(1);
1173         }
1174
1175         fwrite(output, 1, bytes, outfile);
1176
1177         return;
1178 }
1179
1180 static
1181 void pkcs11_set_val(FILE * outfile, const char *url, int detailed,
1182                    unsigned int flags, common_info_st * info,
1183                    gnutls_pkcs11_obj_info_t val_type, const char *val)
1184 {
1185         int ret;
1186         gnutls_pkcs11_obj_t obj;
1187
1188         pkcs11_common(info);
1189
1190         FIX(url, outfile, detailed, info);
1191         CHECK_LOGIN_FLAG(flags);
1192
1193         ret = gnutls_pkcs11_obj_init(&obj);
1194         if (ret < 0) {
1195                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
1196                         gnutls_strerror(ret));
1197                 exit(1);
1198         }
1199
1200         ret = gnutls_pkcs11_obj_import_url(obj, url, flags);
1201         if (ret < 0) {
1202                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
1203                         gnutls_strerror(ret));
1204                 exit(1);
1205         }
1206
1207         ret =
1208             gnutls_pkcs11_obj_set_info(obj, val_type, val, strlen(val), flags);
1209         if (ret < 0) {
1210                 fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
1211                         gnutls_strerror(ret));
1212                 exit(1);
1213         }
1214         gnutls_pkcs11_obj_deinit(obj);
1215
1216         return;
1217 }
1218
1219 void pkcs11_set_id(FILE * outfile, const char *url, int detailed,
1220                    unsigned int flags, common_info_st * info,
1221                    const char *id)
1222 {
1223         return pkcs11_set_val(outfile, url, detailed, flags, info, GNUTLS_PKCS11_OBJ_ID_HEX, id);
1224 }
1225
1226 void pkcs11_set_label(FILE * outfile, const char *url, int detailed,
1227                    unsigned int flags, common_info_st * info,
1228                    const char *label)
1229 {
1230         return pkcs11_set_val(outfile, url, detailed, flags, info, GNUTLS_PKCS11_OBJ_LABEL, label);
1231 }