Coverage Report

Created: 2026-01-13 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/tools/piv-tool.c
Line
Count
Source
1
/*
2
 * piv-tool.c: Tool for accessing smart cards with libopensc
3
 *
4
 * Copyright (C) 2001  Juha Yrjölä <juha.yrjola@iki.fi>
5
 * Copyright (C) 2005,2010 Douglas E. Engert <deengert@gmail.com>
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
#include "config.h"
23
24
#include <stdio.h>
25
#include <stdlib.h>
26
#ifdef HAVE_UNISTD_H
27
#include <unistd.h>
28
#endif
29
#include <string.h>
30
#include <errno.h>
31
#include <ctype.h>
32
#include <sys/stat.h>
33
34
/* Module only built if OPENSSL is enabled */
35
#include <openssl/opensslv.h>
36
#include <openssl/opensslconf.h>
37
#include <openssl/crypto.h>
38
#include <openssl/conf.h>
39
40
#include <openssl/rsa.h>
41
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
42
# include <openssl/param_build.h>
43
# include <openssl/params.h>
44
#endif
45
#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA)
46
#include <openssl/ec.h>
47
#include <openssl/ecdsa.h>
48
#endif
49
#include <openssl/evp.h>
50
#include <openssl/x509.h>
51
#include <openssl/bn.h>
52
#include <openssl/bio.h>
53
#include <openssl/pem.h>
54
#include <openssl/err.h>
55
#include <openssl/obj_mac.h>
56
57
#include "libopensc/opensc.h"
58
#include "libopensc/cardctl.h"
59
#include "libopensc/cards.h"
60
#include "libopensc/asn1.h"
61
#include "libopensc/log.h"
62
#include "util.h"
63
#include "libopensc/sc-ossl-compat.h"
64
65
static const char *app_name = "piv-tool";
66
67
static int  opt_wait = 0;
68
static char **  opt_apdus;
69
static char * opt_reader;
70
static int  opt_apdu_count = 0;
71
static int  verbose = 0;
72
73
enum {
74
  OPT_SERIAL = 0x100,
75
};
76
77
static const struct option options[] = {
78
  { "serial",   0, NULL,  OPT_SERIAL  },
79
  { "name",   0, NULL,    'n' },
80
  { "admin",    1, NULL,    'A' },
81
  { "genkey",   1, NULL,    'G' },
82
  { "object",   1, NULL,    'O' },
83
  { "cert",   1, NULL,    'C' },
84
  { "compresscert", 1, NULL,    'Z' },
85
  { "out",    1, NULL,    'o' },
86
  { "in",     1, NULL,    'i' },
87
  { "send-apdu",    1, NULL,    's' },
88
  { "reader",   1, NULL,    'r' },
89
  { "wait",   0, NULL,    'w' },
90
  { "verbose",    0, NULL,    'v' },
91
  { NULL, 0, NULL, 0 }
92
};
93
94
static const char *option_help[] = {
95
  "Print the card serial number",
96
  "Identify the card and print its name",
97
  "Authenticate using default 3DES key",
98
  "Generate key <ref>:<alg> 9A:06 on card, and output pubkey",
99
  "Load an object <containerID> containerID as defined in 800-73 without leading 0x",
100
  "Load a cert <ref> where <ref> is 9A,9C,9D or 9E",
101
  "Load a cert that has been gzipped <ref>",
102
  "Output file for cert or key",
103
  "Input file for cert",
104
  "Sends an APDU in format AA:BB:CC:DD:EE:FF...",
105
  "Uses reader number <arg> [0]",
106
  "Wait for a card to be inserted",
107
  "Verbose operation, may be used several times",
108
};
109
110
static sc_context_t *ctx = NULL;
111
static sc_card_t *card = NULL;
112
static BIO *bp = NULL;
113
114
static int load_object(const char * object_id, const char * object_file)
115
12
{
116
12
  FILE *fp = NULL;
117
12
  sc_path_t path;
118
12
  size_t derlen;
119
12
  u8 *der = NULL;
120
12
  u8 *body;
121
12
  size_t bodylen;
122
12
  int r = -1;
123
12
  struct stat stat_buf;
124
125
12
  if (!object_file || (fp = fopen(object_file, "rb")) == NULL) {
126
10
    printf("Cannot open object file, %s %s\n",
127
10
        (object_file) ? object_file : "", strerror(errno));
128
10
    goto err;
129
10
  }
130
131
2
  if (0 != stat(object_file, &stat_buf)) {
132
0
    printf("unable to read file %s\n", object_file);
133
0
    goto err;
134
0
  }
135
2
  derlen = stat_buf.st_size;
136
2
  der = malloc(derlen);
137
2
  if (der == NULL) {
138
0
    printf("file %s is too big, %lu\n",
139
0
    object_file, (unsigned long)derlen);
140
0
    goto err;
141
0
  }
142
2
  if (1 != fread(der, derlen, 1, fp)) {
143
1
    printf("unable to read file %s\n",object_file);
144
1
    goto err;
145
1
  }
146
  /* check if tag and length are valid */
147
1
  body = (u8 *)sc_asn1_find_tag(card->ctx, der, derlen, 0x53, &bodylen);
148
1
  if (body == NULL || derlen != body - der + bodylen) {
149
1
    fprintf(stderr, "object tag or length not valid\n");
150
1
    goto err;
151
1
  }
152
153
0
  sc_format_path(object_id, &path);
154
155
0
  r = sc_select_file(card, &path, NULL);
156
0
  if (r < 0) {
157
0
    fprintf(stderr, "select file failed\n");
158
0
    r = -1;
159
0
    goto err;
160
0
  }
161
  /* leave 8 bits for flags, and pass in total length */
162
0
  r = sc_write_binary(card, 0, der, derlen, derlen<<8);
163
164
12
err:
165
12
  free(der);
166
12
  if (fp)
167
2
    fclose(fp);
168
169
12
  return r;
170
0
}
171
172
173
static int load_cert(const char * cert_id, const char * cert_file,
174
          int compress)
