1 /*
2 * pkcs15-tool.c: Tool for poking with PKCS #15 smart cards
3 *
4 * Copyright (C) 2001 Juha Yrjölä <juha.yrjola@iki.fi>
5 * Copyright (C) 2008 Andreas Jellinghaus <aj@dungeon.inka.de>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library 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 GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 #include "config.h"
22
23 #if defined(__APPLE__) || defined(__FreeBSD__)
24 #define _XOPEN_SOURCE 600
25 #else
26 #define _XOPEN_SOURCE 500
27 #endif
28 #include <assert.h>
29 #include <ctype.h>
30 #ifdef _WIN32
31 #ifdef __MINGW32__
32 // work around for https://sourceforge.net/p/mingw-w64/bugs/476/
33 #include <windows.h>
34 #endif
35 #include <shellapi.h>
36 #include <tchar.h>
37 #else
38 #include <ftw.h>
39 #endif
40 #include <stdio.h>
41
42 #ifdef ENABLE_OPENSSL
43 #if defined(HAVE_INTTYPES_H)
44 #include <inttypes.h>
45 #elif defined(HAVE_STDINT_H)
46 #include <stdint.h>
47 #elif defined(_MSC_VER)
48 typedef unsigned __int32 uint32_t;
49 #else
50 #warning no uint32_t type available, please contact opensc-devel@opensc-project.org
51 #endif
52 #include <openssl/bn.h>
53 #include <openssl/crypto.h>
54 #endif
55 #include <limits.h>
56
57 #include "libopensc/pkcs15.h"
58 #include "libopensc/asn1.h"
59 #include "util.h"
60 #include "pkcs11/pkcs11-display.h"
61
62 static const char *app_name = "pkcs15-tool";
63
64 static int opt_wait = 0;
65 static int opt_no_cache = 0;
66 static int opt_clear_cache = 0;
67 static char * opt_auth_id = NULL;
68 static char * opt_reader = NULL;
69 static char * opt_cert = NULL;
70 static char * opt_data = NULL;
71 static int opt_raw = 0;
72 static char * opt_pubkey = NULL;
73 static char * opt_outfile = NULL;
74 static char * opt_bind_to_aid = NULL;
75 static const char * opt_newpin = NULL;
76 static const char * opt_pin = NULL;
77 static const char * opt_puk = NULL;
78 static int compact = 0;
79 static int verbose = 0;
80 static int opt_use_pinpad = 0;
81 #if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
82 static int opt_rfc4716 = 0;
83 #endif
84
85 enum {
86 OPT_CHANGE_PIN = 0x100,
87 OPT_LIST_PINS,
88 OPT_READER,
89 OPT_TEST_SESSION_PIN,
90 OPT_PIN_ID,
91 OPT_NO_CACHE,
92 OPT_CLEAR_CACHE,
93 OPT_LIST_PUB,
94 OPT_READ_PUB,
95 #if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
96 OPT_READ_SSH,
97 OPT_RFC4716,
98 #endif
99 OPT_PIN,
100 OPT_NEWPIN,
101 OPT_PUK,
102 OPT_VERIFY_PIN,
103 OPT_BIND_TO_AID,
104 OPT_LIST_APPLICATIONS,
105 OPT_LIST_SKEYS,
106 OPT_USE_PINPAD,
107 OPT_USE_PINPAD_DEPRECATED,
108 OPT_RAW,
109 OPT_PRINT_VERSION,
110 OPT_LIST_INFO,
111 OPT_READ_CERT,
112 };
113
114 #define NELEMENTS(x) (sizeof(x)/sizeof((x)[0]))
115
116 static int authenticate(sc_pkcs15_object_t *obj);
117
118 static const struct option options[] = {
119 { "version", 0, NULL, OPT_PRINT_VERSION },
120 { "list-info", no_argument, NULL, OPT_LIST_INFO },
121 { "list-applications", no_argument, NULL, OPT_LIST_APPLICATIONS },
122 { "read-certificate", required_argument, NULL, OPT_READ_CERT },
123 { "list-certificates", no_argument, NULL, 'c' },
124 { "read-data-object", required_argument, NULL, 'R' },
125 { "raw", no_argument, NULL, OPT_RAW },
126 { "list-data-objects", no_argument, NULL, 'C' },
127 { "list-pins", no_argument, NULL, OPT_LIST_PINS },
128 { "list-secret-keys", no_argument, NULL, OPT_LIST_SKEYS },
129 { "short", no_argument, NULL, 's' },
130 { "dump", no_argument, NULL, 'D' },
131 { "unblock-pin", no_argument, NULL, 'u' },
132 { "change-pin", no_argument, NULL, OPT_CHANGE_PIN },
133 { "list-keys", no_argument, NULL, 'k' },
134 { "list-public-keys", no_argument, NULL, OPT_LIST_PUB },
135 { "read-public-key", required_argument, NULL, OPT_READ_PUB },
136 #if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
137 { "read-ssh-key", required_argument, NULL, OPT_READ_SSH },
138 { "rfc4716", no_argument, NULL, OPT_RFC4716 },
139 #endif
140 { "test-update", no_argument, NULL, 'T' },
141 { "update", no_argument, NULL, 'U' },
142 { "reader", required_argument, NULL, OPT_READER },
143 { "pin", required_argument, NULL, OPT_PIN },
144 { "new-pin", required_argument, NULL, OPT_NEWPIN },
145 { "puk", required_argument, NULL, OPT_PUK },
146 { "verify-pin", no_argument, NULL, OPT_VERIFY_PIN },
147 { "test-session-pin", no_argument, NULL, OPT_TEST_SESSION_PIN },
148 { "output", required_argument, NULL, 'o' },
149 { "no-cache", no_argument, NULL, OPT_NO_CACHE },
150 { "clear-cache", no_argument, NULL, OPT_CLEAR_CACHE },
151 { "auth-id", required_argument, NULL, 'a' },
152 { "aid", required_argument, NULL, OPT_BIND_TO_AID },
153 { "wait", no_argument, NULL, 'w' },
154 { "verbose", no_argument, NULL, 'v' },
155 { "use-pinpad", no_argument, NULL, OPT_USE_PINPAD },
156 { "no-prompt", no_argument, NULL, OPT_USE_PINPAD_DEPRECATED },
157 { NULL, 0, NULL, 0 }
158 };
159
160 static const char *option_help[] = {
161 "Print OpenSC package version",
162 "List card information",
163 "List the on-card PKCS#15 applications",
164 "Read certificate with ID <arg>",
165 "List certificates",
166 "Reads data object with OID, applicationName or label <arg>",
167 "Outputs raw 8 bit data to stdout. File output will not be affected by this, it always uses raw mode.",
168 "List data objects",
169 "List PIN codes",
170 "List secret keys",
171 "Output lists in compact format",
172 "List all card objects",
173 "Unblock PIN code",
174 "Change PIN or PUK code",
175 "List private keys",
176 "List public keys",
177 "Reads public key with ID <arg>",
178 #if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
179 "Reads public key with ID <arg>, outputs ssh format",
180 "Outputs the public key in RFC 4716 format (requires --read-ssh-key)",
181 #endif
182 "Test if the card needs a security update",
183 "Update the card with a security update",
184 "Uses reader number <arg>",
185 "Specify PIN",
186 "Specify New PIN (when changing or unblocking)",
187 "Specify Unblock PIN",
188 "Verify PIN after card binding (without 'auth-id' the first non-SO, non-Unblock PIN will be verified)",
189 "Equivalent to --verify-pin with additional session PIN generation",
190 "Outputs to file <arg>",
191 "Disable card caching",
192 "Clear card caching",
193 "The auth ID of the PIN to use",
194 "Specify AID of the on-card PKCS#15 application to bind to (in hexadecimal form)",
195 "Wait for card insertion",
196 "Verbose operation. Use several times to enable debug output.",
197 "Do not prompt the user; if no PINs supplied, pinpad will be used.",
198 NULL,
199 NULL
200 };
201
202 static sc_context_t *ctx = NULL;
203 static sc_card_t *card = NULL;
204 static struct sc_pkcs15_card *p15card = NULL;
205
206 struct _access_rule_text {
207 unsigned flag;
208 const char *label;
209 } _access_rules_text[] = {
210 {SC_PKCS15_ACCESS_RULE_MODE_READ, "read"},
211 {SC_PKCS15_ACCESS_RULE_MODE_UPDATE, "update"},
212 {SC_PKCS15_ACCESS_RULE_MODE_EXECUTE, "execute"},
213 {SC_PKCS15_ACCESS_RULE_MODE_DELETE, "delete"},
214 {SC_PKCS15_ACCESS_RULE_MODE_ATTRIBUTE, "attribute"},
215 {SC_PKCS15_ACCESS_RULE_MODE_PSO_CDS, "pso_cds"},
216 {SC_PKCS15_ACCESS_RULE_MODE_PSO_VERIFY, "pso_verify"},
217 {SC_PKCS15_ACCESS_RULE_MODE_PSO_DECRYPT, "pso_decrypt"},
218 {SC_PKCS15_ACCESS_RULE_MODE_PSO_ENCRYPT, "pso_encrypt"},
219 {SC_PKCS15_ACCESS_RULE_MODE_INT_AUTH, "int_auth"},
220 {SC_PKCS15_ACCESS_RULE_MODE_EXT_AUTH, "ext_auth"},
221 {0, NULL},
222 };
223
224 static const char *key_types[] = { "", "RSA", "DSA", "GOSTR3410", "EC", "EDDSA", "XEDDSA", "" };
225
226 static void
print_access_rules(const struct sc_pkcs15_accessrule * rules,int num)227 print_access_rules(const struct sc_pkcs15_accessrule *rules, int num)
228 {
229 int i, j;
230
231 if (!rules->access_mode)
232 return;
233
234 printf("\tAccess Rules :");
235 for (i = 0; i < num; i++) {
236 int next_coma = 0;
237
238 if (!(rules + i)->access_mode)
239 break;
240 printf(" ");
241
242 for (j = 0; _access_rules_text[j].label;j++) {
243 if ((rules + i)->access_mode & (_access_rules_text[j].flag)) {
244 printf("%s%s", next_coma ? "," : "", _access_rules_text[j].label);
245 next_coma = 1;
246 }
247 }
248
249 printf(":%s;", (rules + i)->auth_id.len ? sc_pkcs15_print_id(&(rules + i)->auth_id) : "<always>");
250 }
251 printf("\n");
252 }
253
print_common_flags(const struct sc_pkcs15_object * obj)254 static void print_common_flags(const struct sc_pkcs15_object *obj)
255 {
256 const char *common_flags[] = {"private", "modifiable"};
257 unsigned int i;
258 printf("\tObject Flags : [0x%02X]", obj->flags);
259 for (i = 0; i < NELEMENTS(common_flags); i++) {
260 if (obj->flags & (1 << i)) {
261 printf(", %s", common_flags[i]);
262 }
263 }
264 printf("\n");
265 }
266
print_cert_info(const struct sc_pkcs15_object * obj)267 static void print_cert_info(const struct sc_pkcs15_object *obj)
268 {
269 struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *) obj->data;
270 struct sc_pkcs15_cert *cert_parsed = NULL;
271 int rv;
272
273 if (compact) {
274 printf("\tPath:%s ID:%s", sc_print_path(&cert_info->path),
275 sc_pkcs15_print_id(&cert_info->id));
276 if (cert_info->authority)
277 printf(" Authority");
278 return;
279 }
280
281 printf("X.509 Certificate [%.*s]\n", (int) sizeof obj->label, obj->label);
282 print_common_flags(obj);
283 printf("\tAuthority : %s\n", cert_info->authority ? "yes" : "no");
284 printf("\tPath : %s\n", sc_print_path(&cert_info->path));
285 printf("\tID : %s\n", sc_pkcs15_print_id(&cert_info->id));
286
287 print_access_rules(obj->access_rules, SC_PKCS15_MAX_ACCESS_RULES);
288
289 rv = sc_pkcs15_read_certificate(p15card, cert_info, &cert_parsed);
290 if (rv >= 0 && cert_parsed) {
291 printf("\tEncoded serial : %02X %02X ", *(cert_parsed->serial), *(cert_parsed->serial + 1));
292 util_hex_dump(stdout, cert_parsed->serial + 2, cert_parsed->serial_len - 2, "");
293 printf("\n");
294 sc_pkcs15_free_certificate(cert_parsed);
295 }
296 }
297
list_certificates(void)298 static int list_certificates(void)
299 {
300 int r, i;
301 struct sc_pkcs15_object *objs[32];
302
303 r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, objs, 32);
304 if (r < 0) {
305 fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r));
306 return 1;
307 }
308 if (compact)
309 printf("Card has %d Certificate(s).\n", r);
310 else if (verbose)
311 printf("Card has %d Certificate(s).\n\n", r);
312 for (i = 0; i < r; i++) {
313 print_cert_info(objs[i]);
314 printf("\n");
315 }
316
317 return 0;
318 }
319
320 static int
print_pem_object(const char * kind,const u8 * data,size_t data_len)321 print_pem_object(const char *kind, const u8*data, size_t data_len)
322 {
323 FILE *outf;
324 unsigned char *buf = NULL;
325 size_t buf_len = 1024;
326 int r;
327
328 /* With base64, every 3 bytes yield 4 characters, and with
329 * 64 chars per line we know almost exactly how large a buffer we
330 * will need. */
331 buf_len = (data_len + 2) / 3 * 4;
332 buf_len += 2 * (buf_len / 64 + 2); /* certain platforms use CRLF */
333 buf_len += 64; /* slack for checksum etc */
334
335 if (!(buf = malloc(buf_len))) {
336 perror("print_pem_object");
337 return 1;
338 }
339
340 r = sc_base64_encode(data, data_len, buf, buf_len, 64);
341 if (r < 0) {
342 fprintf(stderr, "Base64 encoding failed: %s\n", sc_strerror(r));
343 free(buf);
344 return 1;
345 }
346
347 if (opt_outfile != NULL) {
348 outf = fopen(opt_outfile, "w");
349 if (outf == NULL) {
350 fprintf(stderr, "Error opening file '%s': %s\n",
351 opt_outfile, strerror(errno));
352 free(buf);
353 return 2;
354 }
355 } else
356 outf = stdout;
357 fprintf(outf,
358 "-----BEGIN %s-----\n"
359 "%s"
360 "-----END %s-----\n",
361 kind, buf, kind);
362 if (outf != stdout)
363 fclose(outf);
364 free(buf);
365 return 0;
366 }
367
368 static void
list_data_object(const char * kind,const unsigned char * data,size_t data_len)369 list_data_object(const char *kind, const unsigned char *data, size_t data_len)
370 {
371 char title[0x100];
372 size_t i;
373
374 snprintf(title, sizeof(title), "%s (%lu bytes): ", kind, (unsigned long) data_len);
375 printf("%s", title);
376 memset(title, ' ', strlen(title));
377 for (i = 0; i < data_len; i++) {
378 if (i && !(i%48))
379 printf("\n%s", title);
380 printf("%02X", data[i]);
381 }
382 printf("\n");
383 }
384
385 static int
print_data_object(const char * kind,const u8 * data,size_t data_len)386 print_data_object(const char *kind, const u8*data, size_t data_len)
387 {
388 size_t i;
389
390 if (opt_outfile != NULL) {
391 FILE *outf;
392 outf = fopen(opt_outfile, "wb");
393 if (outf == NULL) {
394 fprintf(stderr, "Error opening file '%s': %s\n",
395 opt_outfile, strerror(errno));
396 return 2;
397 }
398 for (i=0; i < data_len; i++)
399 fprintf(outf, "%c", data[i]);
400 fclose(outf);
401 } else {
402 if (opt_raw) {
403 for (i=0; i < data_len; i++)
404 printf("%c", data[i]);
405 } else {
406 printf("%s (%lu bytes): <",
407 kind, (unsigned long) data_len);
408 for (i=0; i < data_len; i++)
409 printf(" %02X", data[i]);
410 printf(" >\n");
411 }
412 }
413 return 0;
414 }
415
read_certificate(void)416 static int read_certificate(void)
417 {
418 int r, i, count;
419 struct sc_pkcs15_id id;
420 struct sc_pkcs15_object *objs[32];
421
422 id.len = SC_PKCS15_MAX_ID_SIZE;
423 sc_pkcs15_hex_string_to_id(opt_cert, &id);
424
425 r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, objs, 32);
426 if (r < 0) {
427 fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r));
428 return 1;
429 }
430 count = r;
431 for (i = 0; i < count; i++) {
432 struct sc_pkcs15_cert_info *cinfo = (struct sc_pkcs15_cert_info *) objs[i]->data;
433 struct sc_pkcs15_cert *cert;
434
435 if (sc_pkcs15_compare_id(&id, &cinfo->id) != 1)
436 continue;
437
438 if (verbose)
439 printf("Reading certificate with ID '%s'\n", opt_cert);
440 r = sc_pkcs15_read_certificate(p15card, cinfo, &cert);
441 if (r) {
442 fprintf(stderr, "Certificate read failed: %s\n", sc_strerror(r));
443 return 1;
444 }
445 r = print_pem_object("CERTIFICATE", cert->data.value, cert->data.len);
446 sc_pkcs15_free_certificate(cert);
447 return r;
448 }
449 fprintf(stderr, "Certificate with ID '%s' not found.\n", opt_cert);
450 return 2;
451 }
452
read_data_object(void)453 static int read_data_object(void)
454 {
455 int r, i, count;
456 struct sc_pkcs15_object *objs[32];
457 struct sc_object_id oid;
458
459 r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, objs, 32);
460 if (r < 0) {
461 fprintf(stderr, "Data object enumeration failed: %s\n", sc_strerror(r));
462 return 1;
463 }
464 count = r;
465
466 for (i = 0; i < count; i++) {
467 struct sc_pkcs15_data_info *cinfo = (struct sc_pkcs15_data_info *) objs[i]->data;
468 struct sc_pkcs15_data *data_object = NULL;
469
470 if (!sc_format_oid(&oid, opt_data)) {
471 if (!sc_compare_oid(&oid, &cinfo->app_oid))
472 continue;
473 }
474 else {
475 if (strcmp(opt_data, cinfo->app_label) && strncmp(opt_data, objs[i]->label, sizeof objs[i]->label))
476 continue;
477 }
478
479 if (verbose)
480 printf("Reading data object with label '%s'\n", opt_data);
481 r = authenticate(objs[i]);
482 if (r >= 0) {
483 r = sc_pkcs15_read_data_object(p15card, cinfo, &data_object);
484 if (r) {
485 fprintf(stderr, "Data object read failed: %s\n", sc_strerror(r));
486 if (r == SC_ERROR_FILE_NOT_FOUND)
487 continue; /* DEE emulation may say there is a file */
488 return 1;
489 }
490 r = print_data_object("Data Object", data_object->data, data_object->data_len);
491 sc_pkcs15_free_data_object(data_object);
492 return r;
493 } else {
494 fprintf(stderr, "Authentication error: %s\n", sc_strerror(r));
495 return 1;
496 }
497 }
498 fprintf(stderr, "Data object with label '%s' not found.\n", opt_data);
499 return 2;
500 }
501
list_data_objects(void)502 static int list_data_objects(void)
503 {
504 int r, i, count;
505 struct sc_pkcs15_object *objs[32];
506
507 r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, objs, 32);
508 if (r < 0) {
509 fprintf(stderr, "Data object enumeration failed: %s\n", sc_strerror(r));
510 return 1;
511 }
512 count = r;
513 if (compact)
514 printf("Card has %d Data object(s).\n", count);
515 else if (verbose)
516 printf("Card has %d Data object(s).\n\n", count);
517 for (i = 0; i < count; i++) {
518 int idx;
519 struct sc_pkcs15_data_info *cinfo = (struct sc_pkcs15_data_info *) objs[i]->data;
520
521 if (compact) {
522 printf("\tPath:%-12s", sc_print_path(&cinfo->path));
523 if (sc_valid_oid(&cinfo->app_oid)) {
524 printf(" %i", cinfo->app_oid.value[0]);
525 for (idx = 1; idx < SC_MAX_OBJECT_ID_OCTETS && cinfo->app_oid.value[idx] != -1 ; idx++)
526 printf(".%i", cinfo->app_oid.value[idx]);
527 }
528 if (objs[i]->auth_id.len == 0) {
529 struct sc_pkcs15_data *data_object;
530 r = sc_pkcs15_read_data_object(p15card, cinfo, &data_object);
531 if (r) {
532 fprintf(stderr, "Data object read failed: %s\n", sc_strerror(r));
533 if (r == SC_ERROR_FILE_NOT_FOUND)
534 continue; /* DEE emulation may say there is a file */
535 return 1;
536 }
537 sc_pkcs15_free_data_object(data_object);
538 printf(" Size:%5"SC_FORMAT_LEN_SIZE_T"u",
539 cinfo->data.len);
540 } else {
541 printf(" AuthID:%-3s", sc_pkcs15_print_id(&objs[i]->auth_id));
542 }
543 printf(" %-20s", cinfo->app_label);
544 printf("\n");
545 continue;
546 }
547
548 if (objs[i]->label[0] != '\0')
549 printf("Data object '%.*s'\n",(int) sizeof objs[i]->label, objs[i]->label);
550 else
551 printf("Data object <%i>\n", i);
552 printf("\tapplicationName: %s\n", cinfo->app_label);
553 if (sc_valid_oid(&cinfo->app_oid)) {
554 printf("\tapplicationOID: %i", cinfo->app_oid.value[0]);
555 for (idx = 1; idx < SC_MAX_OBJECT_ID_OCTETS && cinfo->app_oid.value[idx] != -1 ; idx++)
556 printf(".%i", cinfo->app_oid.value[idx]);
557 printf("\n");
558 }
559 printf("\tPath: %s\n", sc_print_path(&cinfo->path));
560 if (objs[i]->auth_id.len == 0) {
561 struct sc_pkcs15_data *data_object;
562 r = sc_pkcs15_read_data_object(p15card, cinfo, &data_object);
563 if (r) {
564 fprintf(stderr, "Data object read failed: %s\n", sc_strerror(r));
565 if (r == SC_ERROR_FILE_NOT_FOUND)
566 continue; /* DEE emulation may say there is a file */
567 return 1;
568 }
569 list_data_object("\tData", data_object->data, data_object->data_len);
570 sc_pkcs15_free_data_object(data_object);
571 }
572 else {
573 printf("\tAuth ID: %s\n", sc_pkcs15_print_id(&objs[i]->auth_id));
574 }
575
576 printf("\n");
577 }
578 return 0;
579 }
580
print_key_usages(int usage)581 static void print_key_usages(int usage)
582 {
583 size_t i;
584 const char *usages[] = {
585 "encrypt", "decrypt", "sign", "signRecover", "wrap", "unwrap",
586 "verify", "verifyRecover", "derive", "nonRepudiation"
587 };
588 const size_t usage_count = NELEMENTS(usages);
589 for (i = 0; i < usage_count; i++)
590 if (usage & (1 << i))
591 printf(", %s", usages[i]);
592 }
593
print_key_access_flags(int flags)594 static void print_key_access_flags(int flags)
595 {
596 size_t i;
597 const char *key_access_flags[] = {
598 "sensitive", "extract", "alwaysSensitive","neverExtract", "local"
599 };
600 const size_t af_count = NELEMENTS(key_access_flags);
601 for (i = 0; i < af_count; i++)
602 if (flags & (1 << i))
603 printf(", %s", key_access_flags[i]);
604 }
605
print_prkey_info(const struct sc_pkcs15_object * obj)606 static void print_prkey_info(const struct sc_pkcs15_object *obj)
607 {
608 struct sc_pkcs15_prkey_info *prkey = (struct sc_pkcs15_prkey_info *) obj->data;
609 unsigned char guid[40];
610 size_t guid_len;
611 int i;
612 int last_algo_refs = 0;
613
614 if (compact) {
615 printf("\t%-3s", key_types[7 & obj->type]);
616
617 if (prkey->modulus_length)
618 printf("[%lu]", (unsigned long)prkey->modulus_length);
619 else {
620 if (prkey->field_length)
621 printf("[%lu]", (unsigned long)prkey->field_length);
622 }
623 printf(" ID:%s", sc_pkcs15_print_id(&prkey->id));
624 printf(" Ref:0x%02X", prkey->key_reference);
625 if (obj->auth_id.len != 0)
626 printf(" AuthID:%s", sc_pkcs15_print_id(&obj->auth_id));
627 printf("\n\t %-18.*s [0x%02X", (int) sizeof obj->label, obj->label, prkey->usage);
628 print_key_usages(prkey->usage);
629 printf("]");
630 return;
631 }
632
633 printf("Private %s Key [%.*s]\n", key_types[7 & obj->type], (int) sizeof obj->label, obj->label);
634 print_common_flags(obj);
635 printf("\tUsage : [0x%02X]", prkey->usage);
636 print_key_usages(prkey->usage);
637 printf("\n");
638 printf("\tAccess Flags : [0x%02X]", prkey->access_flags);
639 print_key_access_flags(prkey->access_flags);
640 printf("\n");
641 printf("\tAlgo_refs : ");
642 /* zero may be valid and don't know how many were read print at least 1*/
643 for (i = 0; i< SC_MAX_SUPPORTED_ALGORITHMS; i++) {
644 if (prkey->algo_refs[i] != 0)
645 last_algo_refs = i;
646 }
647 for (i = 0; i< last_algo_refs + 1; i++) {
648 printf("%s%u", (i == 0) ? "" : ", ", prkey->algo_refs[i]);
649 }
650 printf("\n");
651
652 print_access_rules(obj->access_rules, SC_PKCS15_MAX_ACCESS_RULES);
653
654 if (prkey->modulus_length)
655 printf("\tModLength : %lu\n", (unsigned long)prkey->modulus_length);
656 else
657 printf("\tFieldLength : %lu\n", (unsigned long)prkey->field_length);
658 printf("\tKey ref : %d (0x%02X)\n", prkey->key_reference, prkey->key_reference);
659 printf("\tNative : %s\n", prkey->native ? "yes" : "no");
660 if (prkey->path.len || prkey->path.aid.len)
661 printf("\tPath : %s\n", sc_print_path(&prkey->path));
662 if (obj->auth_id.len != 0)
663 printf("\tAuth ID : %s\n", sc_pkcs15_print_id(&obj->auth_id));
664 printf("\tID : %s\n", sc_pkcs15_print_id(&prkey->id));
665
666 guid_len = sizeof(guid);
667 if (!sc_pkcs15_get_object_guid(p15card, obj, 1, guid, &guid_len)) {
668 printf("\tMD:guid : ");
669 if (strlen((char *)guid) == guid_len) {
670 printf("%s\n", (char *)guid);
671 }
672 else {
673 printf("0x'");
674 util_hex_dump(stdout, guid, guid_len, "");
675 printf("'\n");
676 }
677 }
678 }
679
680
list_private_keys(void)681 static int list_private_keys(void)
682 {
683 int r, i;
684 struct sc_pkcs15_object *objs[32];
685
686 r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, objs, 32);
687 if (r < 0) {
688 fprintf(stderr, "Private key enumeration failed: %s\n", sc_strerror(r));
689 return 1;
690 }
691 if (compact)
692 printf("Card has %d Private key(s).\n", r);
693 else if (verbose)
694 printf("Card has %d Private key(s).\n\n", r);
695 for (i = 0; i < r; i++) {
696 print_prkey_info(objs[i]);
697 printf("\n");
698 }
699 return 0;
700 }
701
print_pubkey_info(const struct sc_pkcs15_object * obj)702 static void print_pubkey_info(const struct sc_pkcs15_object *obj)
703 {
704 const struct sc_pkcs15_pubkey_info *pubkey = (const struct sc_pkcs15_pubkey_info *) obj->data;
705 int have_path = (pubkey->path.len != 0) || (pubkey->path.aid.len != 0);
706
707 if (compact) {
708 printf("\t%-3s", key_types[7 & obj->type]);
709
710 if (pubkey->modulus_length)
711 printf("[%lu]", (unsigned long)pubkey->modulus_length);
712 else
713 printf("[FieldLength:%lu]", (unsigned long)pubkey->field_length);
714 printf(" %s", sc_pkcs15_print_id(&pubkey->id));
715 printf(" Ref:0x%02X", pubkey->key_reference);
716 if (obj->auth_id.len != 0)
717 printf(" AuthID:%s", sc_pkcs15_print_id(&obj->auth_id));
718 printf(" %-18.*s [0x%02X", (int) sizeof obj->label, obj->label, pubkey->usage);
719 print_key_usages(pubkey->usage);
720 printf("]");
721 return;
722 }
723
724 printf("Public %s Key [%.*s]\n", key_types[7 & obj->type], (int) sizeof obj->label, obj->label);
725 print_common_flags(obj);
726 printf("\tUsage : [0x%02X]", pubkey->usage);
727 print_key_usages(pubkey->usage);
728 printf("\n");
729
730 printf("\tAccess Flags : [0x%02X]", pubkey->access_flags);
731 print_key_access_flags(pubkey->access_flags);
732 printf("\n");
733
734 print_access_rules(obj->access_rules, SC_PKCS15_MAX_ACCESS_RULES);
735
736 if (pubkey->modulus_length) {
737 printf("\tModLength : %lu\n", (unsigned long)pubkey->modulus_length);
738 }
739 else if (pubkey->field_length) {
740 printf("\tFieldLength : %lu\n", (unsigned long)pubkey->field_length);
741 }
742 else if ((obj->type == SC_PKCS15_TYPE_PUBKEY_EC || obj->type == SC_PKCS15_TYPE_PUBKEY_EDDSA)
743 && have_path) {
744 sc_pkcs15_pubkey_t *pkey = NULL;
745 if (!sc_pkcs15_read_pubkey(p15card, obj, &pkey)) {
746 printf("\tFieldLength : %lu\n", (unsigned long)pkey->u.ec.params.field_length);
747 sc_pkcs15_free_pubkey(pkey);
748 }
749 }
750
751 printf("\tKey ref : %d (0x%02X)\n", pubkey->key_reference, pubkey->key_reference);
752 printf("\tNative : %s\n", pubkey->native ? "yes" : "no");
753 if (have_path)
754 printf("\tPath : %s\n", sc_print_path(&pubkey->path));
755 if (obj->auth_id.len != 0)
756 printf("\tAuth ID : %s\n", sc_pkcs15_print_id(&obj->auth_id));
757 printf("\tID : %s\n", sc_pkcs15_print_id(&pubkey->id));
758 if (!have_path || obj->content.len)
759 printf("\tDirectValue : <%s>\n", obj->content.len ? "present" : "absent");
760 }
761
list_public_keys(void)762 static int list_public_keys(void)
763 {
764 int r, i;
765 struct sc_pkcs15_object *objs[32];
766
767 r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PUBKEY, objs, 32);
768 if (r < 0) {
769 fprintf(stderr, "Public key enumeration failed: %s\n", sc_strerror(r));
770 return 1;
771 }
772 if (compact)
773 printf("Card has %d Public key(s).\n", r);
774 else if (verbose)
775 printf("Card has %d Public key(s).\n\n", r);
776 for (i = 0; i < r; i++) {
777 print_pubkey_info(objs[i]);
778 printf("\n");
779 }
780 return 0;
781 }
782
read_public_key(void)783 static int read_public_key(void)
784 {
785 int r;
786 struct sc_pkcs15_id id;
787 struct sc_pkcs15_object *obj;
788 sc_pkcs15_pubkey_t *pubkey = NULL;
789 sc_pkcs15_cert_t *cert = NULL;
790 sc_pkcs15_der_t pem_key;
791
792 pem_key.value = NULL;
793 pem_key.len = 0;
794
795 id.len = SC_PKCS15_MAX_ID_SIZE;
796 sc_pkcs15_hex_string_to_id(opt_pubkey, &id);
797
798 r = sc_pkcs15_find_pubkey_by_id(p15card, &id, &obj);
799 if (r >= 0) {
800 if (verbose)
801 printf("Reading public key with ID '%s'\n", opt_pubkey);
802 r = sc_pkcs15_read_pubkey(p15card, obj, &pubkey);
803 } else if (r == SC_ERROR_OBJECT_NOT_FOUND) {
804 /* No pubkey - try if there's a certificate */
805 r = sc_pkcs15_find_cert_by_id(p15card, &id, &obj);
806 if (r >= 0) {
807 if (verbose)
808 printf("Reading certificate with ID '%s'\n", opt_pubkey);
809 r = sc_pkcs15_read_certificate(p15card, (sc_pkcs15_cert_info_t *) obj->data, &cert);
810 }
811 if (r >= 0)
812 pubkey = cert->key;
813 }
814
815 if (r == SC_ERROR_OBJECT_NOT_FOUND) {
816 fprintf(stderr, "Public key with ID '%s' not found.\n", opt_pubkey);
817 r = 2;
818 goto out;
819 }
820 if (r < 0) {
821 fprintf(stderr, "Public key enumeration failed: %s\n", sc_strerror(r));
822 r = 1;
823 goto out;
824 }
825 if (!pubkey) {
826 fprintf(stderr, "Public key not available\n");
827 r = 1;
828 goto out;
829 }
830
831 r = sc_pkcs15_encode_pubkey_as_spki(ctx, pubkey, &pem_key.value, &pem_key.len);
832 if (r < 0) {
833 fprintf(stderr, "Error encoding PEM key: %s\n", sc_strerror(r));
834 r = 1;
835 } else {
836 r = print_pem_object("PUBLIC KEY", pem_key.value, pem_key.len);
837 free(pem_key.value);
838 }
839
840 out:
841 if (cert)
842 sc_pkcs15_free_certificate(cert);
843 else
844 sc_pkcs15_free_pubkey(pubkey);
845
846 return r;
847 }
848
print_skey_info(const struct sc_pkcs15_object * obj)849 static void print_skey_info(const struct sc_pkcs15_object *obj)
850 {
851 static const char *skey_types[] = { "", "Generic", "DES", "2DES", "3DES", "", "", "" };
852 struct sc_pkcs15_skey_info *skey = (struct sc_pkcs15_skey_info *) obj->data;
853 unsigned char guid[40];
854 size_t guid_len;
855
856 printf("Secret %s Key [%.*s]\n", skey_types[7 & obj->type], (int) sizeof obj->label, obj->label);
857 print_common_flags(obj);
858 printf("\tUsage : [0x%02X]", skey->usage);
859 print_key_usages(skey->usage);
860 printf("\n");
861
862 printf("\tAccess Flags : [0x%02X]", skey->access_flags);
863 print_key_access_flags(skey->access_flags);
864 printf("\n");
865
866 print_access_rules(obj->access_rules, SC_PKCS15_MAX_ACCESS_RULES);
867
868 printf("\tSize : %lu bits\n", (unsigned long)skey->value_len);
869 printf("\tID : %s\n", sc_pkcs15_print_id(&skey->id));
870 printf("\tNative : %s\n", skey->native ? "yes" : "no");
871 printf("\tKey ref : %d (0x%02X)\n", skey->key_reference, skey->key_reference);
872
873 if (skey->path.len || skey->path.aid.len)
874 printf("\tPath : %s\n", sc_print_path(&skey->path));
875
876 guid_len = sizeof(guid);
877 if (!sc_pkcs15_get_object_guid(p15card, obj, 1, guid, &guid_len)) {
878 printf("\tGUID : %s\n", (char *)guid);
879 }
880
881 }
882
list_skeys(void)883 static int list_skeys(void)
884 {
885 int r, i;
886 struct sc_pkcs15_object *objs[32];
887
888 r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_SKEY, objs, 32);
889 if (r < 0) {
890 fprintf(stderr, "Secret key enumeration failed: %s\n", sc_strerror(r));
891 return 1;
892 }
893 if (verbose)
894 printf("Card has %d Secret key(s).\n\n", r);
895 for (i = 0; i < r; i++) {
896 print_skey_info(objs[i]);
897 printf("\n");
898 }
899
900 return 0;
901 }
902
903
904 #if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
905
print_ssh_key(FILE * outf,const char * alg,struct sc_pkcs15_object * obj,unsigned char * buf,uint32_t len)906 static void print_ssh_key(FILE *outf, const char * alg, struct sc_pkcs15_object *obj, unsigned char * buf, uint32_t len) {
907 unsigned char *uu;
908 int r;
909
910 uu = malloc(len*2); // Way over - even if we have extra LFs; as each 6 bits take one byte.
911 if (!uu)
912 return;
913
914 if (opt_rfc4716) {
915 r = sc_base64_encode(buf, len, uu, 2*len, 64);
916 if (r < 0) {
917 free(uu);
918 return;
919 }
920
921 fprintf(outf,"---- BEGIN SSH2 PUBLIC KEY ----\n");
922
923 if (obj->label[0] != '\0')
924 fprintf(outf,"Comment: \"%.*s\"\n", (int) sizeof obj->label, obj->label);
925
926 fprintf(outf,"%s", uu);
927 fprintf(outf,"---- END SSH2 PUBLIC KEY ----\n");
928 } else {
929 // Old style openssh - [<quote protected options> <whitespace> <keytype> <whitespace> <key> [<whitespace> anything else]
930 //
931 r = sc_base64_encode(buf, len, uu, 2*len, 0);
932 if (r < 0) {
933 free(uu);
934 return;
935 }
936
937 if (obj->label[0] != '\0')
938 fprintf(outf,"%s %s %.*s\n", alg, uu, (int) sizeof obj->label, obj->label);
939 else
940 fprintf(outf,"%s %s\n", alg, uu);
941 }
942 free(uu);
943 return;
944 }
945
read_ssh_key(void)946 static int read_ssh_key(void)
947 {
948 int r;
949 struct sc_pkcs15_id id;
950 struct sc_pkcs15_object *obj = NULL;
951 sc_pkcs15_pubkey_t *pubkey = NULL;
952 sc_pkcs15_cert_t *cert = NULL;
953 FILE *outf = NULL;
954
955 if (opt_outfile != NULL) {
956 outf = fopen(opt_outfile, "w");
957 if (outf == NULL) {
958 fprintf(stderr, "Error opening file '%s': %s\n", opt_outfile, strerror(errno));
959 goto fail2;
960 }
961 }
962 else {
963 outf = stdout;
964 }
965
966 id.len = SC_PKCS15_MAX_ID_SIZE;
967 sc_pkcs15_hex_string_to_id(opt_pubkey, &id);
968
969 r = sc_pkcs15_find_pubkey_by_id(p15card, &id, &obj);
970 if (r >= 0) {
971 if (verbose)
972 fprintf(stderr,"Reading ssh key with ID '%s'\n", opt_pubkey);
973 r = authenticate(obj);
974 if (r >= 0)
975 r = sc_pkcs15_read_pubkey(p15card, obj, &pubkey);
976 }
977 else if (r == SC_ERROR_OBJECT_NOT_FOUND) {
978 /* No pubkey - try if there's a certificate */
979 r = sc_pkcs15_find_cert_by_id(p15card, &id, &obj);
980 if (r >= 0) {
981 if (verbose)
982 fprintf(stderr,"Reading certificate with ID '%s'\n", opt_pubkey);
983 r = sc_pkcs15_read_certificate(p15card, (sc_pkcs15_cert_info_t *) obj->data, &cert);
984 }
985 if (r >= 0)
986 pubkey = cert->key;
987 }
988
989 if (r == SC_ERROR_OBJECT_NOT_FOUND) {
990 if (opt_outfile != NULL)
991 fclose(outf);
992 fprintf(stderr, "Public key with ID '%s' not found.\n", opt_pubkey);
993 return 2;
994 }
995 if (r < 0) {
996 if (opt_outfile != NULL)
997 fclose(outf);
998 fprintf(stderr, "Public key enumeration failed: %s\n", sc_strerror(r));
999 return 1;
1000 }
1001
1002 if (pubkey->algorithm == SC_ALGORITHM_EDDSA) {
1003 // SSH supports only ed25519 key now
1004
1005 char alg[20];
1006 /* Large enough to fit the following:
1007 * 2 x 4B item length headers
1008 * max 11B algorithm name, 32B key data */
1009 unsigned char buf[64];
1010 unsigned int len, n;
1011
1012 n = pubkey->u.eddsa.pubkey.len;
1013 if (n != 32) {
1014 fprintf(stderr, "Wrong public key length\n");
1015 goto fail2;
1016 }
1017
1018 buf[0] = 0;
1019 buf[1] = 0;
1020 buf[2] = 0;
1021 len = snprintf((char *) buf+4, 20, "ssh-ed25519");
1022 memcpy(alg, buf+4, 20);
1023 buf[3] = len;
1024 len += 4;
1025
1026 buf[len++] = 0;
1027 buf[len++] = 0;
1028 buf[len++] = 0;
1029 buf[len++] = n & 0xff;
1030 memcpy(buf + len, pubkey->u.eddsa.pubkey.value, n);
1031 len += n;
1032
1033 print_ssh_key(outf, alg, obj, buf, len);
1034 }
1035 if (pubkey->algorithm == SC_ALGORITHM_EC) {
1036 // support only for NIST
1037 // 'ssh-keygen -t ecdsa' allow only field lengths 256/384/521
1038
1039 static struct supported_ec_curves {
1040 char *curve_name;
1041 struct sc_object_id curve_oid;
1042 size_t size;
1043 } ec_curves[] = {
1044 {"secp256r1", {{1, 2, 840, 10045, 3, 1, 7, -1}},256},
1045 {"secp384r1", {{1, 3, 132, 0, 34, -1}}, 384},
1046 {"secp521r1", {{1, 3, 132, 0, 35, -1}}, 521},
1047 {NULL, {{-1}}, 0},
1048 };
1049 char alg[20];
1050 /* Large enough to fit the following:
1051 * 3 x 4B item length headers
1052 * max 20B algorithm name, 9B curve name, max 256B key data */
1053 unsigned char buf[300];
1054 unsigned int i, len, tmp, n;
1055
1056 for (n = 0,i = 0; ec_curves[i].curve_name != NULL; i++) {
1057 if(sc_compare_oid (&ec_curves[i].curve_oid,&pubkey->u.ec.params.id))
1058 n = ec_curves[i].size;
1059 }
1060 if (!n) {
1061 fprintf(stderr, "Unsupported curve\n");
1062 goto fail2;
1063 }
1064 if (n != pubkey->u.ec.params.field_length) {
1065 fprintf(stderr, "Wrong field length\n");
1066 goto fail2;
1067 }
1068
1069 buf[0] = 0;
1070 buf[1] = 0;
1071 buf[2] = 0;
1072 len = snprintf((char *) buf+4, 20, "ecdsa-sha2-nistp%d", n);
1073 memcpy(alg, buf+4, 20);
1074 buf[3] = len;
1075
1076 len += 4;
1077 buf[len++] = 0;
1078 buf[len++] = 0;
1079 buf[len++] = 0;
1080 tmp = snprintf((char *) buf+len+1, 9, "nistp%d", n);
1081 buf[len++] = tmp;
1082 len += tmp;
1083
1084 n = pubkey->u.ec.ecpointQ.len;
1085 if(n > 255) {
1086 fprintf(stderr, "Wrong public key length\n");
1087 goto fail2;
1088 }
1089 buf[len++] = 0;
1090 buf[len++] = 0;
1091 buf[len++] = 0;
1092 buf[len++] = n & 0xff;
1093 memcpy(buf+len,pubkey->u.ec.ecpointQ.value,n);
1094 len += n;
1095
1096 print_ssh_key(outf, alg, obj, buf, len);
1097 }
1098
1099 if (pubkey->algorithm == SC_ALGORITHM_RSA) {
1100 unsigned char buf[2048];
1101 uint32_t len, n;
1102
1103 if (!pubkey->u.rsa.modulus.data || !pubkey->u.rsa.modulus.len ||
1104 !pubkey->u.rsa.exponent.data || !pubkey->u.rsa.exponent.len) {
1105 fprintf(stderr, "Failed to decode public RSA key.\n");
1106 goto fail2;
1107 }
1108
1109 buf[0]=0;
1110 buf[1]=0;
1111 buf[2]=0;
1112 buf[3]=7;
1113
1114 len = sprintf((char *) buf+4,"ssh-rsa");
1115 len+=4;
1116
1117 if (sizeof(buf)-len < 4+pubkey->u.rsa.exponent.len)
1118 goto fail;
1119
1120 n = pubkey->u.rsa.exponent.len;
1121 if (pubkey->u.rsa.exponent.data[0] & 0x80)
1122 n++;
1123
1124 buf[len++]=(n >>24) & 0xff;
1125 buf[len++]=(n >>16) & 0xff;
1126 buf[len++]=(n >>8) & 0xff;
1127 buf[len++]=(n) & 0xff;
1128 if (pubkey->u.rsa.exponent.data[0] & 0x80)
1129 buf[len++]= 0;
1130
1131 memcpy(buf+len,pubkey->u.rsa.exponent.data, pubkey->u.rsa.exponent.len);
1132 len += pubkey->u.rsa.exponent.len;
1133
1134 if (sizeof(buf)-len < 5+pubkey->u.rsa.modulus.len)
1135 goto fail;
1136
1137 n = pubkey->u.rsa.modulus.len;
1138 if (pubkey->u.rsa.modulus.data[0] & 0x80)
1139 n++;
1140 buf[len++]=(n >>24) & 0xff;
1141 buf[len++]=(n >>16) & 0xff;
1142 buf[len++]=(n >>8) & 0xff;
1143 buf[len++]=(n) & 0xff;
1144
1145 if (pubkey->u.rsa.modulus.data[0] & 0x80)
1146 buf[len++]= 0;
1147
1148 memcpy(buf+len,pubkey->u.rsa.modulus.data, pubkey->u.rsa.modulus.len);
1149 len += pubkey->u.rsa.modulus.len;
1150
1151 print_ssh_key(outf, "ssh-rsa", obj, buf, len);
1152 }
1153
1154 if (pubkey->algorithm == SC_ALGORITHM_DSA) {
1155 unsigned char buf[2048];
1156 uint32_t len;
1157 uint32_t n;
1158
1159 if (!pubkey->u.dsa.p.data || !pubkey->u.dsa.p.len ||
1160 !pubkey->u.dsa.q.data || !pubkey->u.dsa.q.len ||
1161 !pubkey->u.dsa.g.data || !pubkey->u.dsa.g.len ||
1162 !pubkey->u.dsa.pub.data || !pubkey->u.dsa.pub.len) {
1163 fprintf(stderr, "Failed to decode DSA key.\n");
1164 goto fail2;
1165 }
1166
1167 buf[0]=0;
1168 buf[1]=0;
1169 buf[2]=0;
1170 buf[3]=7;
1171
1172 len = sprintf((char *) buf+4,"ssh-dss");
1173 len+=4;
1174
1175 if (sizeof(buf)-len < 5+pubkey->u.dsa.p.len)
1176 goto fail;
1177
1178 n = pubkey->u.dsa.p.len;
1179 if (pubkey->u.dsa.p.data[0] & 0x80)
1180 n++;
1181
1182 buf[len++]=(n >>24) & 0xff;
1183 buf[len++]=(n >>16) & 0xff;
1184 buf[len++]=(n >>8) & 0xff;
1185 buf[len++]=(n) & 0xff;
1186 if (pubkey->u.dsa.p.data[0] & 0x80)
1187 buf[len++]= 0;
1188
1189 memcpy(buf+len,pubkey->u.dsa.p.data, pubkey->u.dsa.p.len);
1190 len += pubkey->u.dsa.p.len;
1191
1192 if (sizeof(buf)-len < 5+pubkey->u.dsa.q.len)
1193 goto fail;
1194
1195 n = pubkey->u.dsa.q.len;
1196 if (pubkey->u.dsa.q.data[0] & 0x80)
1197 n++;
1198
1199 buf[len++]=(n >>24) & 0xff;
1200 buf[len++]=(n >>16) & 0xff;
1201 buf[len++]=(n >>8) & 0xff;
1202 buf[len++]=(n) & 0xff;
1203 if (pubkey->u.dsa.q.data[0] & 0x80)
1204 buf[len++]= 0;
1205
1206 memcpy(buf+len,pubkey->u.dsa.q.data, pubkey->u.dsa.q.len);
1207 len += pubkey->u.dsa.q.len;
1208
1209 if (sizeof(buf)-len < 5+pubkey->u.dsa.g.len)
1210 goto fail;
1211 n = pubkey->u.dsa.g.len;
1212 if (pubkey->u.dsa.g.data[0] & 0x80)
1213 n++;
1214
1215 buf[len++]=(n >>24) & 0xff;
1216 buf[len++]=(n >>16) & 0xff;
1217 buf[len++]=(n >>8) & 0xff;
1218 buf[len++]=(n) & 0xff;
1219 if (pubkey->u.dsa.g.data[0] & 0x80)
1220 buf[len++]= 0;
1221
1222 memcpy(buf+len,pubkey->u.dsa.g.data, pubkey->u.dsa.g.len);
1223 len += pubkey->u.dsa.g.len;
1224
1225 if (sizeof(buf)-len < 5+pubkey->u.dsa.pub.len)
1226 goto fail;
1227
1228 n = pubkey->u.dsa.pub.len;
1229 if (pubkey->u.dsa.pub.data[0] & 0x80)
1230 n++;
1231
1232 buf[len++]=(n >>24) & 0xff;
1233 buf[len++]=(n >>16) & 0xff;
1234 buf[len++]=(n >>8) & 0xff;
1235 buf[len++]=(n) & 0xff;
1236 if (pubkey->u.dsa.pub.data[0] & 0x80)
1237 buf[len++]= 0;
1238
1239 memcpy(buf+len,pubkey->u.dsa.pub.data, pubkey->u.dsa.pub.len);
1240 len += pubkey->u.dsa.pub.len;
1241
1242 print_ssh_key(outf, "ssh-dss", obj, buf, len);
1243 }
1244
1245 if (opt_outfile != NULL)
1246 fclose(outf);
1247 if (cert)
1248 sc_pkcs15_free_certificate(cert);
1249 else
1250 sc_pkcs15_free_pubkey(pubkey);
1251 return 0;
1252 fail:
1253 printf("can't convert key: buffer too small\n");
1254 fail2:
1255 if (opt_outfile != NULL && outf != NULL)
1256 fclose(outf);
1257 if (cert)
1258 sc_pkcs15_free_certificate(cert);
1259 else
1260 sc_pkcs15_free_pubkey(pubkey);
1261 return SC_ERROR_OUT_OF_MEMORY;
1262 }
1263
1264 #endif
1265
1266 static sc_pkcs15_object_t *
get_pin_info(void)1267 get_pin_info(void)
1268 {
1269 sc_pkcs15_object_t *objs[32], *obj;
1270 int r;
1271
1272 if (opt_auth_id == NULL) {
1273 r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32);
1274 if (r < 0) {
1275 fprintf(stderr, "PIN code enumeration failed: %s\n", sc_strerror(r));
1276 return NULL;
1277 }
1278 if (r == 0) {
1279 fprintf(stderr, "No PIN codes found.\n");
1280 return NULL;
1281 }
1282 obj = objs[0];
1283 } else {
1284 struct sc_pkcs15_id auth_id;
1285
1286 sc_pkcs15_hex_string_to_id(opt_auth_id, &auth_id);
1287 r = sc_pkcs15_find_pin_by_auth_id(p15card, &auth_id, &obj);
1288 if (r) {
1289 fprintf(stderr, "Unable to find PIN code: %s\n", sc_strerror(r));
1290 return NULL;
1291 }
1292 }
1293
1294 return obj;
1295 }
1296
get_pin(const char * prompt,sc_pkcs15_object_t * pin_obj)1297 static u8 * get_pin(const char *prompt, sc_pkcs15_object_t *pin_obj)
1298 {
1299 sc_pkcs15_auth_info_t *pinfo = (sc_pkcs15_auth_info_t *) pin_obj->data;
1300 char *pincode = NULL;
1301 size_t len = 0;
1302 int r;
1303
1304 if (opt_use_pinpad) {
1305 // defer entry of the PIN to the readers pinpad.
1306 if (verbose)
1307 printf("%s [%.*s]: entry deferred to the reader keypad\n", prompt, (int) sizeof pin_obj->label, pin_obj->label);
1308 return NULL;
1309 }
1310
1311 printf("%s [%.*s]: ", prompt, (int) sizeof pin_obj->label, pin_obj->label);
1312 if (pinfo->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1313 return NULL;
1314
1315 while (1) {
1316 r = util_getpass(&pincode, &len, stdin);
1317 if (r < 0)
1318 return NULL;
1319 if (!pincode || strlen(pincode) == 0) {
1320 free(pincode);
1321 return NULL;
1322 }
1323 if (strlen(pincode) < pinfo->attrs.pin.min_length) {
1324 printf("PIN code too short, try again.\n");
1325 continue;
1326 }
1327 if (strlen(pincode) > pinfo->attrs.pin.max_length) {
1328 printf("PIN code too long, try again.\n");
1329 continue;
1330 }
1331 return (u8 *) pincode;
1332 }
1333 }
1334
1335 #ifdef _WIN32
clear_cache(void)1336 static int clear_cache(void)
1337 {
1338 TCHAR dirname[PATH_MAX];
1339 SHFILEOPSTRUCT fileop;
1340 int r;
1341
1342 fileop.hwnd = NULL; // no status display
1343 fileop.wFunc = FO_DELETE; // delete operation
1344 fileop.pFrom = dirname; // source file name as double null terminated string
1345 fileop.pTo = NULL; // no destination needed
1346 fileop.fFlags = FOF_NOCONFIRMATION|FOF_SILENT; // do not prompt the user
1347
1348 fileop.fAnyOperationsAborted = FALSE;
1349 fileop.lpszProgressTitle = NULL;
1350 fileop.hNameMappings = NULL;
1351
1352 /* remove the user's cache directory */
1353 if ((r = sc_get_cache_dir(ctx, dirname, sizeof(dirname))) < 0)
1354 return r;
1355 dirname[_tcslen(dirname)+1] = 0;
1356
1357 printf("Deleting %s...", dirname);
1358 r = SHFileOperation(&fileop);
1359 if (r == 0) {
1360 printf(" OK\n");
1361 } else {
1362 printf(" Error\n");
1363 }
1364
1365 _tcscpy(dirname, _T("C:\\Windows\\System32\\config\\systemprofile\\eid-cache"));
1366 dirname[_tcslen(dirname)+1] = 0;
1367
1368 printf("Deleting %s...", dirname);
1369 r = SHFileOperation(&fileop);
1370 if (r == 0) {
1371 printf(" OK\n");
1372 } else {
1373 printf(" Error\n");
1374 }
1375
1376 return r;
1377 }
1378
1379 #else
1380
unlink_cb(const char * fpath,const struct stat * sb,int typeflag,struct FTW * ftwbuf)1381 static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
1382 {
1383 int r = remove(fpath);
1384 if (r)
1385 perror(fpath);
1386 return r;
1387 }
clear_cache(void)1388 static int clear_cache(void)
1389 {
1390 char dirname[PATH_MAX];
1391 int r = 0;
1392
1393 /* remove the user's cache directory */
1394 if ((r = sc_get_cache_dir(ctx, dirname, sizeof(dirname))) < 0)
1395 return r;
1396 r = nftw(dirname, unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
1397 return r;
1398 }
1399 #endif
1400
1401
verify_pin(void)1402 static int verify_pin(void)
1403 {
1404 struct sc_pkcs15_object *pin_obj = NULL;
1405 unsigned char *pin;
1406 int r;
1407
1408 if (!opt_auth_id) {
1409 struct sc_pkcs15_object *objs[32];
1410 int ii;
1411
1412 r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32);
1413 if (r < 0) {
1414 fprintf(stderr, "PIN code enumeration failed: %s\n", sc_strerror(r));
1415 return -1;
1416 }
1417
1418 for (ii=0;ii<r;ii++) {
1419 struct sc_pkcs15_auth_info *pin_info = (struct sc_pkcs15_auth_info *) objs[ii]->data;
1420
1421 if (pin_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1422 continue;
1423 if (pin_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN)
1424 continue;
1425 if (pin_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN)
1426 continue;
1427
1428 pin_obj = objs[ii];
1429 break;
1430 }
1431 }
1432 else {
1433 pin_obj = get_pin_info();
1434 }
1435
1436 if (!pin_obj) {
1437 fprintf(stderr, "PIN object '%s' not found\n", opt_auth_id);
1438 return -1;
1439 }
1440
1441 if (opt_pin != NULL)
1442 pin = (unsigned char *) opt_pin;
1443 else
1444 pin = get_pin("Please enter PIN", pin_obj);
1445
1446
1447 r = sc_pkcs15_verify_pin(p15card, pin_obj, pin, pin ? strlen((char *) pin) : 0);
1448 if (opt_pin == NULL)
1449 free(pin);
1450 if (r < 0) {
1451 fprintf(stderr, "Operation failed: %s\n", sc_strerror(r));
1452 return -1;
1453 }
1454
1455 return 0;
1456 }
1457
test_session_pin(void)1458 static int test_session_pin(void)
1459 {
1460 struct sc_pkcs15_object *pin_obj = NULL;
1461 struct sc_pkcs15_auth_info *auth_info = NULL;
1462 unsigned int auth_method;
1463 unsigned char *pin;
1464 int r;
1465 unsigned char sessionpin[SC_MAX_PIN_SIZE];
1466 size_t sessionpinlen = sizeof sessionpin;
1467
1468 if (!opt_auth_id) {
1469 struct sc_pkcs15_object *objs[32];
1470 int ii;
1471
1472 r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32);
1473 if (r < 0) {
1474 fprintf(stderr, "PIN code enumeration failed: %s\n", sc_strerror(r));
1475 return -1;
1476 }
1477
1478 for (ii=0;ii<r;ii++) {
1479 struct sc_pkcs15_auth_info *pin_info = (struct sc_pkcs15_auth_info *) objs[ii]->data;
1480
1481 if (pin_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1482 continue;
1483 if (pin_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN)
1484 continue;
1485 if (pin_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN)
1486 continue;
1487
1488 pin_obj = objs[ii];
1489 break;
1490 }
1491 }
1492 else {
1493 pin_obj = get_pin_info();
1494 }
1495
1496 if (!(card->caps & SC_CARD_CAP_SESSION_PIN)) {
1497 fprintf(stderr, "Card does not support session PIN. Will try anyway.\n");
1498 }
1499
1500 if (!pin_obj) {
1501 fprintf(stderr, "PIN object '%s' not found\n", opt_auth_id);
1502 return -1;
1503 }
1504
1505 if (opt_pin != NULL)
1506 pin = (unsigned char *) opt_pin;
1507 else
1508 pin = get_pin("Please enter PIN", pin_obj);
1509
1510 r = sc_pkcs15_verify_pin_with_session_pin(p15card, pin_obj, pin, pin ? strlen((char *) pin) : 0,
1511 sessionpin, &sessionpinlen);
1512 if (opt_pin == NULL)
1513 free(pin);
1514 if (r < 0) {
1515 fprintf(stderr, "Operation failed: %s\n", sc_strerror(r));
1516 return -1;
1517 }
1518
1519 if (!sessionpinlen) {
1520 fprintf(stderr, "Could not generate session PIN\n");
1521 return -1;
1522 }
1523
1524 printf("Generated session PIN (in hexadecimal form): ");
1525 util_hex_dump(stdout, sessionpin, sessionpinlen, "");
1526 puts("");
1527
1528 auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data;
1529 /* save the pin type */
1530 auth_method = auth_info->auth_method;
1531 auth_info->auth_method = SC_AC_SESSION;
1532 r = sc_pkcs15_verify_pin(p15card, pin_obj, sessionpin, sessionpinlen);
1533 /* restore the pin type */
1534 auth_info->auth_method = auth_method;
1535 if (r < 0) {
1536 fprintf(stderr, "Could not verify session PIN: %s\n", sc_strerror(r));
1537 return -1;
1538 }
1539
1540 puts("Verified session PIN");
1541
1542 return 0;
1543 }
1544
authenticate(sc_pkcs15_object_t * obj)1545 static int authenticate(sc_pkcs15_object_t *obj)
1546 {
1547 sc_pkcs15_object_t *pin_obj;
1548 u8 *pin = NULL;
1549 int r;
1550
1551 if (obj->auth_id.len == 0)
1552 return 0;
1553 r = sc_pkcs15_find_pin_by_auth_id(p15card, &obj->auth_id, &pin_obj);
1554 if (r)
1555 return r;
1556
1557 if (opt_pin != NULL)
1558 pin = (u8 *) opt_pin;
1559 else
1560 pin = get_pin("Please enter PIN", pin_obj);
1561
1562 r = sc_pkcs15_verify_pin(p15card, pin_obj, pin, pin? strlen((char *) pin) : 0);
1563
1564 if (opt_pin == NULL)
1565 free(pin);
1566
1567 return r;
1568 }
1569
print_pin_info(const struct sc_pkcs15_object * obj)1570 static void print_pin_info(const struct sc_pkcs15_object *obj)
1571 {
1572 const char *pin_flags[] = {
1573 "case-sensitive", "local", "change-disabled",
1574 "unblock-disabled", "initialized", "needs-padding",
1575 "unblockingPin", "soPin", "disable_allowed",
1576 "integrity-protected", "confidentiality-protected",
1577 "exchangeRefData"
1578 };
1579 const char *pin_types[] = {"bcd", "ascii-numeric", "UTF-8", "halfnibble bcd", "iso 9664-1"};
1580 const struct sc_pkcs15_auth_info *auth_info = (const struct sc_pkcs15_auth_info *) obj->data;
1581 const size_t pf_count = NELEMENTS(pin_flags);
1582 size_t i;
1583
1584 assert(obj->type == SC_PKCS15_TYPE_AUTH_PIN || obj->type == SC_PKCS15_TYPE_AUTH_AUTHKEY);
1585
1586 if (compact) {
1587 printf("\t%-3s ID:%s", obj->type == SC_PKCS15_TYPE_AUTH_PIN ? "PIN" : "Key",
1588 sc_pkcs15_print_id(&auth_info->auth_id));
1589 if (auth_info->auth_type == SC_PKCS15_PIN_AUTH_TYPE_PIN) {
1590 const struct sc_pkcs15_pin_attributes *pin_attrs = &(auth_info->attrs.pin);
1591 printf(" Ref:0x%02X", pin_attrs->reference);
1592 }
1593 else {
1594 const struct sc_pkcs15_authkey_attributes *attrs = &auth_info->attrs.authkey;
1595 printf(" Derived:%i", attrs->derived);
1596 printf(" SecretKeyID:%s", sc_pkcs15_print_id(&attrs->skey_id));
1597 }
1598 if (obj->auth_id.len)
1599 printf(" AuthID:%s", sc_pkcs15_print_id(&obj->auth_id));
1600 if (auth_info->path.len || auth_info->path.aid.len)
1601 printf(" Path:%s", sc_print_path(&auth_info->path));
1602 if (auth_info->tries_left >= 0)
1603 printf(" Tries:%d", auth_info->tries_left);
1604 printf(" %.*s", (int) sizeof obj->label, obj->label);
1605 return;
1606 }
1607
1608 printf("%s [%.*s]\n", obj->type == SC_PKCS15_TYPE_AUTH_PIN ? "PIN" : "AuthKey",
1609 (int) sizeof obj->label, obj->label);
1610
1611 print_common_flags(obj);
1612 if (obj->auth_id.len)
1613 printf("\tAuth ID : %s\n", sc_pkcs15_print_id(&obj->auth_id));
1614
1615 printf("\tID : %s\n", sc_pkcs15_print_id(&auth_info->auth_id));
1616 if (auth_info->auth_type == SC_PKCS15_PIN_AUTH_TYPE_PIN) {
1617 const struct sc_pkcs15_pin_attributes *pin_attrs = &(auth_info->attrs.pin);
1618
1619 printf("\tFlags : [0x%02X]", pin_attrs->flags);
1620 for (i = 0; i < pf_count; i++)
1621 if (pin_attrs->flags & (1 << i))
1622 printf(", %s", pin_flags[i]);
1623 printf("\n");
1624
1625 printf("\tLength : min_len:%lu, max_len:%lu, stored_len:%lu\n",
1626 (unsigned long)pin_attrs->min_length, (unsigned long)pin_attrs->max_length,
1627 (unsigned long)pin_attrs->stored_length);
1628 printf("\tPad char : 0x%02X\n", pin_attrs->pad_char);
1629 printf("\tReference : %d (0x%02X)\n", pin_attrs->reference, pin_attrs->reference);
1630 if (pin_attrs->type < NELEMENTS(pin_types))
1631 printf("\tType : %s\n", pin_types[pin_attrs->type]);
1632 else
1633 printf("\tType : [encoding %d]\n", pin_attrs->type);
1634 }
1635 else if (auth_info->auth_type == SC_PKCS15_PIN_AUTH_TYPE_AUTH_KEY) {
1636 const struct sc_pkcs15_authkey_attributes *attrs = &auth_info->attrs.authkey;
1637 printf("\tDerived : %i\n", attrs->derived);
1638 printf("\tSecretKeyID : %s\n", sc_pkcs15_print_id(&attrs->skey_id));
1639 }
1640
1641 if (auth_info->path.len || auth_info->path.aid.len)
1642 printf("\tPath : %s\n", sc_print_path(&auth_info->path));
1643 if (auth_info->tries_left >= 0)
1644 printf("\tTries left : %d\n", auth_info->tries_left);
1645 }
1646
list_pins(void)1647 static int list_pins(void)
1648 {
1649 int r, i;
1650 struct sc_pkcs15_object *objs[32];
1651
1652 r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH, objs, 32);
1653 if (r < 0) {
1654 fprintf(stderr, "AUTH objects enumeration failed: %s\n", sc_strerror(r));
1655 return 1;
1656 }
1657 if (compact)
1658 printf("Card has %d Authentication object(s).\n", r);
1659 else if (verbose)
1660 printf("Card has %d Authentication object(s).\n\n", r);
1661
1662 for (i = 0; i < r; i++) {
1663 print_pin_info(objs[i]);
1664 printf("\n");
1665 }
1666 return 0;
1667 }
1668
list_apps(FILE * fout)1669 static int list_apps(FILE *fout)
1670 {
1671 unsigned j;
1672 int i;
1673
1674 for (i=0; i<p15card->card->app_count; i++) {
1675 struct sc_app_info *info = p15card->card->app[i];
1676
1677 fprintf(fout, "Application '%s':\n", info->label);
1678 fprintf(fout, "\tAID: ");
1679 for(j=0;j<info->aid.len;j++)
1680 fprintf(fout, "%02X", info->aid.value[j]);
1681 fprintf(fout, "\n");
1682
1683 if (info->ddo.value && info->ddo.len) {
1684 fprintf(fout, "\tDDO: ");
1685 for(j=0;j<info->ddo.len;j++)
1686 fprintf(fout, "%02X", info->ddo.value[j]);
1687 fprintf(fout, "\n");
1688 }
1689
1690 fprintf(fout, "\n");
1691 }
1692 return 0;
1693 }
1694
1695
print_supported_algo_info_operations(unsigned int operation)1696 static void print_supported_algo_info_operations(unsigned int operation)
1697
1698 {
1699 size_t i;
1700 const char *operations[] = {
1701 "compute_checksum", "compute_signature", "verify_checksum", "verify_signature",
1702 "encipher", "decipher", "hash", "generate/derive_key"
1703 };
1704 const size_t operations_count = NELEMENTS(operations);
1705 for (i = 0; i < operations_count; i++)
1706 if (operation & (1 << i))
1707 printf(", %s", operations[i]);
1708 }
1709
list_info(void)1710 static void list_info(void)
1711 {
1712 const char *flags[] = {
1713 "Read-only",
1714 "Login required",
1715 "PRN generation",
1716 "EID compliant"
1717 };
1718 char *last_update = sc_pkcs15_get_lastupdate(p15card);
1719 int i, count = 0;
1720 int idx;
1721
1722 printf("PKCS#15 Card [%s]:\n", p15card->tokeninfo->label);
1723 printf("\tVersion : %d\n", p15card->tokeninfo->version);
1724 printf("\tSerial number : %s\n", p15card->tokeninfo->serial_number);
1725 printf("\tManufacturer ID: %s\n", p15card->tokeninfo->manufacturer_id);
1726 if (last_update)
1727 printf("\tLast update : %s\n", last_update);
1728 if (p15card->tokeninfo->preferred_language)
1729 printf("\tLanguage : %s\n", p15card->tokeninfo->preferred_language);
1730 if (p15card->tokeninfo->profile_indication.name)
1731 printf("\tProfile : %s\n", p15card->tokeninfo->profile_indication.name);
1732 printf("\tFlags : ");
1733 for (i = 0; i < 4; i++) {
1734 if ((p15card->tokeninfo->flags >> i) & 1) {
1735 if (count)
1736 printf(", ");
1737 printf("%s", flags[i]);
1738 count++;
1739 }
1740 }
1741 printf("\n");
1742 for (i = 0; i < SC_MAX_SUPPORTED_ALGORITHMS; i++) {
1743 struct sc_supported_algo_info * sa = &p15card->tokeninfo->supported_algos[i];
1744
1745 if (sa->reference == 0 && sa->mechanism == 0
1746 && sa->operations == 0 && sa->algo_ref == 0)
1747 break;
1748 printf("\t\t sc_supported_algo_info[%d]:\n", i);
1749 printf("\t\t\t reference : %u (0x%02x)\n", sa->reference, sa->reference);
1750 printf("\t\t\t mechanism : [0x%02x] %s\n", sa->mechanism, lookup_enum(MEC_T, sa->mechanism));
1751 if (sc_valid_oid(&sa->parameters)) {
1752 printf("\t\t\t parameters: %i", sa->parameters.value[0]);
1753 for (idx = 1; idx < SC_MAX_OBJECT_ID_OCTETS && sa->parameters.value[idx] != -1 ; idx++)
1754 printf(".%i", sa->parameters.value[idx]);
1755 printf("\n");
1756 }
1757 printf("\t\t\t operations : [0x%2.2x]",sa->operations);
1758 print_supported_algo_info_operations(sa->operations);
1759 printf("\n");
1760 if (sc_valid_oid((const struct sc_object_id*)&sa->algo_id)) {
1761 printf("\t\t\t algo_id : %i", sa->algo_id.value[0]);
1762 for (idx = 1; idx < SC_MAX_OBJECT_ID_OCTETS && sa->algo_id.value[idx] != -1 ; idx++)
1763 printf(".%i", sa->algo_id.value[idx]);
1764 printf("\n");
1765 }
1766 printf("\t\t\t algo_ref : [0x%02x]\n",sa->algo_ref);
1767 }
1768
1769 printf((compact) ? "\n" : "\n\n");
1770 }
1771
dump(void)1772 static int dump(void)
1773 {
1774 list_info();
1775 list_pins();
1776 list_private_keys();
1777 list_public_keys();
1778 list_skeys();
1779 list_certificates();
1780 list_data_objects();
1781
1782 return 0;
1783 }
1784
unblock_pin(void)1785 static int unblock_pin(void)
1786 {
1787 struct sc_pkcs15_auth_info *pinfo = NULL;
1788 sc_pkcs15_object_t *pin_obj;
1789 u8 *pin, *puk;
1790 int r, pinpad_present = 0;
1791
1792 pinpad_present = p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD
1793 || p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH;
1794
1795 if (!(pin_obj = get_pin_info()))
1796 return 2;
1797 pinfo = (sc_pkcs15_auth_info_t *) pin_obj->data;
1798
1799 if (pinfo->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1800 return 1;
1801
1802 puk = (u8 *) opt_puk;
1803 if (puk == NULL) {
1804 sc_pkcs15_object_t *puk_obj = NULL;
1805
1806 if (pin_obj->auth_id.len) {
1807 r = sc_pkcs15_find_pin_by_auth_id(p15card, &pin_obj->auth_id, &puk_obj);
1808 if (r < 0) {
1809 fprintf(stderr, "Failed to find PUK object for PIN: %s\n", sc_strerror(r));
1810 return 2;
1811 }
1812 }
1813
1814 if (puk_obj) {
1815 struct sc_pkcs15_auth_info *puk_info = (sc_pkcs15_auth_info_t *) puk_obj->data;
1816
1817 if (puk_info->auth_type == SC_PKCS15_PIN_AUTH_TYPE_PIN) {
1818 /* TODO: Print PUK's label */
1819 puk = get_pin("Enter PUK", puk_obj);
1820 if (!pinpad_present && puk == NULL)
1821 return 2;
1822 }
1823 }
1824 else {
1825 puk = get_pin("Enter PUK", pin_obj);
1826 if (!pinpad_present && puk == NULL)
1827 return 2;
1828 }
1829 }
1830
1831 if (puk == NULL && verbose)
1832 printf("PUK value will be prompted with pinpad.\n");
1833
1834 /* FIXME should OPENSSL_cleanse on pin/puk data */
1835 pin = opt_pin ? (u8 *) opt_pin : (u8 *) opt_newpin;
1836 while (pin == NULL) {
1837 u8 *pin2;
1838
1839 pin = get_pin("Enter new PIN", pin_obj);
1840 if (pinpad_present && pin == NULL) {
1841 if (verbose)
1842 printf("New PIN value will be prompted with pinpad.\n");
1843 break;
1844 }
1845 if (pin == NULL || strlen((char *) pin) == 0) {
1846 free(pin);
1847 return 2;
1848 }
1849
1850 pin2 = get_pin("Enter new PIN again", pin_obj);
1851 if (pin2 == NULL || strlen((char *) pin2) == 0) {
1852 free(pin);
1853 free(pin2);
1854 return 2;
1855 }
1856 if (strcmp((char *) pin, (char *) pin2) != 0) {
1857 printf("PIN codes do not match, try again.\n");
1858 free(pin);
1859 pin = NULL;
1860 }
1861 free(pin2);
1862 }
1863
1864 r = sc_pkcs15_unblock_pin(p15card, pin_obj,
1865 puk, puk ? strlen((char *) puk) : 0,
1866 pin, pin ? strlen((char *) pin) : 0);
1867
1868 if (NULL == opt_puk)
1869 free(puk);
1870 if (NULL == opt_pin && NULL == opt_newpin)
1871 free(pin);
1872
1873 if (r == SC_ERROR_PIN_CODE_INCORRECT) {
1874 fprintf(stderr, "PUK code incorrect; tries left: %d\n", pinfo->tries_left);
1875 return 3;
1876 } else if (r) {
1877 fprintf(stderr, "PIN unblocking failed: %s\n", sc_strerror(r));
1878 return 2;
1879 }
1880 if (verbose)
1881 printf("PIN successfully unblocked.\n");
1882 return 0;
1883 }
1884
change_pin(void)1885 static int change_pin(void)
1886 {
1887 sc_pkcs15_object_t *pin_obj;
1888 sc_pkcs15_auth_info_t *pinfo = NULL;
1889 u8 *pincode, *newpin;
1890 int r, pinpad_present = 0;
1891
1892 pinpad_present = p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD
1893 || p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH;
1894
1895 if (!(pin_obj = get_pin_info()))
1896 return 2;
1897
1898 pinfo = (sc_pkcs15_auth_info_t *) pin_obj->data;
1899 if (pinfo->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1900 return 1;
1901
1902 if (pinfo->tries_left != -1) {
1903 if (pinfo->tries_left != pinfo->max_tries) {
1904 if (pinfo->tries_left == 0) {
1905 fprintf(stderr, "PIN code blocked!\n");
1906 return 2;
1907 } else {
1908 fprintf(stderr, "%d PIN tries left.\n", pinfo->tries_left);
1909 }
1910 }
1911 }
1912
1913 pincode = (u8 *) opt_pin;
1914 if (pincode == NULL) {
1915 pincode = get_pin("Enter old PIN", pin_obj);
1916 if (!pinpad_present && pincode == NULL)
1917 return 2;
1918 }
1919
1920 if (pincode && strlen((char *) pincode) == 0) {
1921 fprintf(stderr, "No PIN code supplied.\n");
1922 free(pincode);
1923 return 2;
1924 }
1925
1926 if (pincode == NULL && verbose)
1927 printf("Old PIN value will be prompted with pinpad.\n");
1928
1929 newpin = (u8 *) opt_newpin;
1930 while (newpin == NULL) {
1931 u8 *newpin2;
1932
1933 newpin = get_pin("Enter new PIN", pin_obj);
1934 if (pinpad_present && newpin == NULL) {
1935 if (verbose)
1936 printf("New PIN value will be prompted with pinpad.\n");
1937 break;
1938 }
1939 if (newpin == NULL || strlen((char *) newpin) == 0) {
1940 fprintf(stderr, "No new PIN value supplied.\n");
1941 free(newpin);
1942 free(pincode);
1943 return 2;
1944 }
1945
1946 newpin2 = get_pin("Enter new PIN again", pin_obj);
1947 if (newpin2 && strlen((char *) newpin2) &&
1948 strcmp((char *) newpin, (char *) newpin2) == 0) {
1949 free(newpin2);
1950 break;
1951 }
1952 printf("PIN codes do not match, try again.\n");
1953 free(newpin);
1954 free(newpin2);
1955 newpin=NULL;
1956 }
1957
1958 r = sc_pkcs15_change_pin(p15card, pin_obj,
1959 pincode, pincode ? strlen((char *) pincode) : 0,
1960 newpin, newpin ? strlen((char *) newpin) : 0);
1961 if (r == SC_ERROR_PIN_CODE_INCORRECT) {
1962 fprintf(stderr, "PIN code incorrect; tries left: %d\n", pinfo->tries_left);
1963 return 3;
1964 } else if (r) {
1965 fprintf(stderr, "PIN code change failed: %s\n", sc_strerror(r));
1966 return 2;
1967 }
1968 if (verbose)
1969 printf("PIN code changed successfully.\n");
1970
1971 if (opt_pin == NULL)
1972 free(pincode);
1973 if (opt_newpin == NULL)
1974 free(newpin);
1975
1976 return 0;
1977 }
1978
test_update(sc_card_t * in_card)1979 static int test_update(sc_card_t *in_card)
1980 {
1981 sc_apdu_t apdu;
1982 static u8 cmd1[2] = { 0x50, 0x15};
1983 u8 rbuf[258];
1984 int rc;
1985 int r;
1986 static u8 fci_bad[] = { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1987 static u8 fci_good[] = { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00 };
1988
1989 r = sc_lock(card);
1990 if (r < 0)
1991 return r;
1992
1993 if (strcmp("cardos",in_card->driver->short_name) != 0) {
1994 printf("not using the cardos driver, card is fine.\n");
1995 rc = 0;
1996 goto end;
1997 }
1998
1999 /* first select file on 5015 and get fci */
2000 sc_format_apdu(in_card, &apdu, SC_APDU_CASE_4_SHORT, 0xa4, 0x08, 0x00);
2001 apdu.lc = sizeof(cmd1);
2002 apdu.datalen = sizeof(cmd1);
2003 apdu.data = cmd1;
2004 apdu.le = 256;
2005 apdu.resp = rbuf;
2006 apdu.resplen = sizeof(rbuf);
2007
2008 r = sc_transmit_apdu(card, &apdu);
2009 if (r < 0) {
2010 printf("selecting folder failed: %s\n", sc_strerror(r));
2011 rc = 2;
2012 goto end;
2013 }
2014
2015 if (apdu.sw1 != 0x90) {
2016 printf("apdu command select file failed: card returned %02X %02X\n",
2017 apdu.sw1, apdu.sw2);
2018 rc = 2;
2019 goto end;
2020
2021 }
2022
2023 if (apdu.resplen < 6) {
2024 printf("select file did not return enough data (length %d)\n",
2025 (int) apdu.resplen);
2026 goto bad_fci;
2027 }
2028
2029 if (rbuf[0] != 0x6f) {
2030 printf("select file did not return the information we need\n");
2031 goto bad_fci;
2032 }
2033
2034 if (rbuf[1] != apdu.resplen -2) {
2035 printf("select file returned inconsistent information\n");
2036 goto bad_fci;
2037 }
2038
2039 {
2040 size_t i=0;
2041 while(i < rbuf[1]) {
2042 if (rbuf[2+i] == 0x86) { /* found our buffer */
2043 break;
2044 }
2045 /* other tag */
2046 i += 2 + rbuf[2+i+1]; /* length of this tag*/
2047 }
2048 if (rbuf[2+i+1] < 9 || 2+i+2+9 > apdu.resplen) {
2049 printf("select file returned short fci\n");
2050 goto bad_fci;
2051 }
2052
2053 if (memcmp(&rbuf[2+i+2],fci_good,sizeof(fci_good)) == 0) {
2054 printf("fci is up-to-date, card is fine\n");
2055 rc = 0;
2056 goto end;
2057 }
2058
2059 if (memcmp(&rbuf[2+i+2],fci_bad,sizeof(fci_bad)) == 0) {
2060 printf("fci is out-of-date, card is vulnerable\n");
2061 rc = 1;
2062 goto end;
2063 }
2064
2065 printf("select file returned fci with unknown data\n");
2066 goto bad_fci;
2067 }
2068 end:
2069 sc_unlock(card);
2070 /* 0 = card ok, 1 = card vulnerable, 2 = problem! */
2071 return rc;
2072
2073 bad_fci:
2074 sc_unlock(card);
2075 util_hex_dump(stdout,rbuf,apdu.resplen," ");
2076 printf("\n");
2077 return 2;
2078 }
2079
update(sc_card_t * in_card)2080 static int update(sc_card_t *in_card)
2081 {
2082 sc_apdu_t apdu;
2083 u8 rbuf[258];
2084 static u8 cmd1[2] = { 0x50, 0x15};
2085 static u8 cmd3[11] = { 0x86, 0x09, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
2086 0xff, 0x00, 0x00};
2087 int r;
2088
2089 /* first select file on 5015 */
2090 sc_format_apdu(in_card, &apdu, SC_APDU_CASE_3_SHORT, 0xa4, 0x08, 0x00);
2091 apdu.lc = sizeof(cmd1);
2092 apdu.datalen = sizeof(cmd1);
2093 apdu.data = cmd1;
2094
2095 r = sc_lock(card);
2096 if (r < 0)
2097 return r;
2098
2099 r = sc_transmit_apdu(card, &apdu);
2100 if (r < 0) {
2101 printf("selecting folder failed: %s\n", sc_strerror(r));
2102 goto end;
2103 }
2104
2105 if (apdu.sw1 != 0x90) {
2106 printf("apdu command select file: card returned %02X %02X\n",
2107 apdu.sw1, apdu.sw2);
2108 goto end;
2109
2110 }
2111
2112 /* next get lifecycle */
2113 memset(&apdu, 0, sizeof(apdu));
2114 sc_format_apdu(in_card, &apdu, SC_APDU_CASE_2, 0xca, 0x01, 0x83);
2115 apdu.cla = 0x00;
2116 apdu.le = 256;
2117 apdu.resp = rbuf;
2118 apdu.resplen = sizeof(rbuf);
2119
2120 r = sc_transmit_apdu(card, &apdu);
2121 if (r < 0) {
2122 printf("get lifecycle failed: %s\n", sc_strerror(r));
2123 goto end;
2124 }
2125
2126 if (apdu.sw1 != 0x90) {
2127 printf("get lifecycle failed: card returned %02X %02X\n",
2128 apdu.sw1, apdu.sw2);
2129 goto end;
2130
2131 }
2132
2133 if (apdu.resplen < 1) {
2134 printf("get lifecycle failed: lifecycle byte not in response\n");
2135 goto end;
2136 }
2137
2138 if (rbuf[0] != 0x10 && rbuf[0] != 0x20) {
2139 printf("lifecycle neither user nor admin, can't proceed\n");
2140 goto end;
2141 }
2142
2143 if (rbuf[0] == 0x20)
2144 goto skip_change_lifecycle;
2145
2146 /* next phase control / change lifecycle to operational */
2147 memset(&apdu, 0, sizeof(apdu));
2148 sc_format_apdu(in_card, &apdu, SC_APDU_CASE_1, 0x10, 0x00, 0x00);
2149 apdu.cla = 0x80;
2150
2151 r = sc_transmit_apdu(card, &apdu);
2152 if (r < 0) {
2153 printf("change lifecycle failed: %s\n", sc_strerror(r));
2154 goto end;
2155 }
2156
2157 if (apdu.sw1 != 0x90) {
2158 printf("apdu command change lifecycle failed: card returned %02X %02X\n",
2159 apdu.sw1, apdu.sw2);
2160 goto end;
2161
2162 }
2163
2164 skip_change_lifecycle:
2165 /* last update AC */
2166 memset(&apdu, 0, sizeof(apdu));
2167 sc_format_apdu(in_card, &apdu, SC_APDU_CASE_3_SHORT, 0xda, 0x01, 0x6f);
2168 apdu.lc = sizeof(cmd3);
2169 apdu.datalen = sizeof(cmd3);
2170 apdu.data = cmd3;
2171 apdu.le = 0;
2172 apdu.resplen = 0;
2173 apdu.resp = NULL;
2174
2175 r = sc_transmit_apdu(card, &apdu);
2176 if (r < 0) {
2177 printf("update fci failed: %s\n", sc_strerror(r));
2178 goto end;
2179 }
2180
2181 if (apdu.sw1 != 0x90) {
2182 printf("apdu command update fci failed: card returned %02X %02X\n",
2183 apdu.sw1, apdu.sw2);
2184 goto end;
2185
2186 }
2187
2188 printf("security update applied successfully.\n");
2189 end:
2190 sc_unlock(card);
2191 return 0;
2192 }
2193
main(int argc,char * argv[])2194 int main(int argc, char *argv[])
2195 {
2196 int err = 0, r, c, long_optind = 0;
2197 int do_read_cert = 0;
2198 int do_list_certs = 0;
2199 int do_read_data_object = 0;
2200 int do_list_data_objects = 0;
2201 int do_list_pins = 0;
2202 int do_list_skeys = 0;
2203 int do_list_apps = 0;
2204 int do_dump = 0;
2205 int do_list_prkeys = 0;
2206 int do_list_pubkeys = 0;
2207 int do_read_pubkey = 0;
2208 #if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
2209 int do_read_sshkey = 0;
2210 #endif
2211 int do_verify_pin = 0;
2212 int do_change_pin = 0;
2213 int do_unblock_pin = 0;
2214 int do_test_update = 0;
2215 int do_test_session_pin = 0;
2216 int do_update = 0;
2217 int do_print_version = 0;
2218 int do_list_info = 0;
2219 int action_count = 0;
2220 sc_context_param_t ctx_param;
2221
2222 assert(sizeof(option_help)/sizeof(char *)==sizeof(options)/sizeof(struct option));
2223
2224 while (1) {
2225 c = getopt_long(argc, argv, "r:cuko:sva:LR:CwDTU", options, &long_optind);
2226 if (c == -1)
2227 break;
2228 if (c == '?')
2229 util_print_usage_and_die(app_name, options, option_help, NULL);
2230 switch (c) {
2231 case 'r':
2232
2233 #if OPENSC_MAJOR == 0 && OPENSC_VERSION_MINOR == 19
2234 fprintf(stderr, "\nWarning, option -r is reserved to specify card reader in future versions\n");
2235 fprintf (stderr, "Using -r option for read-certificate operation\n\n");
2236 opt_cert = optarg;
2237 do_read_cert = 1;
2238 action_count++;
2239 break;
2240 #elif OPENSC_MAJOR == 0 && OPENSC_VERSION_MINOR == 20
2241
2242 memset(&ctx_param, 0, sizeof(ctx_param));
2243 ctx_param.ver = 0;
2244 ctx_param.app_name = app_name;
2245
2246 if (SC_SUCCESS == sc_context_create(&ctx, &ctx_param)) {
2247 /* attempt to connect reader, on error, -r is used for read-certificate operation */
2248 struct sc_reader *reader = NULL;
2249
2250 err = util_connect_reader(ctx, &reader, optarg, 0, 0);
2251 sc_release_context(ctx);
2252 ctx = NULL;
2253
2254 if (err != SC_SUCCESS ) {
2255 #if 1
2256 fprintf (stderr,
2257 "Error, option -r is reserved to specify card reader, no reader \"%s\" found\n", optarg);
2258 exit (1);
2259 #else
2260 fprintf (stderr,
2261 "\nWarning, option -r is reserved to specify card reader, no reader \"%s\" found\n", optarg);
2262 fprintf (stderr, "Using -r option for read-certificate operation\n\n");
2263 opt_cert = optarg;
2264 do_read_cert = 1;
2265 action_count++;
2266 break;
2267 #endif
2268 }
2269 }
2270 opt_reader = optarg;
2271 break;
2272 #elif (OPENSC_MAJOR > 0) || (OPENSC_MAJOR == 0 && OPENSC_VERSION_MINOR > 20)
2273
2274 opt_reader = optarg;
2275 break;
2276 #endif
2277
2278 case OPT_PRINT_VERSION:
2279 do_print_version = 1;
2280 action_count++;
2281 break;
2282 case OPT_LIST_INFO:
2283 do_list_info = 1;
2284 action_count++;
2285 break;
2286 case OPT_READ_CERT:
2287 opt_cert = optarg;
2288 do_read_cert = 1;
2289 action_count++;
2290 break;
2291 case 'c':
2292 do_list_certs = 1;
2293 action_count++;
2294 break;
2295 case 'R':
2296 opt_data = optarg;
2297 do_read_data_object = 1;
2298 action_count++;
2299 break;
2300 case OPT_RAW:
2301 opt_raw = 1;
2302 break;
2303 case 'C':
2304 do_list_data_objects = 1;
2305 action_count++;
2306 break;
2307 case OPT_VERIFY_PIN:
2308 do_verify_pin = 1;
2309 action_count++;
2310 break;
2311 case OPT_CHANGE_PIN:
2312 do_change_pin = 1;
2313 action_count++;
2314 break;
2315 case 'u':
2316 do_unblock_pin = 1;
2317 action_count++;
2318 break;
2319 case OPT_LIST_PINS:
2320 do_list_pins = 1;
2321 action_count++;
2322 break;
2323 case OPT_LIST_SKEYS:
2324 do_list_skeys = 1;
2325 action_count++;
2326 break;
2327 case 'D':
2328 do_dump = 1;
2329 action_count++;
2330 break;
2331 case 'k':
2332 do_list_prkeys = 1;
2333 action_count++;
2334 break;
2335 case OPT_LIST_PUB:
2336 do_list_pubkeys = 1;
2337 action_count++;
2338 break;
2339 case OPT_READ_PUB:
2340 opt_pubkey = optarg;
2341 do_read_pubkey = 1;
2342 action_count++;
2343 break;
2344 #if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
2345 case OPT_READ_SSH:
2346 opt_pubkey = optarg;
2347 do_read_sshkey = 1;
2348 action_count++;
2349 break;
2350 case OPT_RFC4716:
2351 opt_rfc4716 = 1;
2352 break;
2353 #endif
2354 case 'T':
2355 do_test_update = 1;
2356 action_count++;
2357 break;
2358 case OPT_TEST_SESSION_PIN:
2359 do_test_session_pin = 1;
2360 action_count++;
2361 break;
2362 case 'U':
2363 do_update = 1;
2364 action_count++;
2365 break;
2366 case OPT_READER:
2367 opt_reader = optarg;
2368 break;
2369 case OPT_PIN:
2370 util_get_pin(optarg, &opt_pin);
2371 break;
2372 case OPT_NEWPIN:
2373 util_get_pin(optarg, &opt_newpin);
2374 break;
2375 case OPT_PUK:
2376 util_get_pin(optarg, &opt_puk);
2377 break;
2378 case 'o':
2379 opt_outfile = optarg;
2380 break;
2381 case 's':
2382 compact++;
2383 break;
2384 case 'v':
2385 verbose++;
2386 break;
2387 case 'a':
2388 opt_auth_id = optarg;
2389 break;
2390 case OPT_BIND_TO_AID:
2391 opt_bind_to_aid = optarg;
2392 break;
2393 case OPT_LIST_APPLICATIONS:
2394 do_list_apps = 1;
2395 action_count++;
2396 break;
2397 case OPT_NO_CACHE:
2398 opt_no_cache++;
2399 break;
2400 case OPT_CLEAR_CACHE:
2401 opt_clear_cache = 1;
2402 action_count++;
2403 break;
2404 case 'w':
2405 opt_wait = 1;
2406 break;
2407 case OPT_USE_PINPAD_DEPRECATED:
2408 fprintf(stderr, "'--no-prompt' is deprecated , use '--use-pinpad' instead.\n");
2409 /* fallthrough */
2410 case OPT_USE_PINPAD:
2411 opt_use_pinpad = 1;
2412 break;
2413 }
2414 }
2415 if (action_count == 0)
2416 util_print_usage_and_die(app_name, options, option_help, NULL);
2417
2418 if (do_print_version) {
2419 printf("%s\n", OPENSC_SCM_REVISION);
2420 action_count--;
2421 }
2422
2423 memset(&ctx_param, 0, sizeof(ctx_param));
2424 ctx_param.ver = 0;
2425 ctx_param.app_name = app_name;
2426
2427 r = sc_context_create(&ctx, &ctx_param);
2428 if (r) {
2429 fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r));
2430 return 1;
2431 }
2432
2433 if (opt_clear_cache) {
2434 if ((err = clear_cache()))
2435 goto end;
2436 action_count--;
2437 }
2438
2439 err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0, verbose);
2440 if (err)
2441 goto end;
2442
2443 if (verbose)
2444 fprintf(stderr, "Trying to find a PKCS#15 compatible card...\n");
2445
2446 if (opt_bind_to_aid) {
2447 struct sc_aid aid;
2448
2449 aid.len = sizeof(aid.value);
2450 if (sc_hex_to_bin(opt_bind_to_aid, aid.value, &aid.len)) {
2451 fprintf(stderr, "Invalid AID value: '%s'\n", opt_bind_to_aid);
2452 return 1;
2453 }
2454
2455 r = sc_pkcs15_bind(card, &aid, &p15card);
2456 }
2457 else {
2458 r = sc_pkcs15_bind(card, NULL, &p15card);
2459 }
2460
2461 if (r) {
2462 fprintf(stderr, "PKCS#15 binding failed: %s\n", sc_strerror(r));
2463 err = 1;
2464 goto end;
2465 }
2466 if (opt_no_cache)
2467 p15card->opts.use_file_cache = 0;
2468 if (verbose)
2469 fprintf(stderr, "Found %s!\n", p15card->tokeninfo->label);
2470
2471 if (do_list_info) {
2472 if (!do_dump)
2473 list_info();
2474 action_count--;
2475 }
2476
2477 if (do_verify_pin)
2478 if ((err = verify_pin()))
2479 goto end;
2480
2481 if (do_list_certs) {
2482 if ((err = list_certificates()))
2483 goto end;
2484 action_count--;
2485 }
2486 if (do_read_cert) {
2487 if ((err = read_certificate()))
2488 goto end;
2489 action_count--;
2490 }
2491 if (do_list_data_objects) {
2492 if ((err = list_data_objects()))
2493 goto end;
2494 action_count--;
2495 }
2496 if (do_read_data_object) {
2497 if ((err = read_data_object()))
2498 goto end;
2499 action_count--;
2500 }
2501 if (do_list_prkeys) {
2502 if ((err = list_private_keys()))
2503 goto end;
2504 action_count--;
2505 }
2506 if (do_list_pubkeys) {
2507 if ((err = list_public_keys()))
2508 goto end;
2509 action_count--;
2510 }
2511 if (do_read_pubkey) {
2512 if ((err = read_public_key()))
2513 goto end;
2514 action_count--;
2515 }
2516 #if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
2517 if (do_read_sshkey) {
2518 if ((err = read_ssh_key()))
2519 goto end;
2520 action_count--;
2521 }
2522 #endif
2523 if (do_list_pins) {
2524 if ((err = list_pins()))
2525 goto end;
2526 action_count--;
2527 }
2528 if (do_list_skeys) {
2529 if ((err = list_skeys()))
2530 goto end;
2531 action_count--;
2532 }
2533 if (do_list_apps) {
2534 if ((err = list_apps(stdout)))
2535 goto end;
2536 action_count--;
2537 }
2538 if (do_dump) {
2539 if ((err = dump()))
2540 goto end;
2541 action_count--;
2542 }
2543 if (do_change_pin) {
2544 if ((err = change_pin()))
2545 goto end;
2546 action_count--;
2547 }
2548 if (do_unblock_pin) {
2549 if ((err = unblock_pin()))
2550 goto end;
2551 action_count--;
2552 }
2553 if (do_test_update || do_update) {
2554 err = test_update(card);
2555 action_count--;
2556 if (err == 2) { /* problem */
2557 err = 1;
2558 goto end;
2559 }
2560 if (do_update && err == 1) { /* card vulnerable */
2561 if ((err = update(card)))
2562 goto end;
2563 }
2564 }
2565 if (do_test_session_pin) {
2566 if ((err = test_session_pin()))
2567 goto end;
2568 action_count--;
2569 }
2570 end:
2571 sc_pkcs15_unbind(p15card);
2572 sc_disconnect_card(card);
2573 sc_release_context(ctx);
2574 return err;
2575 }
2576