1 /*
2 * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
3 * Copyright (c) 2002 Juha Yrjölä. All rights reserved.
4 * Copyright (c) 2001 Markus Friedl.
5 * Copyright (c) 2002 Olaf Kirch
6 * Copyright (c) 2003 Kevin Stefanik
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
29 /*****************************************************************************
30 ChangeLog (01/04/2013):
31 Added following new functionalities
32 - API to list objects on the token
33 - API to store certificate to token
34 - API to generate & store RSA key pair to token
35 - API to get RSA public key from token
36 - API to Delete object from token
37 *****************************************************************************/
39 #include <config.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <openssl/crypto.h>
43 #include <openssl/objects.h>
44 #include <openssl/engine.h>
45 #include <libp11.h>
46 #include "engine_pkcs11.h"
48 #ifdef _WIN32
49 #define strncasecmp strnicmp
50 #endif
52 #define fail(msg) { fprintf(stderr,msg); return NULL;}
54 /** The maximum length of an internally-allocated PIN */
55 #define MAX_PIN_LENGTH 32
57 /* Maximum size of a token object */
58 #define MAX_OBJECT_SIZE 5000
60 struct cert_ctrl_params {
61 int slot_nr;
62 unsigned char *cert_id;
63 size_t cert_id_len;
64 char *cert_label;
65 X509 *cert;
66 };
68 static int do_login(PKCS11_SLOT *slot);
69 static int pkcs11_store_cert
70 (
71 ENGINE * e,
72 int slot_nr,
73 unsigned char *cert_id,
74 size_t cert_id_len,
75 char *cert_label,
76 X509 *x
77 );
78 static int parse_cert_store_string
79 (
80 const char *cert_store_str,
81 int *slot,
82 unsigned char *id,
83 size_t * id_len,
84 char **label,
85 char **cert_file
86 );
87 static int parse_key_gen_string
88 (
89 const char *key_gen_str,
90 int *slot,
91 int *key_size,
92 unsigned char *id,
93 size_t * id_len,
94 char **label
95 );
96 static int pkcs11_gen_key
97 (
98 ENGINE * e,
99 int slot_nr,
100 unsigned int key_size,
101 unsigned char *key_id,
102 size_t key_id_len,
103 char *key_label
104 );
105 static int pkcs11_del_obj
106 (
107 ENGINE * e,
108 int slot_nr,
109 char *type_str,
110 unsigned char *id,
111 size_t id_len,
112 char *label
113 );
114 static int parse_del_obj_string
115 (
116 const char *del_obj_str,
117 int *slot,
118 char **type,
119 unsigned char *id,
120 size_t * id_len,
121 char **label
122 );
123 static int parse_key_string
124 (
125 const char *pubkey_get_str,
126 int *slot,
127 unsigned char *id,
128 size_t * id_len,
129 char **label,
130 char **key_file
131 );
133 static PKCS11_CTX *ctx = NULL;
135 /**
136 * The PIN used for login. Cache for the get_pin function.
137 * The memory for this PIN is always owned internally,
138 * and may be freed as necessary. Before freeing, the PIN
139 * must be whitened, to prevent security holes.
140 */
141 static char *pin = NULL;
142 static int pin_length = 0;
144 static int verbose = 0;
146 static char *module = NULL;
148 static char *init_args = NULL;
150 int set_module(const char *modulename)
151 {
152 module = modulename ? strdup(modulename) : NULL;
153 return 1;
154 }
156 /**
157 * Set the PIN used for login. A copy of the PIN shall be made.
158 *
159 * If the PIN cannot be assigned, the value 0 shall be returned
160 * and errno shall be set as follows:
161 *
162 * EINVAL - a NULL PIN was supplied
163 * ENOMEM - insufficient memory to copy the PIN
164 *
165 * @param _pin the pin to use for login. Must not be NULL.
166 *
167 * @return 1 on success, 0 on failure.
168 */
169 int set_pin(const char *_pin)
170 {
171 /* Pre-condition check */
172 if (_pin == NULL) {
173 errno = EINVAL;
174 return 0;
175 }
177 /* Copy the PIN. If the string cannot be copied, NULL
178 shall be returned and errno shall be set. */
179 pin = strdup(_pin);
180 if (pin != NULL)
181 pin_length = strlen(pin);
183 return (pin != NULL);
184 }
186 int inc_verbose(void)
187 {
188 verbose++;
189 return 1;
190 }
192 /* either get the pin code from the supplied callback data, or get the pin
193 * via asking our self. In both cases keep a copy of the pin code in the
194 * pin variable (strdup'ed copy). */
195 static int get_pin(UI_METHOD * ui_method, void *callback_data)
196 {
197 UI *ui;
198 struct {
199 const void *password;
200 const char *prompt_info;
201 } *mycb = callback_data;
203 /* pin in the call back data, copy and use */
204 if (mycb != NULL && mycb->password) {
205 pin = (char *)calloc(MAX_PIN_LENGTH, sizeof(char));
206 if (!pin)
207 return 0;
208 strncpy(pin,mycb->password,MAX_PIN_LENGTH);
209 pin_length = MAX_PIN_LENGTH;
210 return 1;
211 }
213 /* call ui to ask for a pin */
214 ui = UI_new();
215 if (ui_method != NULL)
216 UI_set_method(ui, ui_method);
217 if (callback_data != NULL)
218 UI_set_app_data(ui, callback_data);
220 if (!UI_add_input_string
221 (ui, "PKCS#11 token PIN: ", 0, pin, 1, MAX_PIN_LENGTH)) {
222 fprintf(stderr, "UI_add_input_string failed\n");
223 UI_free(ui);
224 return 0;
225 }
226 if (UI_process(ui)) {
227 fprintf(stderr, "UI_process failed\n");
228 UI_free(ui);
229 return 0;
230 }
231 UI_free(ui);
232 return 1;
233 }
235 int set_init_args(const char *init_args_orig)
236 {
237 init_args = init_args_orig ? strdup(init_args_orig) : NULL;
238 return 1;
239 }
241 int pkcs11_finish(ENGINE * engine)
242 {
243 if (verbose) {
244 fprintf(stderr, "engine finish\n");
245 }
246 if (ctx) {
247 PKCS11_CTX_unload(ctx);
248 PKCS11_CTX_free(ctx);
249 ctx = NULL;
250 }
251 if (pin != NULL) {
252 OPENSSL_cleanse(pin, pin_length);
253 free(pin);
254 pin = NULL;
255 pin_length = 0;
256 }
257 return 1;
258 }
260 int pkcs11_init(ENGINE * engine)
261 {
262 if (verbose) {
263 fprintf(stderr, "initializing engine\n");
264 }
265 ctx = PKCS11_CTX_new();
266 PKCS11_CTX_init_args(ctx, init_args);
267 if (PKCS11_CTX_load(ctx, module) < 0) {
268 fprintf(stderr, "unable to load module %s\n", module);
269 return 0;
270 }
271 return 1;
272 }
274 int pkcs11_rsa_finish(RSA * rsa)
275 {
276 if (pin) {
277 OPENSSL_cleanse(pin, pin_length);
278 free(pin);
279 pin = NULL;
280 pin_length = 0;
281 }
282 if (module) {
283 free(module);
284 module = NULL;
285 }
286 /* need to free RSA_ex_data? */
287 return 1;
288 }
290 static int hex_to_bin(const char *in, unsigned char *out, size_t * outlen)
291 {
292 size_t left, count = 0;
294 if (in == NULL || *in == '\0') {
295 *outlen = 0;
296 return 1;
297 }
299 left = *outlen;
301 while (*in != '\0') {
302 int byte = 0, nybbles = 2;
304 while (nybbles-- && *in && *in != ':') {
305 char c;
306 byte <<= 4;
307 c = *in++;
308 if ('0' <= c && c <= '9')
309 c -= '0';
310 else if ('a' <= c && c <= 'f')
311 c = c - 'a' + 10;
312 else if ('A' <= c && c <= 'F')
313 c = c - 'A' + 10;
314 else {
315 fprintf(stderr,
316 "hex_to_bin(): invalid char '%c' in hex string\n",
317 c);
318 *outlen = 0;
319 return 0;
320 }
321 byte |= c;
322 }
323 if (*in == ':')
324 in++;
325 if (left <= 0) {
326 fprintf(stderr, "hex_to_bin(): hex string too long\n");
327 *outlen = 0;
328 return 0;
329 }
330 out[count++] = (unsigned char)byte;
331 left--;
332 }
334 *outlen = count;
335 return 1;
336 }
338 /* parse string containing slot and id information */
340 static int parse_slot_id_string(const char *slot_id, int *slot,
341 unsigned char *id, size_t * id_len,
342 char **label)
343 {
344 int n, i;
346 if (!slot_id)
347 return 0;
349 /* support for several formats */
350 #define HEXDIGITS "01234567890ABCDEFabcdef"
351 #define DIGITS "0123456789"
353 /* first: pure hex number (id, slot is 0) */
354 if (strspn(slot_id, HEXDIGITS) == strlen(slot_id)) {
355 /* ah, easiest case: only hex. */
356 if ((strlen(slot_id) + 1) / 2 > *id_len) {
357 fprintf(stderr, "id string too long!\n");
358 return 0;
359 }
360 *slot = 0;
361 return hex_to_bin(slot_id, id, id_len);
362 }
364 /* second: slot:id. slot is an digital int. */
365 if (sscanf(slot_id, "%d", &n) == 1) {
366 i = strspn(slot_id, DIGITS);
368 if (slot_id[i] != ':') {
369 fprintf(stderr, "could not parse string!\n");
370 return 0;
371 }
372 i++;
373 if (slot_id[i] == 0) {
374 *slot = n;
375 *id_len = 0;
376 return 1;
377 }
378 if (strspn(slot_id + i, HEXDIGITS) + i != strlen(slot_id)) {
379 fprintf(stderr, "could not parse string!\n");
380 return 0;
381 }
382 /* ah, rest is hex */
383 if ((strlen(slot_id) - i + 1) / 2 > *id_len) {
384 fprintf(stderr, "id string too long!\n");
385 return 0;
386 }
387 *slot = n;
388 return hex_to_bin(slot_id + i, id, id_len);
389 }
391 /* third: id_<id> */
392 if (strncmp(slot_id, "id_", 3) == 0) {
393 if (strspn(slot_id + 3, HEXDIGITS) + 3 != strlen(slot_id)) {
394 fprintf(stderr, "could not parse string!\n");
395 return 0;
396 }
397 /* ah, rest is hex */
398 if ((strlen(slot_id) - 3 + 1) / 2 > *id_len) {
399 fprintf(stderr, "id string too long!\n");
400 return 0;
401 }
402 *slot = 0;
403 return hex_to_bin(slot_id + 3, id, id_len);
404 }
406 /* label_<label> */
407 if (strncmp(slot_id, "label_", 6) == 0) {
408 *label = strdup(slot_id + 6);
409 return *label != NULL;
410 }
412 /* last try: it has to be slot_<slot> and then "-id_<cert>" */
414 if (strncmp(slot_id, "slot_", 5) != 0) {
415 fprintf(stderr, "format not recognized!\n");
416 return 0;
417 }
419 /* slot is an digital int. */
420 if (sscanf(slot_id + 5, "%d", &n) != 1) {
421 fprintf(stderr, "slot number not deciphered!\n");
422 return 0;
423 }
425 i = strspn(slot_id + 5, DIGITS);
427 if (slot_id[i + 5] == 0) {
428 *slot = n;
429 *id_len = 0;
430 return 1;
431 }
433 if (slot_id[i + 5] != '-') {
434 fprintf(stderr, "could not parse string!\n");
435 return 0;
436 }
438 i = 5 + i + 1;
440 /* now followed by "id_" */
441 if (strncmp(slot_id + i, "id_", 3) == 0) {
442 if (strspn(slot_id + i + 3, HEXDIGITS) + 3 + i !=
443 strlen(slot_id)) {
444 fprintf(stderr, "could not parse string!\n");
445 return 0;
446 }
447 /* ah, rest is hex */
448 if ((strlen(slot_id) - i - 3 + 1) / 2 > *id_len) {
449 fprintf(stderr, "id string too long!\n");
450 return 0;
451 }
452 *slot = n;
453 return hex_to_bin(slot_id + i + 3, id, id_len);
454 }
456 /* ... or "label_" */
457 if (strncmp(slot_id + i, "label_", 6) == 0) {
458 *slot = n;
459 return (*label = strdup(slot_id + i + 6)) != NULL;
460 }
462 fprintf(stderr, "could not parse string!\n");
463 return 0;
464 }
466 #define MAX_VALUE_LEN 200
468 static X509 *pkcs11_load_cert
469 (
470 ENGINE * e,
471 int slot_nr,
472 unsigned char *cert_id,
473 size_t cert_id_len,
474 char *cert_label
475 )
476 {
477 PKCS11_SLOT *slot_list, *slot;
478 PKCS11_SLOT *found_slot = NULL;
479 PKCS11_TOKEN *tok;
480 PKCS11_CERT *certs, *selected_cert = NULL;
481 X509 *x509 = NULL;
482 unsigned int slot_count, cert_count, n, m;
483 char flags[64];
484 int local_init = 0;
486 if (ctx == NULL) {
487 pkcs11_init(e);
488 local_init = 1;
489 }
491 if (PKCS11_enumerate_slots(ctx, &slot_list, &slot_count) < 0)
492 fail("failed to enumerate slots\n");
494 if (verbose) {
495 fprintf(stderr, "Found %u slot%s\n", slot_count,
496 (slot_count <= 1) ? "" : "s");
497 }
499 for (n = 0; n < slot_count; n++) {
500 slot = slot_list + n;
501 flags[0] = '\0';
502 if (slot->token) {
503 if (!slot->token->initialized)
504 strcat(flags, "uninitialized, ");
505 else if (!slot->token->userPinSet)
506 strcat(flags, "no pin, ");
507 if (slot->token->loginRequired)
508 strcat(flags, "login, ");
509 if (slot->token->readOnly)
510 strcat(flags, "ro, ");
511 } else {
512 strcpy(flags, "no token");
513 }
514 if ((m = strlen(flags)) != 0) {
515 flags[m - 2] = '\0';
516 }
518 if (slot_nr != -1 &&
519 slot_nr == PKCS11_get_slotid_from_slot(slot)) {
520 found_slot = slot;
521 }
523 if (verbose) {
524 fprintf(stderr, "[%lu] %-25.25s %-16s",
525 PKCS11_get_slotid_from_slot(slot),
526 slot->description, flags);
527 if (slot->token) {
528 fprintf(stderr, " (%s)",
529 slot->token->label[0] ?
530 slot->token->label : "no label");
531 }
532 fprintf(stderr, "\n");
533 }
534 }
536 if (found_slot) {
537 slot = found_slot;
538 } else {
539 fprintf(stderr, "Invalid slot number: %d\n", (int)slot_nr);
540 goto err_out;
541 }
543 tok = slot->token;
545 if (tok == NULL) {
546 fprintf(stderr, "Found empty token; \n");
547 goto err_out;
548 }
550 if (verbose) {
551 fprintf(stderr, "Found slot: %s\n", slot->description);
552 fprintf(stderr, "Found token: %s\n", slot->token->label);
553 }
555 if ((tok->loginRequired) && (do_login(slot))) {
556 fprintf(stderr, "failed to login\n");
557 goto err_out;
558 }
560 if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) {
561 fprintf(stderr, "unable to enumerate certificates\n");
562 goto err_out;
563 }
565 if (verbose) {
566 fprintf(stderr, "Found %u cert%s:\n", cert_count,
567 (cert_count <= 1) ? "" : "s");
568 }
570 /* Find the matching cert */
571 if (cert_id_len || cert_label) {
572 for (n = 0; n < cert_count; n++) {
573 PKCS11_CERT *k = certs + n;
575 if (cert_label == NULL) {
576 if (cert_id_len != 0 && k->id_len == cert_id_len &&
577 memcmp(k->id, cert_id, cert_id_len) == 0) {
578 selected_cert = k;
579 }
580 } else {
581 if (strcmp(k->label, cert_label) == 0) {
582 selected_cert = k;
583 }
584 }
585 }
586 } else {
587 selected_cert = certs; /* use first */
588 }
590 if (selected_cert == NULL) {
591 fprintf(stderr, "certificate not found.\n");
592 goto err_out;
593 }
595 x509 = X509_dup(selected_cert->x509);
596 goto out;
598 err_out:
599 PKCS11_release_all_slots(ctx, slot_list, slot_count);
601 out:
602 if (local_init) {
603 pkcs11_finish(e);
604 }
605 return x509;
606 }
608 int load_cert_ctrl(ENGINE * e, void *p)
609 {
610 struct cert_ctrl_params *params = p;
612 if (params->cert != NULL)
613 return 0;
615 params->cert = pkcs11_load_cert(e, params->slot_nr, params->cert_id,
616 params->cert_id_len, params->cert_label);
618 if (params->cert == NULL)
619 return 0;
621 return 1;
623 }
625 static EVP_PKEY *pkcs11_load_key
626 (
627 ENGINE * e,
628 int slot_nr,
629 unsigned char *key_id,
630 size_t key_id_len,
631 char *key_label,
632 UI_METHOD * ui_method,
633 void *callback_data,
634 int isPrivate
635 )
636 {
637 PKCS11_SLOT *slot_list, *slot;
638 PKCS11_SLOT *found_slot = NULL;
639 PKCS11_TOKEN *tok;
640 PKCS11_KEY *keys, *selected_key = NULL;
641 PKCS11_CERT *certs;
642 EVP_PKEY *pk = NULL;
643 unsigned int slot_count, cert_count, key_count, n, m;
644 char flags[64];
645 int local_init = 0;
647 if (ctx == NULL) {
648 pkcs11_init(e);
649 local_init = 1;
650 }
652 if (PKCS11_enumerate_slots(ctx, &slot_list, &slot_count) < 0)
653 fail("failed to enumerate slots\n");
655 if (verbose) {
656 fprintf(stderr, "Found %u slot%s\n", slot_count,
657 (slot_count <= 1) ? "" : "s");
658 }
660 for (n = 0; n < slot_count; n++) {
661 slot = slot_list + n;
662 flags[0] = '\0';
663 if (slot->token) {
664 if (!slot->token->initialized)
665 strcat(flags, "uninitialized, ");
666 else if (!slot->token->userPinSet)
667 strcat(flags, "no pin, ");
668 if (slot->token->loginRequired)
669 strcat(flags, "login, ");
670 if (slot->token->readOnly)
671 strcat(flags, "ro, ");
672 } else {
673 strcpy(flags, "no token");
674 }
675 if ((m = strlen(flags)) != 0) {
676 flags[m - 2] = '\0';
677 }
679 if (slot_nr != -1 &&
680 slot_nr == PKCS11_get_slotid_from_slot(slot)) {
681 found_slot = slot;
682 }
684 if (verbose) {
685 fprintf(stderr, "[%lu] %-25.25s %-16s",
686 PKCS11_get_slotid_from_slot(slot),
687 slot->description, flags);
688 if (slot->token) {
689 fprintf(stderr, " (%s)",
690 slot->token->label[0] ?
691 slot->token->label : "no label");
692 }
693 fprintf(stderr, "\n");
694 }
695 }
697 if (slot_nr == -1) {
698 if (!(slot = PKCS11_find_token(ctx, slot_list, slot_count)))
699 fail("didn't find any tokens\n");
700 } else if (found_slot) {
701 slot = found_slot;
702 } else {
703 fprintf(stderr, "Invalid slot number: %d\n", slot_nr);
704 PKCS11_release_all_slots(ctx, slot_list, slot_count);
705 goto out;
706 }
707 tok = slot->token;
709 if (tok == NULL) {
710 fprintf(stderr, "Found empty token; \n");
711 PKCS11_release_all_slots(ctx, slot_list, slot_count);
712 goto out;
713 }
715 if (isPrivate && !tok->userPinSet && !tok->readOnly) {
716 fprintf(stderr, "Found slot without user PIN\n");
717 PKCS11_release_all_slots(ctx, slot_list, slot_count);
718 goto out;
719 }
721 if (verbose) {
722 fprintf(stderr, "Found slot: %s\n", slot->description);
723 fprintf(stderr, "Found token: %s\n", slot->token->label);
724 }
726 #ifdef DEBUG
727 if (PKCS11_enumerate_certs(tok, &certs, &cert_count))
728 fail("unable to enumerate certificates\n");
730 if (verbose) {
731 fprintf(stderr, "Found %u certificate%s:\n", cert_count,
732 (cert_count <= 1) ? "" : "s");
733 for (n = 0; n < cert_count; n++) {
734 PKCS11_CERT *c = certs + n;
735 char *dn = NULL;
737 fprintf(stderr, " %2u %s", n + 1, c->label);
738 if (c->x509)
739 dn = X509_NAME_oneline(X509_get_subject_name
740 (c->x509), NULL, 0);
741 if (dn) {
742 fprintf(stderr, " (%s)", dn);
743 OPENSSL_free(dn);
744 }
745 fprintf(stderr, "\n");
746 }
747 }
748 #endif
750 /* Perform login to the token if required */
751 if (tok->loginRequired) {
752 /* If the token has a secure login (i.e., an external keypad),
753 then use a NULL pin. Otherwise, check if a PIN exists. If
754 not, allocate and obtain a new PIN. */
755 if (tok->secureLogin) {
756 /* Free the PIN if it has already been
757 assigned (i.e, cached by get_pin) */
758 if (pin != NULL) {
759 OPENSSL_cleanse(pin, pin_length);
760 free(pin);
761 pin = NULL;
762 pin_length = 0;
763 }
764 } else if (pin == NULL) {
765 pin = (char *)calloc(MAX_PIN_LENGTH, sizeof(char));
766 pin_length = MAX_PIN_LENGTH;
767 if (pin == NULL) {
768 fail("Could not allocate memory for PIN");
769 }
770 if (!get_pin(ui_method, callback_data) ) {
771 OPENSSL_cleanse(pin, pin_length);
772 free(pin);
773 pin = NULL;
774 pin_length = 0;
775 fail("No pin code was entered");
776 }
777 }
779 /* Now login in with the (possibly NULL) pin */
780 if (PKCS11_login(slot, 0, pin)) {
781 /* Login failed, so free the PIN if present */
782 if (pin != NULL) {
783 OPENSSL_cleanse(pin, pin_length);
784 free(pin);
785 pin = NULL;
786 pin_length = 0;
787 }
788 fail("Login failed\n");
789 }
790 /* Login successful, PIN retained in case further logins are
791 required. This will occur on subsequent calls to the
792 pkcs11_load_key function. Subsequent login calls should be
793 relatively fast (the token should maintain its own login
794 state), although there may still be a slight performance
795 penalty. We could maintain state noting that successful
796 login has been performed, but this state may not be updated
797 if the token is removed and reinserted between calls. It
798 seems safer to retain the PIN and peform a login on each
799 call to pkcs11_load_key, even if this may not be strictly
800 necessary. */
801 /* TODO when does PIN get freed after successful login? */
802 /* TODO confirm that multiple login attempts do not introduce
803 significant performance penalties */
805 }
807 /* Make sure there is at least one private key on the token */
808 if (PKCS11_enumerate_keys(tok, &keys, &key_count)) {
809 fail("unable to enumerate keys\n");
810 }
811 if (key_count == 0) {
812 fail("No keys found.\n");
813 }
815 if (verbose) {
816 fprintf(stderr, "Found %u key%s:\n", key_count,
817 (key_count <= 1) ? "" : "s");
818 }
819 if ((key_id_len != 0) || (key_label != NULL)) {
820 for (n = 0; n < key_count; n++) {
821 PKCS11_KEY *k = keys + n;
823 if (verbose) {
824 fprintf(stderr, " %2u %c%c %s\n", n + 1,
825 k->isPrivate ? 'P' : ' ',
826 k->needLogin ? 'L' : ' ', k->label);
827 }
829 if (!!isPrivate != !!(k->isPrivate)) continue;
831 if (key_label == NULL) {
832 if (key_id_len != 0 && k->id_len == key_id_len
833 && (memcmp(k->id, key_id, key_id_len) == 0)) {
834 selected_key = k;
835 }
836 } else {
837 if (strcmp(k->label, key_label) == 0) {
838 selected_key = k;
839 }
840 }
841 }
842 } else {
843 selected_key = keys; /* use first */
844 }
846 if (selected_key == NULL) {
847 fprintf(stderr, "key not found.\n");
848 goto out;
849 }
851 if (isPrivate) {
852 pk = PKCS11_get_private_key(selected_key);
853 } else {
854 pk = PKCS11_get_public_key(selected_key);
855 }
857 out:
858 if (local_init) {
859 pkcs11_finish(e);
860 }
862 return pk;
863 }
865 EVP_PKEY *pkcs11_load_public_key(ENGINE * e, const char *s_key_id,
866 UI_METHOD * ui_method, void *callback_data)
867 {
868 int n;
869 unsigned char key_id[MAX_VALUE_LEN / 2];
870 size_t key_id_len = sizeof(key_id);
871 char *key_label = NULL;
872 int slot_nr = -1;
873 EVP_PKEY *pk;
875 n = parse_key_string(s_key_id, &slot_nr, key_id, &key_id_len,
876 &key_label, NULL);
877 if (n) {
878 fprintf(stderr,
879 "supported format: slot_<slot>:id_<id>:label_<label>\n");
880 fprintf(stderr,
881 "where <slot> is the slot number as normal integer,\n");
882 fprintf(stderr,
883 "and <id> is the id number as hex string.\n");
884 fprintf(stderr,
885 "and <label> is the textual key label string.\n");
886 return NULL;
887 }
889 pk = pkcs11_load_key(e, slot_nr, key_id, key_id_len, key_label,
890 ui_method, callback_data, 0);
891 if (pk == NULL)
892 fprintf(stderr, "PKCS11_load_public_key returned NULL\n");
894 if (key_label) free(key_label);
895 return pk;
896 }
898 EVP_PKEY *pkcs11_load_private_key(ENGINE * e, const char *s_key_id,
899 UI_METHOD * ui_method, void *callback_data)
900 {
901 int n;
902 unsigned char key_id[MAX_VALUE_LEN / 2];
903 size_t key_id_len = sizeof(key_id);
904 char *key_label = NULL;
905 int slot_nr = -1;
906 EVP_PKEY *pk;
908 n = parse_key_string(s_key_id, &slot_nr, key_id, &key_id_len,
909 &key_label, NULL);
910 if (n) {
911 fprintf(stderr,
912 "supported format: slot_<slot>:id_<id>:label_<label>\n");
913 fprintf(stderr,
914 "where <slot> is the slot number as normal integer,\n");
915 fprintf(stderr,
916 "and <id> is the id number as hex string.\n");
917 fprintf(stderr,
918 "and <label> is the textual key label string.\n");
919 return NULL;
920 }
922 pk = pkcs11_load_key(e, slot_nr, key_id, key_id_len, key_label,
923 ui_method, callback_data, 1);
924 if (pk == NULL)
925 fprintf(stderr, "PKCS11_get_private_key returned NULL\n");
927 if (key_label) free(key_label);
928 return pk;
929 }
931 int list_token_objects
932 (
933 ENGINE * e,
934 long slot_nr /* slot number */
935 )
936 {
937 PKCS11_SLOT *slot_list, *slot, *found_slot = NULL;
938 PKCS11_TOKEN *tok;
939 PKCS11_CERT *certs;
940 PKCS11_KEY *keys;
941 unsigned int slot_count, cert_count, key_count, m, n, i;
942 char flags[64];
943 int local_init = 0;
944 int ret_val = 0;
946 if (verbose) {
947 fprintf(stderr, "Displaying token objects from slot %d\n", (int)slot_nr);
948 }
950 if (ctx == NULL) {
951 pkcs11_init(e);
952 local_init = 1;
953 }
954 if (PKCS11_enumerate_slots(ctx, &slot_list, &slot_count)) {
955 fprintf(stderr, "failed to enumerate slots\n");
956 goto out;
957 }
959 if (verbose) {
960 fprintf(stderr, "Found %u slots\n", slot_count);
961 }
963 for (n = 0; n < slot_count; n++) {
964 slot = slot_list + n;
965 flags[0] = '\0';
966 if (slot->token) {
967 if (!slot->token->initialized)
968 strcat(flags, "uninitialized, ");
969 else if (!slot->token->userPinSet)
970 strcat(flags, "no pin, ");
971 if (slot->token->loginRequired)
972 strcat(flags, "login, ");
973 if (slot->token->readOnly)
974 strcat(flags, "ro, ");
975 } else {
976 strcpy(flags, "no token");
977 }
978 if ((m = strlen(flags)) != 0) {
979 flags[m - 2] = '\0';
980 }
982 if (slot_nr != -1 &&
983 slot_nr == PKCS11_get_slotid_from_slot(slot)) {
984 found_slot = slot;
985 }
987 if (verbose) {
988 fprintf(stderr, "[%lu] %-25.25s %-16s",
989 PKCS11_get_slotid_from_slot(slot),
990 slot->description, flags);
991 if (slot->token) {
992 fprintf(stderr, " (%s)",
993 slot->token->label[0] ?
994 slot->token->label : "no label");
995 }
996 fprintf(stderr, "\n");
997 }
998 }
1000 if (found_slot) {
1001 slot = found_slot;
1002 } else {
1003 fprintf(stderr, "Invalid slot number: %d\n", (int)slot_nr);
1004 PKCS11_release_all_slots(ctx, slot_list, slot_count);
1005 goto out;
1006 }
1008 tok = slot->token;
1010 if (tok == NULL) {
1011 fprintf(stderr, "Found empty token; \n");
1012 PKCS11_release_all_slots(ctx, slot_list, slot_count);
1013 goto out;
1014 }
1016 if (verbose) {
1017 fprintf(stderr, "Found slot: %s\n", slot->description);
1018 fprintf(stderr, "Found token: %s\n", slot->token->label);
1019 }
1021 if ((tok->loginRequired) && (do_login(slot))) {
1022 fprintf(stderr, "failed to login\n");
1023 PKCS11_release_all_slots(ctx, slot_list, slot_count);
1024 goto out;
1025 }
1027 if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) {
1028 fprintf(stderr, "unable to enumerate certificates\n");
1029 PKCS11_release_all_slots(ctx, slot_list, slot_count);
1030 goto out;
1031 }
1033 for (n=0; n<cert_count; n++) {
1034 PKCS11_CERT *c = certs + n;
1035 char *dn = NULL;
1037 fprintf(stderr, "Certificate Object:\n");
1038 fprintf(stderr, "\ttype: X.509 cert\n");
1039 fprintf(stderr, "\tlabel: %s\n", c->label);
1040 fprintf(stderr, "\tID: ", c->id);
1041 for (i = 0; i < c->id_len; i++)
1042 printf("%02x", c->id[i]);
1043 printf("\n");
1045 if (c->x509)
1046 dn = X509_NAME_oneline(X509_get_subject_name(c->x509),
1047 NULL, 0);
1048 if (dn) {
1049 fprintf(stderr, "\tname: %s\n", dn);
1050 OPENSSL_free(dn);
1051 }
1052 }
1054 if (PKCS11_enumerate_keys(tok, &keys, &key_count)) {
1055 fprintf(stderr, "unable to enumerate keys\n");
1056 PKCS11_release_all_slots(ctx, slot_list, slot_count);
1057 goto out;
1058 }
1060 for (n=0; n<key_count; n++) {
1061 PKCS11_KEY *k = keys + n;
1063 if (k->isPrivate) {
1064 fprintf(stderr, "Private Key Object:\n");
1065 fprintf(stderr, "\ttype: RSA\n");
1066 } else {
1067 fprintf(stderr, "Public Key Object:\n");
1068 fprintf(stderr, "\ttype: RSA %d bits\n",
1069 (PKCS11_get_key_size(k)*8));
1070 }
1071 fprintf(stderr, "\tlabel: %s\n", k->label);
1072 fprintf(stderr, "\tID: ");
1073 for (i = 0; i < k->id_len; i++)
1074 printf("%02x", k->id[i]);
1075 printf("\n");
1076 }
1078 ret_val = 1;
1080 out:
1081 if (local_init) {
1082 pkcs11_finish(e);
1083 }
1085 return ret_val;
1086 }
1088 static int do_login(PKCS11_SLOT *slot)
1089 {
1090 PKCS11_TOKEN *tok = slot->token;
1092 if (pin == NULL) {
1093 fprintf(stderr, "PIN not set\n");
1094 return -1;
1095 }
1097 /* Now login in with the (possibly NULL) pin */
1098 if (PKCS11_login(slot, 0, pin)) {
1099 /* Login failed, so free the PIN if present */
1100 if (pin != NULL) {
1101 OPENSSL_cleanse(pin, pin_length);
1102 free(pin);
1103 pin = NULL;
1104 pin_length = 0;
1105 }
1106 fprintf(stderr, "Login failed\n");
1107 return -1;
1108 }
1109 return 0;
1110 }
1112 int store_cert_ctrl(ENGINE * e, void *p)
1113 {
1114 struct cert_ctrl_params *params = p;
1116 if (params->cert == NULL)
1117 return 0;
1119 if (pkcs11_store_cert(e, params->slot_nr, params->cert_id,
1120 params->cert_id_len, params->cert_label, params->cert))
1121 return 0;
1123 return 1;
1124 }
1126 int store_cert_cmd(ENGINE * e, const char *p)
1127 {
1128 int n, rv=0;
1129 unsigned char cert_id[MAX_VALUE_LEN / 2];
1130 size_t cert_id_len = sizeof(cert_id);
1131 char *cert_label = NULL;
1132 char *cert_file = NULL;
1133 int slot_nr = -1;
1134 unsigned char data[MAX_OBJECT_SIZE];
1135 const unsigned char *pp = data;
1136 int data_len = 0;
1137 FILE *f;
1138 X509 *x;
1140 if (!p || !*p) {
1141 fprintf(stderr, "no parameter\n");
1142 return 0;
1143 }
1145 n = parse_cert_store_string(p, &slot_nr, cert_id, &cert_id_len,
1146 &cert_label, &cert_file);
1147 if (n) {
1148 fprintf(stderr,
1149 "supported format: slot_<slot>:id_<id>:label_<label>:cert_<filename>\n");
1150 fprintf(stderr,
1151 "where <slot> is the slot number as normal integer,\n");
1152 fprintf(stderr,
1153 "and <id> is the id number as hex string.\n");
1154 fprintf(stderr,
1155 "and <label> is the textual cert label string.\n");
1156 fprintf(stderr,
1157 "and <filename> is the cert filename with full path.\n");
1158 goto store_cert_err_out;
1159 }
1161 f = fopen(cert_file, "rb");
1162 if (f == NULL) {
1163 fprintf(stderr, "Couldn't open cert file \"%s\"\n", cert_file);
1164 goto store_cert_err_out;
1165 }
1167 data_len = fread(data, 1, sizeof(data), f);
1169 if (data_len < 0) {
1170 fprintf(stderr, "Couldn't read from file \"%s\"\n", cert_file);
1171 goto store_cert_err_out;
1172 }
1174 x = d2i_X509(NULL, &pp, data_len);
1175 if (!x) {
1176 fprintf(stderr, "OpenSSL cert parse error\n");
1177 goto store_cert_err_out;
1178 }
1180 /* No ID specified */
1181 if (cert_id_len == sizeof(cert_id))
1182 cert_id_len = 0;
1184 if (verbose) {
1185 fprintf(stderr, "Storing cert(%s) in slot(%d) with label(%s) and id(",
1186 cert_file, slot_nr, cert_label);
1187 for (n = 0; n < cert_id_len; n++)
1188 fprintf(stderr, "%02x", cert_id[n]);
1189 fprintf(stderr, ")\n");
1190 }
1192 if (pkcs11_store_cert(e, slot_nr, cert_id, cert_id_len, cert_label, x))
1193 goto store_cert_err_out;
1195 rv = 1;
1197 store_cert_err_out:
1198 if (f) fclose(f);
1199 if (cert_label) free(cert_label);
1200 if (cert_file) free(cert_file);
1201 return rv;
1202 }
1204 static int pkcs11_store_cert
1205 (
1206 ENGINE * e,
1207 int slot_nr,
1208 unsigned char *cert_id,
1209 size_t cert_id_len,
1210 char *cert_label,
1211 X509 *x
1212 )
1213 {
1214 PKCS11_SLOT *slot_list, *slot;
1215 PKCS11_SLOT *found_slot = NULL;
1216 PKCS11_TOKEN *tok;
1217 PKCS11_CERT *certs, *ret_cert = NULL;
1218 unsigned int slot_count, cert_count;
1219 char flags[64];
1220 int n,m;
1221 int ret_val = -1;
1222 int local_init = 0;
1224 if (ctx == NULL) {
1225 pkcs11_init(e);
1226 local_init = 1;
1227 }
1229 if (PKCS11_enumerate_slots(ctx, &slot_list, &slot_count)) {
1230 fprintf(stderr, "failed to enumerate slots\n");
1231 goto out;
1232 }
1234 if (verbose) {
1235 fprintf(stderr, "Found %u slots\n", slot_count);
1236 }
1238 for (n = 0; n < slot_count; n++) {
1239 slot = slot_list + n;
1240 flags[0] = '\0';
1241 if (slot->token) {
1242 if (!slot->token->initialized)
1243 strcat(flags, "uninitialized, ");
1244 else if (!slot->token->userPinSet)
1245 strcat(flags, "no pin, ");
1246 if (slot->token->loginRequired)
1247 strcat(flags, "login, ");
1248 if (slot->token->readOnly)
1249 strcat(flags, "ro, ");
1250 } else {
1251 strcpy(flags, "no token");
1252 }
1253 if ((m = strlen(flags)) != 0) {
1254 flags[m - 2] = '\0';
1255 }
1257 if (slot_nr != -1 &&
1258 slot_nr == PKCS11_get_slotid_from_slot(slot)) {
1259 found_slot = slot;
1260 }
1262 if (verbose) {
1263 fprintf(stderr, "[%lu] %-25.25s %-16s",
1264 PKCS11_get_slotid_from_slot(slot),
1265 slot->description, flags);
1266 if (slot->token) {
1267 fprintf(stderr, " (%s)",
1268 slot->token->label[0] ?
1269 slot->token->label : "no label");
1270 }
1271 fprintf(stderr, "\n");
1272 }
1273 }
1275 if (found_slot) {
1276 slot = found_slot;
1277 } else {
1278 fprintf(stderr, "Invalid slot number: %d\n", (int)slot_nr);
1279 goto err_out;
1280 }
1282 tok = slot->token;
1284 if (tok == NULL) {
1285 fprintf(stderr, "Found empty token; \n");
1286 goto err_out;
1287 }
1289 if (verbose) {
1290 fprintf(stderr, "Found slot: %s\n", slot->description);
1291 fprintf(stderr, "Found token: %s\n", slot->token->label);
1292 }
1294 if ((tok->loginRequired) && (do_login(slot))) {
1295 fprintf(stderr, "failed to login\n");
1296 goto err_out;
1297 }
1299 /* Enumerate certs to initialize libp11 cert count */
1300 if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) {
1301 fprintf(stderr, "unable to enumerate certificates\n");
1302 goto err_out;
1303 }
1305 if (PKCS11_store_certificate(tok, x, cert_label, cert_id,
1306 cert_id_len, &ret_cert)) {
1307 fprintf(stderr, "failed to store cert\n");
1308 goto err_out;
1309 }
1311 ret_val = 0;
1312 goto out;
1314 err_out:
1315 PKCS11_release_all_slots(ctx, slot_list, slot_count);
1317 out:
1318 if(local_init) {
1319 pkcs11_finish(e);
1320 }
1322 return ret_val;
1323 }
1325 static int parse_cert_store_string
1326 (
1327 const char *cert_store_str,
1328 int *slot,
1329 unsigned char *id,
1330 size_t * id_len,
1331 char **label,
1332 char **cert_file
1333 )
1334 {
1335 char *token;
1336 const char *sep = ":";
1337 char *str, *lasts;
1338 int rv = -1;
1340 if (!cert_store_str)
1341 return -1;
1343 str = strdup(cert_store_str);
1344 if (str == NULL)
1345 return -1;
1347 /* Default values */
1348 *slot = 0;
1349 *label = NULL;
1350 *cert_file = NULL;
1352 token = strtok_r(str, sep, &lasts);
1354 while (token) {
1356 /* slot identifier */
1357 if (!strncmp(token, "slot_", 5)) {
1358 /* slot is a decimal number */
1359 if (sscanf(token + 5, "%d", slot) != 1) {
1360 fprintf(stderr, "slot number not deciphered!\n");
1361 goto err;
1362 }
1363 } else if (!strncmp(token, "id_", 3)) {
1364 /* certificate ID */
1365 /* id is hexadecimal number */
1366 if (!hex_to_bin(token + 3, id, id_len)) {
1367 fprintf(stderr, "id not deciphered!\n");
1368 goto err;
1369 }
1370 } else if (!strncmp(token, "label_", 6)) {
1371 /* label */
1372 /* label is string */
1373 *label = strdup(token + 6);
1374 if (*label == NULL) {
1375 fprintf(stderr, "label not deciphered!\n");
1376 goto err;
1377 }
1378 } else if (!strncmp(token, "cert_", 5)) {
1379 /* cert file name */
1380 *cert_file = strdup(token + 5);
1381 if (*cert_file == NULL) {
1382 fprintf(stderr, "cert file not deciphered!\n");
1383 goto err;
1384 }
1385 }
1386 token = strtok_r(NULL, sep, &lasts);
1387 } /* end while(token) */
1389 if (*cert_file == NULL) {
1390 fprintf(stderr, "cert file name not present!\n");
1391 goto err;
1392 }
1394 rv = 0;
1396 err:
1397 if (str) free(str);
1398 if (rv && *label) { free(*label); *label = NULL; }
1399 if (rv && *cert_file) { free(*cert_file); *cert_file = NULL; }
1400 return rv;
1401 }
1403 int gen_key_cmd(ENGINE * e, const char *p)
1404 {
1405 int key_size, n;
1406 unsigned char key_id[MAX_VALUE_LEN / 2];
1407 size_t key_id_len = sizeof(key_id);
1408 char *key_label = NULL;
1409 int slot_nr = -1;
1410 int rv = 0;
1412 if (!p || !*p) {
1413 fprintf(stderr, "no parameter\n");
1414 return 0;
1415 }
1417 n = parse_key_gen_string(p, &slot_nr, &key_size, key_id, &key_id_len,
1418 &key_label);
1419 if (n) {
1420 fprintf(stderr,
1421 "supported format: slot_<slot>:size_<size>:id_<id>:label_<label>\n");
1422 fprintf(stderr,
1423 "where <slot> is the slot number as normal integer,\n");
1424 fprintf(stderr,
1425 "and <size> is the RSA key size in bits.\n");
1426 fprintf(stderr,
1427 "and <id> is the id number as hex string.\n");
1428 fprintf(stderr,
1429 "and <label> is the textual cert label string.\n");
1430 goto gen_key_err_out;
1431 }
1433 if (verbose) {
1434 fprintf(stderr, "Generating %dbits RSA key in slot(%d) with label(%s) and id(",
1435 key_size, slot_nr, key_label);
1436 for (n = 0; n < key_id_len; n++)
1437 fprintf(stderr, "%02x", key_id[n]);
1438 fprintf(stderr, ")\n");
1439 }
1441 if (pkcs11_gen_key(e, slot_nr, (unsigned int)key_size, key_id, key_id_len, key_label))
1442 goto gen_key_err_out;
1444 rv = 1;
1446 gen_key_err_out:
1447 if (key_label) free(key_label);
1448 return rv;
1450 }
1452 static int parse_key_gen_string
1453 (
1454 const char *key_gen_str,
1455 int *slot,
1456 int *key_size,
1457 unsigned char *id,
1458 size_t * id_len,
1459 char **label
1460 )
1461 {
1462 char *token;
1463 const char *sep = ":";
1464 char *str, *lasts;
1465 int rv = -1;
1467 if (!key_gen_str)
1468 return -1;
1470 str = strdup(key_gen_str);
1471 if (str == NULL)
1472 return -1;
1474 /* Default values */
1475 *slot = 0;
1476 *label = NULL;
1477 *key_size = -1;
1479 token = strtok_r(str, sep, &lasts);
1481 while (token) {
1483 /* slot identifier */
1484 if (!strncmp(token, "slot_", 5)) {
1485 /* slot is a decimal number */
1486 if (sscanf(token + 5, "%d", slot) != 1) {
1487 fprintf(stderr, "slot number not deciphered!\n");
1488 goto err;
1489 }
1490 } else if (!strncmp(token, "id_", 3)) {
1491 /* certificate ID */
1492 /* id is hexadecimal number */
1493 if (!hex_to_bin(token + 3, id, id_len)) {
1494 fprintf(stderr, "id not deciphered!\n");
1495 goto err;
1496 }
1497 } else if (!strncmp(token, "label_", 6)) {
1498 /* label */
1499 /* label is string */
1500 *label = strdup(token + 6);
1501 if (*label == NULL) {
1502 fprintf(stderr, "label not deciphered!\n");
1503 goto err;
1504 }
1505 } else if (!strncmp(token, "size_", 5)) {
1506 /* key size in bits */
1507 if (sscanf(token + 5, "%d", key_size) != 1) {
1508 fprintf(stderr, "key size not deciphered!\n");
1509 goto err;
1510 }
1511 }
1512 token = strtok_r(NULL, sep, &lasts);
1513 } /* end while(token) */
1515 if (*key_size == -1) {
1516 fprintf(stderr, "key size not present!\n");
1517 goto err;
1518 }
1520 rv = 0;
1521 err:
1522 if (str) free(str);
1523 if (rv && *label) { free(*label); *label = NULL; }
1524 return rv;
1525 }
1527 static int pkcs11_gen_key
1528 (
1529 ENGINE * e,
1530 int slot_nr,
1531 unsigned int key_size,
1532 unsigned char *key_id,
1533 size_t key_id_len,
1534 char *key_label
1535 )
1536 {
1537 PKCS11_SLOT *slot_list, *slot;
1538 PKCS11_SLOT *found_slot = NULL;
1539 PKCS11_TOKEN *tok;
1540 PKCS11_KEY *keys, *ret_key = NULL;
1541 unsigned int slot_count, key_count;
1542 char flags[64];
1543 int n,m;
1544 int ret_val = -1;
1545 int local_init = 0;
1547 if (ctx == NULL) {
1548 pkcs11_init(e);
1549 local_init = 1;
1550 }
1552 if (PKCS11_enumerate_slots(ctx, &slot_list, &slot_count)) {
1553 fprintf(stderr, "failed to enumerate slots\n");
1554 goto out;
1555 }
1557 if (verbose) {
1558 fprintf(stderr, "Found %u slots\n", slot_count);
1559 }
1561 for (n = 0; n < slot_count; n++) {
1562 slot = slot_list + n;
1563 flags[0] = '\0';
1564 if (slot->token) {
1565 if (!slot->token->initialized)
1566 strcat(flags, "uninitialized, ");
1567 else if (!slot->token->userPinSet)
1568 strcat(flags, "no pin, ");
1569 if (slot->token->loginRequired)
1570 strcat(flags, "login, ");
1571 if (slot->token->readOnly)
1572 strcat(flags, "ro, ");
1573 } else {
1574 strcpy(flags, "no token");
1575 }
1576 if ((m = strlen(flags)) != 0) {
1577 flags[m - 2] = '\0';
1578 }
1580 if (slot_nr != -1 &&
1581 slot_nr == PKCS11_get_slotid_from_slot(slot)) {
1582 found_slot = slot;
1583 }
1585 if (verbose) {
1586 fprintf(stderr, "[%lu] %-25.25s %-16s",
1587 PKCS11_get_slotid_from_slot(slot),
1588 slot->description, flags);
1589 if (slot->token) {
1590 fprintf(stderr, " (%s)",
1591 slot->token->label[0] ?
1592 slot->token->label : "no label");
1593 }
1594 fprintf(stderr, "\n");
1595 }
1596 }
1598 if (found_slot) {
1599 slot = found_slot;
1600 } else {
1601 fprintf(stderr, "Invalid slot number: %d\n", (int)slot_nr);
1602 goto err_out;
1603 }
1605 tok = slot->token;
1607 if (tok == NULL) {
1608 fprintf(stderr, "Found empty token; \n");
1609 goto err_out;
1610 }
1612 if (verbose) {
1613 fprintf(stderr, "Found slot: %s\n", slot->description);
1614 fprintf(stderr, "Found token: %s\n", slot->token->label);
1615 }
1617 if ((tok->loginRequired) && (do_login(slot))) {
1618 fprintf(stderr, "failed to login\n");
1619 goto err_out;
1620 }
1622 /* Enumerate keys to initialize libp11 key count */
1623 if (PKCS11_enumerate_keys(tok, &keys, &key_count)) {
1624 fprintf(stderr, "unable to enumerate keys\n");
1625 goto err_out;
1626 }
1628 if (PKCS11_generate_key(tok, EVP_PKEY_RSA, key_size, key_label,
1629 key_id, key_id_len)) {
1630 fprintf(stderr, "failed to generate RSA key pair\n");
1631 goto err_out;
1632 }
1634 ret_val = 0;
1635 goto out;
1637 err_out:
1638 PKCS11_release_all_slots(ctx, slot_list, slot_count);
1639 out:
1640 if (local_init) {
1641 pkcs11_finish(e);
1642 }
1643 return ret_val;
1644 }
1646 int del_obj_cmd(ENGINE * e, const char *p)
1647 {
1648 int n;
1649 unsigned char id[MAX_VALUE_LEN / 2];
1650 size_t id_len = sizeof(id);
1651 char *label = NULL, *type = NULL;
1652 int slot_nr = -1;
1653 int rv = 0;
1655 if (!p || !*p) {
1656 fprintf(stderr, "no parameter\n");
1657 return 0;
1658 }
1660 n = parse_del_obj_string(p, &slot_nr, &type, id, &id_len, &label);
1661 if (n) {
1662 fprintf(stderr,
1663 "supported format: slot_<slot>:type_<type>:id_<id>:label_<label>\n");
1664 fprintf(stderr,
1665 "where <slot> is the slot number as normal integer,\n");
1666 fprintf(stderr,
1667 "and <type> is the object type (privkey/pubkey/cert)\n");
1668 fprintf(stderr,
1669 "and <id> is the id number as hex string.\n");
1670 fprintf(stderr,
1671 "and <label> is the textual label string.\n");
1672 goto err;
1673 }
1675 /* No ID specified */
1676 if (id_len == sizeof(id))
1677 id_len = 0;
1679 if (verbose) {
1680 fprintf(stderr, "Deleting object type(%s) from slot(%d) with label(%s) and id(",
1681 type, slot_nr, label);
1682 for (n = 0; n < id_len; n++)
1683 fprintf(stderr, "%02x", id[n]);
1684 fprintf(stderr, ")\n");
1685 }
1687 if (pkcs11_del_obj(e, slot_nr, type, id, id_len, label))
1688 goto err;
1690 rv = 1;
1692 err:
1693 if (label) free(label);
1694 if (type) free(type);
1695 return rv;
1696 }
1698 static int parse_del_obj_string
1699 (
1700 const char *del_obj_str,
1701 int *slot,
1702 char **type,
1703 unsigned char *id,
1704 size_t * id_len,
1705 char **label
1706 )
1707 {
1708 char *token;
1709 const char *sep = ":";
1710 char *str, *lasts;
1711 int rv = -1;
1713 if (!del_obj_str)
1714 return -1;
1716 str = strdup(del_obj_str);
1717 if (str == NULL)
1718 return -1;
1720 /* Default values */
1721 *slot = 0;
1722 *label = NULL;
1723 *type = NULL;
1725 token = strtok_r(str, sep, &lasts);
1727 while (token) {
1729 /* slot identifier */
1730 if (!strncmp(token, "slot_", 5)) {
1731 /* slot is a decimal number */
1732 if (sscanf(token + 5, "%d", slot) != 1) {
1733 fprintf(stderr, "slot number not deciphered!\n");
1734 goto err;
1735 }
1736 } else if (!strncmp(token, "id_", 3)) {
1737 /* certificate ID */
1738 /* id is hexadecimal number */
1739 if (!hex_to_bin(token + 3, id, id_len)) {
1740 fprintf(stderr, "id not deciphered!\n");
1741 goto err;
1742 }
1743 } else if (!strncmp(token, "label_", 6)) {
1744 /* label */
1745 /* label is string */
1746 *label = strdup(token + 6);
1747 if (*label == NULL) {
1748 fprintf(stderr, "label not deciphered!\n");
1749 goto err;
1750 }
1751 } else if (!strncmp(token, "type_", 5)) {
1752 /* Object type */
1753 *type = strdup(token + 5);
1754 if (*type == NULL) {
1755 fprintf(stderr, "type not deciphered!\n");
1756 goto err;
1757 }
1758 }
1759 token = strtok_r(NULL, sep, &lasts);
1760 } /* end while(token) */
1762 if (*type == NULL) {
1763 fprintf(stderr, "type not present!\n");
1764 goto err;
1765 }
1767 rv = 0;
1768 err:
1769 if (str) free(str);
1770 if (rv && *label) { free(*label); *label = NULL; }
1771 if (rv && *type) { free(*type); *type = NULL; }
1772 return rv;
1773 }
1775 static int pkcs11_del_obj
1776 (
1777 ENGINE * e,
1778 int slot_nr,
1779 char *type_str,
1780 unsigned char *id,
1781 size_t id_len,
1782 char *label
1783 )
1784 {
1785 PKCS11_SLOT *slot_list, *slot;
1786 PKCS11_SLOT *found_slot = NULL;
1787 PKCS11_TOKEN *tok;
1788 PKCS11_KEY *keys, *ret_key = NULL;
1789 unsigned int slot_count, key_count;
1790 char flags[64];
1791 int n,m, type, retval = -1;
1792 int local_init = 0;
1793 #define TYPE_PRIVKEY 1
1794 #define TYPE_PUBKEY 2
1795 #define TYPE_CERT 3
1797 if (!strcmp(type_str, "privkey")) {
1798 type = TYPE_PRIVKEY;
1799 } else if (!strcmp(type_str, "pubkey")) {
1800 type = TYPE_PUBKEY;
1801 } else if (!strcmp(type_str, "cert")) {
1802 type = TYPE_CERT;
1803 } else {
1804 fprintf(stderr, "invalid object type(%s)\n", type_str);
1805 goto out;
1806 }
1808 if (ctx == NULL) {
1809 pkcs11_init(e);
1810 local_init = 1;
1811 }
1813 if (PKCS11_enumerate_slots(ctx, &slot_list, &slot_count)) {
1814 fprintf(stderr, "failed to enumerate slots\n");
1815 goto out;
1816 }
1818 if (verbose) {
1819 fprintf(stderr, "Found %u slots\n", slot_count);
1820 }
1822 for (n = 0; n < slot_count; n++) {
1823 slot = slot_list + n;
1824 flags[0] = '\0';
1825 if (slot->token) {
1826 if (!slot->token->initialized)
1827 strcat(flags, "uninitialized, ");
1828 else if (!slot->token->userPinSet)
1829 strcat(flags, "no pin, ");
1830 if (slot->token->loginRequired)
1831 strcat(flags, "login, ");
1832 if (slot->token->readOnly)
1833 strcat(flags, "ro, ");
1834 } else {
1835 strcpy(flags, "no token");
1836 }
1837 if ((m = strlen(flags)) != 0) {
1838 flags[m - 2] = '\0';
1839 }
1841 if (slot_nr != -1 &&
1842 slot_nr == PKCS11_get_slotid_from_slot(slot)) {
1843 found_slot = slot;
1844 }
1846 if (verbose) {
1847 fprintf(stderr, "[%lu] %-25.25s %-16s",
1848 PKCS11_get_slotid_from_slot(slot),
1849 slot->description, flags);
1850 if (slot->token) {
1851 fprintf(stderr, " (%s)",
1852 slot->token->label[0] ?
1853 slot->token->label : "no label");
1854 }
1855 fprintf(stderr, "\n");
1856 }
1857 }
1859 if (found_slot) {
1860 slot = found_slot;
1861 } else {
1862 fprintf(stderr, "Invalid slot number: %d\n", (int)slot_nr);
1863 goto err_out;
1864 }
1866 tok = slot->token;
1868 if (tok == NULL) {
1869 fprintf(stderr, "Found empty token; \n");
1870 goto err_out;
1871 }
1873 if (verbose) {
1874 fprintf(stderr, "Found slot: %s\n", slot->description);
1875 fprintf(stderr, "Found token: %s\n", slot->token->label);
1876 }
1878 if ((tok->loginRequired) && (do_login(slot))) {
1879 fprintf(stderr, "failed to login\n");
1880 goto err_out;
1881 }
1883 switch(type) {
1884 case TYPE_CERT:
1885 if (PKCS11_remove_certificate(tok, label, id, id_len)) {
1886 fprintf(stderr, "failed to delete certificate\n");
1887 goto err_out;
1888 }
1889 break;
1891 case TYPE_PUBKEY:
1892 if (PKCS11_remove_public_key(tok, label, id, id_len)) {
1893 fprintf(stderr, "failed to delete public key\n");
1894 goto err_out;
1895 }
1896 break;
1898 case TYPE_PRIVKEY:
1899 if (PKCS11_remove_private_key(tok, label, id, id_len)) {
1900 fprintf(stderr, "failed to delete private key\n");
1901 goto err_out;
1902 }
1903 break;
1905 default:
1906 fprintf(stderr, "object type(%s) not supported\n", type_str);
1907 goto err_out;
1908 break;
1909 }
1911 retval = 0;
1912 err_out:
1913 PKCS11_release_all_slots(ctx, slot_list, slot_count);
1914 out:
1915 if (local_init) {
1916 pkcs11_finish(e);
1917 }
1918 return retval;
1919 }
1921 int get_pubkey_cmd(ENGINE * e, const char *p)
1922 {
1923 int n, rv = 0;
1924 unsigned char key_id[MAX_VALUE_LEN / 2];
1925 size_t key_id_len = sizeof(key_id);
1926 char *key_label = NULL;
1927 char *key_file = NULL;
1928 int slot_nr = -1;
1929 unsigned char *pp, *data = NULL;
1930 int data_len = 0;
1931 FILE *f;
1932 EVP_PKEY *pk;
1933 RSA *rsa;
1935 if (!p || !*p) {
1936 fprintf(stderr, "no parameter\n");
1937 return 0;
1938 }
1940 n = parse_key_string(p, &slot_nr, key_id, &key_id_len,
1941 &key_label, &key_file);
1942 if (n) {
1943 fprintf(stderr,
1944 "supported format: slot_<slot>:id_<id>:label_<label>:key_<filename>\n");
1945 fprintf(stderr,
1946 "where <slot> is the slot number as normal integer,\n");
1947 fprintf(stderr,
1948 "and <id> is the id number as hex string.\n");
1949 fprintf(stderr,
1950 "and <label> is the textual key label string.\n");
1951 fprintf(stderr,
1952 "and <filename> is the key filename with full path.\n");
1953 goto get_pubkey_err_out;
1954 }
1956 f = fopen(key_file, "wb");
1957 if (f == NULL) {
1958 fprintf(stderr, "Couldn't open key file \"%s\"\n", key_file);
1959 goto get_pubkey_err_out;
1960 }
1962 /* No ID specified */
1963 if (key_id_len == sizeof(key_id))
1964 key_id_len = 0;
1966 if (verbose) {
1967 fprintf(stderr, "Getting public key in slot(%d) with label(%s) and id(",
1968 slot_nr, key_label);
1969 for (n = 0; n < key_id_len; n++)
1970 fprintf(stderr, "%02x", key_id[n]);
1971 fprintf(stderr, ")\n");
1972 }
1974 pk = pkcs11_load_key(e, slot_nr, key_id, key_id_len, key_label, NULL, NULL, 0);
1975 if (pk == NULL) {
1976 fprintf(stderr, "PKCS11_load_public_key returned NULL\n");
1977 goto get_pubkey_err_out;
1978 }
1980 rsa = EVP_PKEY_get1_RSA(pk);
1981 if (rsa == NULL) {
1982 fprintf(stderr, "Couldn't retrieve RSA key form EVP_PKEY\n");
1983 goto get_pubkey_err_out;
1984 }
1986 #if 0
1987 /* To store in DER format */
1988 data_len = i2d_RSAPublicKey(rsa, NULL);
1989 if ((data = (unsigned char *)malloc(data_len)) == NULL) {
1990 fprintf(stderr, "couldn't allocate memory for key\n");
1991 goto get_pubkey_err_out;
1992 }
1993 pp = data;
1994 data_len = i2d_RSAPublicKey(rsa, &pp);
1995 n = fwrite(data, 1, data_len, f);
1997 if (n != data_len) {
1998 fprintf(stderr, "Couldn't write to file \"%s\"\n", key_file);
1999 goto get_pubkey_err_out;
2000 }
2001 #endif
2002 if (!PEM_write_RSA_PUBKEY(f, rsa)) {
2003 fprintf(stderr, "Couldn't write to file \"%s\"\n", key_file);
2004 goto get_pubkey_err_out;
2005 }
2007 rv = 1;
2009 get_pubkey_err_out:
2010 if (f) fclose(f);
2011 if (key_label) free(key_label);
2012 if (key_file) free(key_file);
2013 return rv;
2015 }
2017 static int parse_key_string
2018 (
2019 const char *key_get_str,
2020 int *slot,
2021 unsigned char *id,
2022 size_t * id_len,
2023 char **label,
2024 char **key_file
2025 )
2026 {
2027 char *token;
2028 const char *sep = ":";
2029 char *str, *lasts;
2030 int rv = -1;
2032 if (!key_get_str)
2033 return -1;
2035 str = strdup(key_get_str);
2036 if (str == NULL)
2037 return -1;
2039 /* Default values */
2040 *slot = 0;
2041 *label = NULL;
2042 if (key_file) *key_file = NULL;
2044 token = strtok_r(str, sep, &lasts);
2046 while (token) {
2048 /* slot identifier */
2049 if (!strncmp(token, "slot_", 5)) {
2050 /* slot is a decimal number */
2051 if (sscanf(token + 5, "%d", slot) != 1) {
2052 fprintf(stderr, "slot number not deciphered!\n");
2053 goto err;
2054 }
2055 } else if (!strncmp(token, "id_", 3)) {
2056 /* certificate ID */
2057 /* id is hexadecimal number */
2058 if (!hex_to_bin(token + 3, id, id_len)) {
2059 fprintf(stderr, "id not deciphered!\n");
2060 goto err;
2061 }
2062 } else if (!strncmp(token, "label_", 6)) {
2063 /* label */
2064 /* label is string */
2065 *label = strdup(token + 6);
2066 if (*label == NULL) {
2067 fprintf(stderr, "label not deciphered!\n");
2068 goto err;
2069 }
2070 } else if ((key_file) && (!strncmp(token, "key_", 4))) {
2071 /* key file name */
2072 *key_file = strdup(token + 4);
2073 if (*key_file == NULL) {
2074 fprintf(stderr, "key file not deciphered!\n");
2075 goto err;
2076 }
2077 }
2078 token = strtok_r(NULL, sep, &lasts);
2079 } /* end while(token) */
2081 if ((key_file) && (*key_file == NULL)) {
2082 fprintf(stderr, "key file name not present!\n");
2083 goto err;
2084 }
2086 rv = 0;
2088 err:
2089 if (str) free(str);
2090 if (rv && *label) { free(*label); *label = NULL; }
2091 if (rv && *key_file) { free(*key_file); *key_file = NULL; }
2092 return rv;
2093 }