175
43
{
176
43
  X509 * cert = NULL;
177
43
  FILE *fp = NULL;
178
43
  u8 buf[1];
179
43
  size_t buflen = 1;
180
43
  sc_path_t path;
181
43
  u8 *der = NULL;
182
43
  u8 *p;
183
43
  size_t derlen;
184
43
  int r = -1;
185
186
43
  if (!cert_file) {
187
17
    printf("Missing cert file\n");
188
17
    goto err;
189
17
  }
190
191
26
  if ((fp = fopen(cert_file, "rb")) == NULL) {
192
4
    printf("Cannot open cert file, %s %s\n",
193
4
        cert_file, strerror(errno));
194
4
    goto err;
195
4
  }
196
22
  if (compress) { /* file is gzipped already */
197
20
    struct stat stat_buf;
198
199
20
    if (0 != stat(cert_file, &stat_buf)) {
200
0
      printf("unable to read file %s\n", cert_file);
201
0
      goto err;
202
0
    }
203
20
    derlen = stat_buf.st_size;
204
20
    der = malloc(derlen);
205
20
    if (der == NULL) {
206
0
      printf("file %s is too big, %lu\n",
207
0
        cert_file, (unsigned long)derlen);
208
0
      goto err;
209
0
    }
210
20
    if (1 != fread(der, derlen, 1, fp)) {
211
1
      printf("unable to read file %s\n", cert_file);
212
1
      goto err;
213
1
    }
214
20
  } else {
215
2
    cert = PEM_read_X509(fp, &cert, NULL, NULL);
216
2
    if (cert == NULL) {
217
2
      sc_log_openssl(ctx);
218
2
      printf("file %s does not contain PEM-encoded certificate\n", cert_file);
219
2
      goto err;
220
2
    }
221
222
0
    derlen = i2d_X509(cert, NULL);
223
0
    der = malloc(derlen);
224
0
    if (!der) {
225
0
      goto err;
226
0
    }
227
0
    p = der;
228
0
    i2d_X509(cert, &p);
229
0
  }
230
19
  sc_hex_to_bin(cert_id, buf,&buflen);
231
232
19
  switch (buf[0]) {
233
2
    case 0x9a: sc_format_path("0101",&path); break;
234
4
    case 0x9c: sc_format_path("0100",&path); break;
235
1
    case 0x9d: sc_format_path("0102",&path); break;
236
11
    case 0x9e: sc_format_path("0500",&path); break;
237
1
    default:
238
1
      fprintf(stderr,"cert must be 9A, 9C, 9D or 9E\n");
239
1
      r = 2;
240
1
      goto err;
241
19
  }
242
243
18
  r = sc_select_file(card, &path, NULL);
244
18
  if (r < 0) {
245
0
    fprintf(stderr, "select file failed\n");
246
0
    goto err;
247
0
  }
248
  /* we pass length  and  8 bits of flag to card-piv.c write_binary */
249
  /* pass in its a cert and if needs compress */
250
18
  r = sc_write_binary(card, 0, der, derlen, (derlen << 8) | (compress << 4) | 1);
251
252
43
err:
253
43
  free(der);
254
43
  if (fp)
255
22
    fclose(fp);
256
257
43
  return r;
258
18
}
259
static int admin_mode(const char* admin_info)
260
220
{
261
220
  int r;
262
220
  u8 opts[3];
263
220
  size_t buflen = 2;
264
265
266
220
  if (admin_info && strlen(admin_info) == 7 &&
267
201
      (admin_info[0] == 'A' || admin_info[0] == 'M') &&
268
183
      admin_info[1] == ':' &&
269
167
      (sc_hex_to_bin(admin_info+2, opts+1, &buflen) == 0) &&
270
166
      buflen == 2) {
271
164
    opts[0] = admin_info[0];
272
164
  } else {
273
56
    fprintf(stderr, " admin_mode params <M|A>:<keyref>:<alg>\n");
274
56
    return -1;
275
56
  }
276
277
164
  r = sc_card_ctl(card, SC_CARDCTL_PIV_AUTHENTICATE, &opts);
278
164
  if (r)
279
164
    fprintf(stderr, " admin_mode failed %d\n", r);
280
164
  return r;
281
220
}
282
283
/* generate a new key pair, and save public key in newkey */
284
static int gen_key(const char * key_info)
285
244
{
286
244
  int r = 1;
287
244
  u8 buf[2];
288
244
  size_t buflen = 2;
289
244
  sc_cardctl_piv_genkey_info_t
290
244
    keydata = {0, 0, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0};
291
244
  EVP_PKEY *evpkey = NULL;
292
244
#if !defined(OPENSSL_NO_EC)
293
244
  int nid = -1;
294
244
#endif
295
296
244
  sc_hex_to_bin(key_info, buf, &buflen);
297
244
  if (buflen != 2) {
298
101
    fprintf(stderr, "<keyref>:<algid> invalid, example: 9A:06\n");
299
101
    return 2;
300
101
  }
301
143
  switch (buf[0]) {
302
13
    case 0x9a:
303
20
    case 0x9c:
304
88
    case 0x9d:
305
129
    case 0x9e:
306
129
      keydata.key_num = buf[0];
307
129
      break;
308
14
    default:
309
14
      fprintf(stderr, "<keyref>:<algid> must be 9A, 9C, 9D or 9E\n");
310
14
      return 2;
311
143
  }
312
313
129
  switch (buf[1]) {
314
29
    case 0x05: keydata.key_bits = 3072; break;
315
22
    case 0x06: keydata.key_bits = 1024; break;
316
11
    case 0x07: keydata.key_bits = 2048; break;
317
0
#if !defined(OPENSSL_NO_EC)
318
42
    case 0x11: keydata.key_bits = 0;
319
42
      nid = NID_X9_62_prime256v1; /* We only support one curve per algid */
320
42
      break;
321
5
    case 0x14: keydata.key_bits = 0;
322
5
      nid = NID_secp384r1;
323
5
      break;
324
5
    case 0xE0:
325
5
      keydata.key_bits = 0;
326
5
      nid = NID_ED25519;
327
5
      break;
328
10
    case 0xE1:
329
10
      keydata.key_bits = 0;
330
10
      nid = NID_X25519;
331
10
      break;
332
0
#endif
333
5
    default:
334
5
      fprintf(stderr, "<keyref>:<algid> algid=RSA - 05, 06, 07 for 3072, 1024, 2048;EC - 11, 14 for 256, 384\n");
335
5
      return 2;
336
129
  }
337
338
124
  keydata.key_algid = buf[1];
339
340
341
124
  r = sc_card_ctl(card, SC_CARDCTL_PIV_GENERATE_KEY, &keydata);
342
124
  if (r) {
343
110
    fprintf(stderr, "gen_key failed %d\n", r);
344
110
    return 1;
345
110
  }
346
347
14
#if OPENSSL_VERSION_NUMBER < 0x30000000L
348
14
  evpkey = EVP_PKEY_new();
349
14
  if (!evpkey) {
350
0
    sc_log_openssl(ctx);
351
0
    fprintf(stderr, "allocation of key failed\n");
352
0
    r = 1;
353
0
    goto out;
354
0
  }
355
14
#endif
356
357
14
  if (keydata.key_bits > 0) { /* RSA key */
358
4
    BIGNUM *newkey_n, *newkey_e;
359
4
#if OPENSSL_VERSION_NUMBER < 0x30000000L
360
4
    RSA *newkey = NULL;
361
#else
362
    EVP_PKEY_CTX *cctx = NULL;
363
    OSSL_PARAM_BLD *bld = NULL;
364
    OSSL_PARAM *params = NULL;
365
#endif
366
367
4
    if (!keydata.pubkey || !keydata.exponent) {
368
0
      fprintf(stderr, "gen_key failed %d\n", r);
369
0
      r = 1;
370
0
      goto out;
371
0
    }
372
373
4
    newkey_n = BN_bin2bn(keydata.pubkey, (int)keydata.pubkey_len, NULL);
374
4
    newkey_e = BN_bin2bn(keydata.exponent, (int)keydata.exponent_len, NULL);
375
4
    if (!newkey_n || !newkey_e) {
376
0
      sc_log_openssl(ctx);
377
0
      fprintf(stderr, "conversion or key params failed\n");
378
0
      r = 1;
379
0
      goto out;
380
0
    }
381
382
4
#if OPENSSL_VERSION_NUMBER < 0x30000000L
383
4
    newkey = RSA_new();
384
4
    if (!newkey) {
385
0
      sc_log_openssl(ctx);
386
0
      fprintf(stderr, "gen_key RSA_new failed\n");
387
0
      r = 1;
388
0
      goto out;
389
0
    }
390
391
4
    if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1) {
392
0
      sc_log_openssl(ctx);
393
0
      RSA_free(newkey);
394
0
      BN_free(newkey_n);
395
0
      BN_free(newkey_e);
396
0
      fprintf(stderr, "gen_key unable to set RSA values");
397
0
      r = 1;
398
0
      goto out;
399
0
    }
400
401
4
    if (verbose)
402
4
      RSA_print_fp(stdout, newkey, 0);
403
404
4
    if (EVP_PKEY_assign_RSA(evpkey, newkey) != 1) {
405
0
      sc_log_openssl(ctx);
406
0
      RSA_free(newkey);
407
0
      BN_free(newkey_n);
408
0
      BN_free(newkey_e);
409
0
      fprintf(stderr, "gen_key unable to set RSA values");
410
0
      r = 1;
411
0
      goto out;
412
0
    }
413
#else
414
    if (!(bld = OSSL_PARAM_BLD_new()) ||
415
        OSSL_PARAM_BLD_push_BN(bld, "n", newkey_n) != 1 ||
416
        OSSL_PARAM_BLD_push_BN(bld, "e", newkey_e) != 1 ||
417
        !(params = OSSL_PARAM_BLD_to_param(bld))) {
418
      sc_log_openssl(ctx);
419
      OSSL_PARAM_BLD_free(bld);
420
      BN_free(newkey_n);
421
      BN_free(newkey_e);
422
      r = 1;
423
      goto out;
424
    }
425
426
    OSSL_PARAM_BLD_free(bld);
427
    BN_free(newkey_n);
428
    BN_free(newkey_e);
429
430
    cctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
431
    if (!cctx ||
432
        EVP_PKEY_fromdata_init(cctx) != 1 ||
433
        EVP_PKEY_fromdata(cctx, &evpkey, EVP_PKEY_KEYPAIR, params) != 1) {
434
      sc_log_openssl(ctx);
435
      EVP_PKEY_CTX_free(cctx);
436
      OSSL_PARAM_free(params);
437
      fprintf(stderr, "gen_key unable to gen RSA");
438
      r = 1;
439
      goto out;
440
    }
441
    if (verbose)
442
      EVP_PKEY_print_public_fp(stdout, evpkey, 0, NULL);
443
444
    EVP_PKEY_CTX_free(cctx);
445
    OSSL_PARAM_free(params);
446
#endif
447
448
4
#ifdef EVP_PKEY_ED25519
449
10
  } else if (nid == NID_ED25519 || nid == NID_X25519) {
450
6
#if OPENSSL_VERSION_NUMBER < 0x30000000L
451
6
    fprintf(stderr, "This build of OpenSSL does not support ED25519 or X25519 keys\n");
452
6
    r = 1;
453
6
    goto out;
454
#else
455
    if (!keydata.ecpoint) {
456
      fprintf(stderr, "gen_key failed\n");
457
      r = 1;
458
      goto out;
459
    }
460
    evpkey = EVP_PKEY_new_raw_public_key(nid, NULL, keydata.ecpoint, keydata.ecpoint_len);
461
    if (!evpkey) {
462
      sc_log_openssl(ctx);
463
      fprintf(stderr, "gen key failed ti copy 25519 pubkey\n");
464
      r = 1;
465
      goto out;
466
    }
467
468
    if (verbose)
469
      EVP_PKEY_print_public_fp(stdout, evpkey, 0, NULL);
470
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
471
#else
472
    fprintf(stderr, "This build of OpenSSL does not support ED25519 or X25519 keys\n");
473
    return -1;
474
#endif     /* EVP_PKEY_ED25519 */
475
6
  } else { /* EC key */
476
4
#if !defined(OPENSSL_NO_EC)
477
4
    int i;
478
4
    BIGNUM *x = NULL;
479
4
    BIGNUM *y = NULL;
480
4
    EC_GROUP * ecgroup = NULL;
481
4
    EC_POINT * ecpoint = NULL;
482
4
#if OPENSSL_VERSION_NUMBER < 0x30000000L
483
4
    EC_KEY * eckey = NULL;
484
#else
485
    EVP_PKEY_CTX *cctx = NULL;
486
    OSSL_PARAM_BLD *bld = NULL;
487
    OSSL_PARAM *params = NULL;
488
    size_t len = 0;
489
    unsigned char * buf = NULL;
490
    const char *group_name;
491
#endif
492
493
4
    if (!keydata.ecpoint) {
494
0
      fprintf(stderr, "gen_key failed\n");
495
0
      r = 1;
496
0
      goto out;
497
0
    }
498
499
4
    ecgroup = EC_GROUP_new_by_curve_name(nid);
500
4
    EC_GROUP_set_asn1_flag(ecgroup, OPENSSL_EC_NAMED_CURVE);
501
4
    ecpoint = EC_POINT_new(ecgroup);
502
503
    /* PIV returns 04||x||y  and x and y are the same size */
504
4
    i = (int)(keydata.ecpoint_len - 1) / 2;
505
4
    x = BN_bin2bn(keydata.ecpoint + 1, i, NULL);
506
4
    y = BN_bin2bn(keydata.ecpoint + 1 + i, i, NULL);
507
4
    if (!x || !y) {
508
0
      sc_log_openssl(ctx);
509
0
      BN_free(x);
510
0
      BN_free(y);
511
0
      EC_GROUP_free(ecgroup);
512
0
      EC_POINT_free(ecpoint);
513
0
      r = 1;
514
0
      goto out;
515
0
    }
516
4
    r = EC_POINT_set_affine_coordinates(ecgroup, ecpoint, x, y, NULL);
517
518
4
    BN_free(x);
519
4
    BN_free(y);
520
521
4
    if (r == 0) {
522
4
      sc_log_openssl(ctx);
523
4
      fprintf(stderr, "EC_POINT_set_affine_coordinates_GFp failed\n");
524
4
      EC_GROUP_free(ecgroup);
525
4
      EC_POINT_free(ecpoint);
526
4
      r = 1;
527
4
      goto out;
528
4
    }
529
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
530
0
    eckey = EC_KEY_new();
531
0
    if (eckey == NULL) {
532
0
      sc_log_openssl(ctx);
533
0
      fprintf(stderr, "EC_KEY_new failed\n");
534
0
      EC_GROUP_free(ecgroup);
535
0
      EC_POINT_free(ecpoint);
536
0
      r = 1;
537
0
      goto out;
538
0
    }
539
0
    r = EC_KEY_set_group(eckey, ecgroup);
540
0
    EC_GROUP_free(ecgroup);
541
0
    if (r == 0) {
542
0
      sc_log_openssl(ctx);
543
0
      fprintf(stderr, "EC_KEY_set_group failed\n");
544
0
      EC_POINT_free(ecpoint);
545
0
      EC_KEY_free(eckey);
546
0
      r = 1;
547
0
      goto out;
548
0
    }
549
0
    r = EC_KEY_set_public_key(eckey, ecpoint);
550
0
    EC_POINT_free(ecpoint);
551
0
    if (r == 0) {
552
0
      sc_log_openssl(ctx);
553
0
      fprintf(stderr, "EC_KEY_set_public_key failed\n");
554
0
      EC_KEY_free(eckey);
555
0
      r = 1;
556
0
      goto out;
557
0
    }
558
559
0
    if (verbose)
560
0
      EC_KEY_print_fp(stdout, eckey, 0);
561
562
0
    if (EVP_PKEY_assign_EC_KEY(evpkey, eckey) != 1) {
563
0
      EC_KEY_free(eckey);
564
0
      sc_log_openssl(ctx);
565
0
      r = 1;
566
0
      goto out;
567
0
    }
568
#else
569
    group_name = OBJ_nid2sn(nid);
570
    len = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL);
571
    if (!(buf = malloc(len))) {
572
      sc_log_openssl(ctx);
573
      fprintf(stderr, "EC_KEY_set_public_key out of memory\n");
574
      EC_GROUP_free(ecgroup);
575
      EC_POINT_free(ecpoint);
576
      r = 1;
577
      goto out;
578
    }
579
    if (EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_COMPRESSED, buf, len, NULL) == 0) {
580
      sc_log_openssl(ctx);
581
      fprintf(stderr, "EC_KEY_set_public_key failed\n");
582
      EC_GROUP_free(ecgroup);
583
      EC_POINT_free(ecpoint);
584
      free(buf);
585
      r = 1;
586
      goto out;
587
    }
588
589
    EC_GROUP_free(ecgroup);
590
    EC_POINT_free(ecpoint);
591
592
    if (!(bld = OSSL_PARAM_BLD_new()) ||
593
        OSSL_PARAM_BLD_push_utf8_string(bld, "group", group_name, strlen(group_name)) != 1 ||
594
        OSSL_PARAM_BLD_push_octet_string(bld, "pub", buf, len) != 1 ||
595
        !(params = OSSL_PARAM_BLD_to_param(bld))) {
596
      sc_log_openssl(ctx);
597
      OSSL_PARAM_BLD_free(bld);
598
      free(buf);
599
      r = 1;
600
      goto out;
601
    }
602
    free(buf);
603
    OSSL_PARAM_BLD_free(bld);
604
605
    cctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
606
    if (!cctx ||
607
        EVP_PKEY_fromdata_init(cctx) != 1 ||
608
        EVP_PKEY_fromdata(cctx, &evpkey, EVP_PKEY_KEYPAIR, params) != 1) {
609
      sc_log_openssl(ctx);
610
      fprintf(stderr, "gen_key unable to gen EC key");
611
      EVP_PKEY_CTX_free(cctx);
612
      OSSL_PARAM_free(params);
613
      r = 1;
614
      goto out;
615
    }
616
    if (verbose)
617
      EVP_PKEY_print_public_fp(stdout, evpkey, 0, NULL);
618
619
    EVP_PKEY_CTX_free(cctx);
620
    OSSL_PARAM_free(params);
621
#endif
622
#else  /* OPENSSL_NO_EC */
623
    fprintf(stderr, "This build of OpenSSL does not support EC keys\n");
624
    r = 1;
625
#endif /* OPENSSL_NO_EC */
626
627
0
  }
628
629
4
  if (bp) {
630
4
    r = i2d_PUBKEY_bio(bp, evpkey);
631
4
    if (r != 1) {
632
2
      sc_log_openssl(ctx);
633
2
      fprintf(stderr, "Failed to encode public key");
634
2
      r = 1;
635
2
      goto out;
636
2
    }
637
4
  }
638
2
  r = SC_SUCCESS;
639
14
out:
640
14
  free(keydata.pubkey);
641
14
  free(keydata.exponent);
642
14
  free(keydata.ecpoint);
643
644
14
  EVP_PKEY_free(evpkey);
645
646
14
  return r;
647
2
}
648
649
650
static int send_apdu(void)
651
918
{
652
918
  sc_apdu_t apdu;
653
918
  u8 buf[SC_MAX_APDU_BUFFER_SIZE+3];
654
918
  u8 rbuf[8192];
655
918
  size_t len0, i;
656
918
  int r;
657
918
  int c;
658
659
27.7k
  for (c = 0; c < opt_apdu_count; c++) {
660
27.2k
    len0 = sizeof(buf);
661
27.2k
    sc_hex_to_bin(opt_apdus[c], buf, &len0);
662
663
27.2k
    r = sc_bytes2apdu(card->ctx, buf, len0, &apdu);
664
27.2k
    if (r) {
665
397
      fprintf(stderr, "Invalid APDU: %s\n", sc_strerror(r));
666
397
      return 2;
667
397
    }
668
669
26.8k
    apdu.resp = rbuf;
670
26.8k
    apdu.resplen = sizeof(rbuf);
671
672
26.8k
    printf("Sending: ");
673
139k
    for (i = 0; i < len0; i++)
674
112k
      printf("%02X ", buf[i]);
675
26.8k
    printf("\n");
676
26.8k
    r = sc_transmit_apdu(card, &apdu);
677
26.8k
    if (r) {
678
75
      fprintf(stderr, "APDU transmit failed: %s\n", sc_strerror(r));
679
75
      return 1;
680
75
    }
681
26.8k
    printf("Received (SW1=0x%02X, SW2=0x%02X)%s\n", apdu.sw1, apdu.sw2,
682
26.8k
           apdu.resplen ? ":" : "");
683
26.8k
    if (apdu.resplen)
684
2.30k
      util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);
685
26.8k
  }
686
446
  return 0;
687
918
}
688
689
static void print_serial(sc_card_t *in_card)
690
253
{
691
253
  int r;
692
253
  sc_serial_number_t serial;
693
694
253
  r = sc_card_ctl(in_card, SC_CARDCTL_GET_SERIALNR, &serial);
695
253
  if (r < 0)
696
212
    fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_GET_SERIALNR, *) failed %d\n", r);
697
41
  else
698
41
    util_hex_dump_asc(stdout, serial.value, serial.len, -1);
699
253
}
700
701
int main(int argc, char *argv[])
702
3.30k
{
703
3.30k
  int err = 0, r, c;
704
3.30k
  int do_send_apdu = 0;
705
3.30k
  int do_admin_mode = 0;
706
3.30k
  int do_gen_key = 0;
707
3.30k
  int do_load_cert = 0;
708
3.30k
  int do_load_object = 0;
709
3.30k
  int compress_cert = 0;
710
3.30k
  int do_print_serial = 0;
711
3.30k
  int do_print_name = 0;
712
3.30k
  int action_count = 0;
713
3.30k
  const char *out_file = NULL;
714
3.30k
  const char *in_file = NULL;
715
3.30k
  const char *cert_id = NULL;
716
3.30k
  const char *object_id = NULL;
717
3.30k
  const char *key_info = NULL;
718
3.30k
  const char *admin_info = NULL;
719
3.30k
  sc_context_param_t ctx_param;
720
3.30k
  char **old_apdus = NULL;
721
722
3.21M
  while ((c = getopt_long(argc, argv, "nA:G:O:Z:C:i:o:r:fvs:c:w", options, (int *) 0)) != -1) {
723
3.21M
    switch (c) {
724
466
    case OPT_SERIAL:
725
466
      do_print_serial = 1;
726
466
      action_count++;
727
466
      break;
728
31.8k
    case 's':
729
31.8k
      old_apdus = opt_apdus;
730
31.8k
      opt_apdus = (char **) realloc(opt_apdus,
731
31.8k
          (opt_apdu_count + 1) * sizeof(char *));
732
31.8k
      if (!opt_apdus) {
733
0
        free(old_apdus);
734
0
        err = 1;
735
0
        goto end;
736
0
      }
737
31.8k
      opt_apdus[opt_apdu_count] = optarg;
738
31.8k
      do_send_apdu++;
739
31.8k
      if (opt_apdu_count == 0)
740
992
        action_count++;
741
31.8k
      opt_apdu_count++;
742
31.8k
      break;
743
144k
    case 'n':
744
144k
      do_print_name = 1;
745
144k
      action_count++;
746
144k
      break;
747
427
    case 'A':
748
427
      do_admin_mode = 1;
749
427
      admin_info = optarg;
750
427
      action_count++;
751
427
      break;
752
462
    case 'G':
753
462
      do_gen_key = 1;
754
462
      key_info = optarg;
755
462
      action_count++;
756
462
      break;
757
212
    case 'O':
758
212
      do_load_object = 1;
759
212
      object_id = optarg;
760
212
      action_count++;
761
212
      break;
762
434
    case 'Z':
763
434
      compress_cert = 1;
764
      /* fall through */
765
1.19k
    case 'C':
766
1.19k
      do_load_cert = 1;
767
1.19k
      cert_id = optarg;
768
1.19k
      action_count++;
769
1.19k
      break;
770
234
    case 'i':
771
234
      in_file = optarg;
772
234
      break;
773
198
    case 'o':
774
198
      out_file = optarg;
775
198
      break;
776
414
    case 'r':
777
414
      opt_reader = optarg;
778
414
      break;
779
3.01M
    case 'v':
780
3.01M
      verbose++;
781
3.01M
      break;
782
16.6k
    case 'w':
783
16.6k
      opt_wait = 1;
784
16.6k
      break;
785
7
    default:
786
7
      util_print_usage(app_name, options, option_help, NULL);
787
7
      if (opt_apdus)
788
1
        free(opt_apdus);
789
7
      return 2;
790
3.21M
    }
791
3.21M
  }
792
793
3.30k
  if (action_count == 0) {
794
75
    util_print_usage(app_name, options, option_help, NULL);
795
75
    if (opt_apdus)
796
0
      free(opt_apdus);
797
75
    return 2;
798
75
  }
799
800
3.22k
  if (out_file) {
801
11
    bp = BIO_new(BIO_s_file());
802
11
    if (!BIO_write_filename(bp, (char *)out_file))
803
5
      goto end;
804
3.21k
  } else {
805
3.21k
    bp = BIO_new(BIO_s_file());
806
3.21k
    BIO_set_fp(bp,stdout,BIO_NOCLOSE);
807
3.21k
  }
808
809
3.22k
  memset(&ctx_param, 0, sizeof(sc_context_param_t));
810
3.22k
  ctx_param.app_name = app_name;
811
3.22k
  ctx_param.debug    = verbose;
812
3.22k
  if (verbose)
813
3.21k
    ctx_param.debug_file = stderr;
814
815
3.22k
  r = sc_context_create(&ctx, &ctx_param);
816
3.22k
  if (r != SC_SUCCESS) {
817
0
    fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r));
818
0
    return 1;
819
0
  }
820
821
3.22k
  if (action_count <= 0)
822
0
    goto end;
823
824
  /* force PIV card driver */
825
3.22k
  err = sc_set_card_driver(ctx, "PIV-II");
826
3.22k
  if (err) {
827
0
    fprintf(stderr, "PIV card driver not found!\n");
828
0
    err = 1;
829
0
    goto end;
830
0
  }
831
832
3.22k
  err = util_connect_card(ctx, &card, opt_reader, opt_wait);
833
3.22k
  if (err)
834
1.47k
    goto end;
835
836
  /* fail if card is not a PIV card */
837
1.74k
  if (card->type < SC_CARD_TYPE_PIV_II_BASE || card->type >= SC_CARD_TYPE_PIV_II_BASE+1000) {
838
0
    fprintf(stderr, "Card type %X: not a PIV card\n", card->type);
839
0
    err = 1;
840
0
    goto end;
841
0
  }
842
843
1.74k
  if (do_admin_mode) {
844
220
    if ((err = admin_mode(admin_info)))
845
220
      goto end;
846
0
    action_count--;
847
0
  }
848
1.52k
  if (do_send_apdu) {   /* can use pin before load cert for a beta card */
849
918
    if ((err = send_apdu()))
850
472
      goto end;
851
446
    action_count--;
852
446
  }
853
1.05k
  if (do_gen_key) {
854
244
    if ((err = gen_key(key_info)))
855
242
      goto end;
856
2
    action_count--;
857
2
  }
858
815
  if (do_load_object) {
859
12
    if ((err = load_object(object_id, in_file)))
860
12
      goto end;
861
0
    action_count--;
862
0
  }
863
803
  if (do_load_cert) {
864
43
    if ((err = load_cert(cert_id, in_file, compress_cert)))
865
43
      goto end;
866
0
    action_count--;
867
0
  }
868
760
  if (do_print_serial) {
869
253
    if (verbose)
870
253
      printf("Card serial number:");
871
253
    print_serial(card);
872
253
    action_count--;
873
253
  }
874
760
  if (do_print_name) {
875
181
    if (verbose)
876
181
      printf("Card name: ");
877
181
    printf("%s\n", card->name);
878
181
    action_count--;
879
181
  }
880
3.22k
end:
881
3.22k
  if (bp)
882
3.22k
    BIO_free(bp);
883
3.22k
  if (card) {
884
1.74k
    sc_unlock(card);
885
1.74k
    sc_disconnect_card(card);
886
1.74k
  }
887
3.22k
  if (opt_apdus)
888
991
    free(opt_apdus);
889
3.22k
  sc_release_context(ctx);
890
891
  ERR_print_errors_fp(stderr);
892
3.22k
  return err;
893
760
}