Coverage Report

Created: 2025-07-11 06:59

/src/opensc/src/tools/piv-tool.c
Line
Count
Source (jump to first uncovered line)
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
4
{
116
4
  FILE *fp = NULL;
117
4
  sc_path_t path;
118
4
  size_t derlen;
119
4
  u8 *der = NULL;
120
4
  u8 *body;
121
4
  size_t bodylen;
122
4
  int r = -1;
123
4
  struct stat stat_buf;
124
125
4
  if (!object_file || (fp = fopen(object_file, "rb")) == NULL) {
126
3
    printf("Cannot open object file, %s %s\n",
127
3
        (object_file) ? object_file : "", strerror(errno));
128
3
    goto err;
129
3
  }
130
131
1
  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
1
  derlen = stat_buf.st_size;
136
1
  der = malloc(derlen);
137
1
  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
1
  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
0
  body = (u8 *)sc_asn1_find_tag(card->ctx, der, derlen, 0x53, &bodylen);
148
0
  if (body == NULL || derlen != body - der + bodylen) {
149
0
    fprintf(stderr, "object tag or length not valid\n");
150
0
    goto err;
151
0
  }
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
4
err:
165
4
  free(der);
166
4
  if (fp)
167
1
    fclose(fp);
168
169
4
  return r;
170
0
}
171
172
173
static int load_cert(const char * cert_id, const char * cert_file,
174
          int compress)
175
25
{
176
25
  X509 * cert = NULL;
177
25
  FILE *fp = NULL;
178
25
  u8 buf[1];
179
25
  size_t buflen = 1;
180
25
  sc_path_t path;
181
25
  u8 *der = NULL;
182
25
  u8 *p;
183
25
  size_t derlen;
184
25
  int r = -1;
185
186
25
  if (!cert_file) {
187
22
    printf("Missing cert file\n");
188
22
    goto err;
189
22
  }
190
191
3
  if ((fp = fopen(cert_file, "rb")) == NULL) {
192
1
    printf("Cannot open cert file, %s %s\n",
193
1
        cert_file, strerror(errno));
194
1
    goto err;
195
1
  }
196
2
  if (compress) { /* file is gzipped already */
197
1
    struct stat stat_buf;
198
199
1
    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
1
    derlen = stat_buf.st_size;
204
1
    der = malloc(derlen);
205
1
    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
1
    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
1
  } else {
215
1
    cert = PEM_read_X509(fp, &cert, NULL, NULL);
216
1
    if (cert == NULL) {
217
1
      sc_log_openssl(ctx);
218
1
      printf("file %s does not contain PEM-encoded certificate\n", cert_file);
219
1
      goto err;
220
1
    }
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
0
  sc_hex_to_bin(cert_id, buf,&buflen);
231
232
0
  switch (buf[0]) {
233
0
    case 0x9a: sc_format_path("0101",&path); break;
234
0
    case 0x9c: sc_format_path("0100",&path); break;
235
0
    case 0x9d: sc_format_path("0102",&path); break;
236
0
    case 0x9e: sc_format_path("0500",&path); break;
237
0
    default:
238
0
      fprintf(stderr,"cert must be 9A, 9C, 9D or 9E\n");
239
0
      r = 2;
240
0
      goto err;
241
0
  }
242
243
0
  r = sc_select_file(card, &path, NULL);
244
0
  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
0
  r = sc_write_binary(card, 0, der, derlen, (derlen << 8) | (compress << 4) | 1);
251
252
25
err:
253
25
  free(der);
254
25
  if (fp)
255
2
    fclose(fp);
256
257
25
  return r;
258
0
}
259
static int admin_mode(const char* admin_info)
260
235
{
261
235
  int r;
262
235
  u8 opts[3];
263
235
  size_t buflen = 2;
264
265
266
235
  if (admin_info && strlen(admin_info) == 7 &&
267
235
      (admin_info[0] == 'A' || admin_info[0] == 'M') &&
268
235
      admin_info[1] == ':' &&
269
235
      (sc_hex_to_bin(admin_info+2, opts+1, &buflen) == 0) &&
270
235
      buflen == 2) {
271
183
    opts[0] = admin_info[0];
272
183
  } else {
273
52
    fprintf(stderr, " admin_mode params <M|A>:<keyref>:<alg>\n");
274
52
    return -1;
275
52
  }
276
277
183
  r = sc_card_ctl(card, SC_CARDCTL_PIV_AUTHENTICATE, &opts);
278
183
  if (r)
279
183
    fprintf(stderr, " admin_mode failed %d\n", r);
280
183
  return r;
281
235
}
282
283
/* generate a new key pair, and save public key in newkey */
284
static int gen_key(const char * key_info)
285
283
{
286
283
  int r = 1;
287
283
  u8 buf[2];
288
283
  size_t buflen = 2;
289
283
  sc_cardctl_piv_genkey_info_t
290
283
    keydata = {0, 0, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0};
291
283
  EVP_PKEY *evpkey = NULL;
292
283
#if !defined(OPENSSL_NO_EC)
293
283
  int nid = -1;
294
283
#endif
295
296
283
  sc_hex_to_bin(key_info, buf, &buflen);
297
283
  if (buflen != 2) {
298
131
    fprintf(stderr, "<keyref>:<algid> invalid, example: 9A:06\n");
299
131
    return 2;
300
131
  }
301
152
  switch (buf[0]) {
302
10
    case 0x9a:
303
17
    case 0x9c:
304
96
    case 0x9d:
305
140
    case 0x9e:
306
140
      keydata.key_num = buf[0];
307
140
      break;
308
12
    default:
309
12
      fprintf(stderr, "<keyref>:<algid> must be 9A, 9C, 9D or 9E\n");
310
12
      return 2;
311
152
  }
312
313
140
  switch (buf[1]) {
314
28
    case 0x05: keydata.key_bits = 3072; break;
315
23
    case 0x06: keydata.key_bits = 1024; break;
316
10
    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
13
    case 0x14: keydata.key_bits = 0;
322
13
      nid = NID_secp384r1;
323
13
      break;
324
9
    case 0xE0:
325
9
      keydata.key_bits = 0;
326
9
      nid = NID_ED25519;
327
9
      break;
328
5
    case 0xE1:
329
5
      keydata.key_bits = 0;
330
5
      nid = NID_X25519;
331
5
      break;
332
0
#endif
333
10
    default:
334
10
      fprintf(stderr, "<keyref>:<algid> algid=RSA - 05, 06, 07 for 3072, 1024, 2048;EC - 11, 14 for 256, 384\n");
335
10
      return 2;
336
140
  }
337
338
130
  keydata.key_algid = buf[1];
339
340
341
130
  r = sc_card_ctl(card, SC_CARDCTL_PIV_GENERATE_KEY, &keydata);
342
130
  if (r) {
343
113
    fprintf(stderr, "gen_key failed %d\n", r);
344
113
    return 1;
345
113
  }
346
347
17
#if OPENSSL_VERSION_NUMBER < 0x30000000L
348
17
  evpkey = EVP_PKEY_new();
349
17
  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
17
#endif
356
357
17
  if (keydata.key_bits > 0) { /* RSA key */
358
8
    BIGNUM *newkey_n, *newkey_e;
359
8
#if OPENSSL_VERSION_NUMBER < 0x30000000L
360
8
    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
8
    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
8
    newkey_n = BN_bin2bn(keydata.pubkey, (int)keydata.pubkey_len, NULL);
374
8
    newkey_e = BN_bin2bn(keydata.exponent, (int)keydata.exponent_len, NULL);
375
8
    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
8
#if OPENSSL_VERSION_NUMBER < 0x30000000L
383
8
    newkey = RSA_new();
384
8
    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
8
    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
8
    if (verbose)
402
8
      RSA_print_fp(stdout, newkey, 0);
403
404
8
    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
8
#ifdef EVP_PKEY_ED25519
449
9
  } else if (nid == NID_ED25519 || nid == NID_X25519) {
450
7
#if OPENSSL_VERSION_NUMBER < 0x30000000L
451
7
    fprintf(stderr, "This build of OpenSSL does not support ED25519 or X25519 keys\n");
452
7
    r = 1;
453
7
    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
7
  } else { /* EC key */
476
2
#if !defined(OPENSSL_NO_EC)
477
2
    int i;
478
2
    BIGNUM *x = NULL;
479
2
    BIGNUM *y = NULL;
480
2
    EC_GROUP * ecgroup = NULL;
481
2
    EC_POINT * ecpoint = NULL;
482
2
#if OPENSSL_VERSION_NUMBER < 0x30000000L
483
2
    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
2
    if (!keydata.ecpoint) {
494
0
      fprintf(stderr, "gen_key failed\n");
495
0
      r = 1;
496
0
      goto out;
497
0
    }
498
499
2
    ecgroup = EC_GROUP_new_by_curve_name(nid);
500
2
    EC_GROUP_set_asn1_flag(ecgroup, OPENSSL_EC_NAMED_CURVE);
501
2
    ecpoint = EC_POINT_new(ecgroup);
502
503
    /* PIV returns 04||x||y  and x and y are the same size */
504
2
    i = (int)(keydata.ecpoint_len - 1) / 2;
505
2
    x = BN_bin2bn(keydata.ecpoint + 1, i, NULL);
506
2
    y = BN_bin2bn(keydata.ecpoint + 1 + i, i, NULL);
507
2
    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
2
    r = EC_POINT_set_affine_coordinates(ecgroup, ecpoint, x, y, NULL);
517
518
2
    BN_free(x);
519
2
    BN_free(y);
520
521
2
    if (r == 0) {
522
2
      sc_log_openssl(ctx);
523
2
      fprintf(stderr, "EC_POINT_set_affine_coordinates_GFp failed\n");
524
2
      EC_GROUP_free(ecgroup);
525
2
      EC_POINT_free(ecpoint);
526
2
      r = 1;
527
2
      goto out;
528
2
    }
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
8
  if (bp) {
630
8
    r = i2d_PUBKEY_bio(bp, evpkey);
631
8
    if (r != 1) {
632
6
      sc_log_openssl(ctx);
633
6
      fprintf(stderr, "Failed to encode public key");
634
6
      r = 1;
635
6
      goto out;
636
6
    }
637
8
  }
638
2
  r = SC_SUCCESS;
639
17
out:
640
17
  free(keydata.pubkey);
641
17
  free(keydata.exponent);
642
17
  free(keydata.ecpoint);
643
644
17
  EVP_PKEY_free(evpkey);
645
646
17
  return r;
647
2
}
648
649
650
static int send_apdu(void)
651
885
{
652
885
  sc_apdu_t apdu;
653
885
  u8 buf[SC_MAX_APDU_BUFFER_SIZE+3];
654
885
  u8 rbuf[8192];
655
885
  size_t len0, i;
656
885
  int r;
657
885
  int c;
658
659
42.5k
  for (c = 0; c < opt_apdu_count; c++) {
660
42.1k
    len0 = sizeof(buf);
661
42.1k
    sc_hex_to_bin(opt_apdus[c], buf, &len0);
662
663
42.1k
    r = sc_bytes2apdu(card->ctx, buf, len0, &apdu);
664
42.1k
    if (r) {
665
422
      fprintf(stderr, "Invalid APDU: %s\n", sc_strerror(r));
666
422
      return 2;
667
422
    }
668
669
41.7k
    apdu.resp = rbuf;
670
41.7k
    apdu.resplen = sizeof(rbuf);
671
672
41.7k
    printf("Sending: ");
673
215k
    for (i = 0; i < len0; i++)
674
174k
      printf("%02X ", buf[i]);
675
41.7k
    printf("\n");
676
41.7k
    r = sc_transmit_apdu(card, &apdu);
677
41.7k
    if (r) {
678
67
      fprintf(stderr, "APDU transmit failed: %s\n", sc_strerror(r));
679
67
      return 1;
680
67
    }
681
41.6k
    printf("Received (SW1=0x%02X, SW2=0x%02X)%s\n", apdu.sw1, apdu.sw2,
682
41.6k
           apdu.resplen ? ":" : "");
683
41.6k
    if (apdu.resplen)
684
2.36k
      util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);
685
41.6k
  }
686
396
  return 0;
687
885
}
688
689
static void print_serial(sc_card_t *in_card)
690
223
{
691
223
  int r;
692
223
  sc_serial_number_t serial;
693
694
223
  r = sc_card_ctl(in_card, SC_CARDCTL_GET_SERIALNR, &serial);
695
223
  if (r < 0)
696
180
    fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_GET_SERIALNR, *) failed %d\n", r);
697
43
  else
698
43
    util_hex_dump_asc(stdout, serial.value, serial.len, -1);
699
223
}
700
701
int main(int argc, char *argv[])
702
3.12k
{
703
3.12k
  int err = 0, r, c;
704
3.12k
  int do_send_apdu = 0;
705
3.12k
  int do_admin_mode = 0;
706
3.12k
  int do_gen_key = 0;
707
3.12k
  int do_load_cert = 0;
708
3.12k
  int do_load_object = 0;
709
3.12k
  int compress_cert = 0;
710
3.12k
  int do_print_serial = 0;
711
3.12k
  int do_print_name = 0;
712
3.12k
  int action_count = 0;
713
3.12k
  const char *out_file = NULL;
714
3.12k
  const char *in_file = NULL;
715
3.12k
  const char *cert_id = NULL;
716
3.12k
  const char *object_id = NULL;
717
3.12k
  const char *key_info = NULL;
718
3.12k
  const char *admin_info = NULL;
719
3.12k
  sc_context_param_t ctx_param;
720
3.12k
  char **old_apdus = NULL;
721
722
1.17M
  while ((c = getopt_long(argc, argv, "nA:G:O:Z:C:i:o:r:fvs:c:w", options, (int *) 0)) != -1) {
723
1.17M
    switch (c) {
724
436
    case OPT_SERIAL:
725
436
      do_print_serial = 1;
726
436
      action_count++;
727
436
      break;
728
74.2k
    case 's':
729
74.2k
      old_apdus = opt_apdus;
730
74.2k
      opt_apdus = (char **) realloc(opt_apdus,
731
74.2k
          (opt_apdu_count + 1) * sizeof(char *));
732
74.2k
      if (!opt_apdus) {
733
0
        free(old_apdus);
734
0
        err = 1;
735
0
        goto end;
736
0
      }
737
74.2k
      opt_apdus[opt_apdu_count] = optarg;
738
74.2k
      do_send_apdu++;
739
74.2k
      if (opt_apdu_count == 0)
740
1.03k
        action_count++;
741
74.2k
      opt_apdu_count++;
742
74.2k
      break;
743
164k
    case 'n':
744
164k
      do_print_name = 1;
745
164k
      action_count++;
746
164k
      break;
747
437
    case 'A':
748
437
      do_admin_mode = 1;
749
437
      admin_info = optarg;
750
437
      action_count++;
751
437
      break;
752
560
    case 'G':
753
560
      do_gen_key = 1;
754
560
      key_info = optarg;
755
560
      action_count++;
756
560
      break;
757
369
    case 'O':
758
369
      do_load_object = 1;
759
369
      object_id = optarg;
760
369
      action_count++;
761
369
      break;
762
197
    case 'Z':
763
197
      compress_cert = 1;
764
      /* fall through */
765
534
    case 'C':
766
534
      do_load_cert = 1;
767
534
      cert_id = optarg;
768
534
      action_count++;
769
534
      break;
770
206
    case 'i':
771
206
      in_file = optarg;
772
206
      break;
773
198
    case 'o':
774
198
      out_file = optarg;
775
198
      break;
776
900
    case 'r':
777
900
      opt_reader = optarg;
778
900
      break;
779
918k
    case 'v':
780
918k
      verbose++;
781
918k
      break;
782
9.55k
    case 'w':
783
9.55k
      opt_wait = 1;
784
9.55k
      break;
785
6
    default:
786
6
      util_print_usage(app_name, options, option_help, NULL);
787
6
      if (opt_apdus)
788
3
        free(opt_apdus);
789
6
      return 2;
790
1.17M
    }
791
1.17M
  }
792
793
3.11k
  if (action_count == 0) {
794
77
    util_print_usage(app_name, options, option_help, NULL);
795
77
    if (opt_apdus)
796
0
      free(opt_apdus);
797
77
    return 2;
798
77
  }
799
800
3.04k
  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.02k
  } else {
805
3.02k
    bp = BIO_new(BIO_s_file());
806
3.02k
    BIO_set_fp(bp,stdout,BIO_NOCLOSE);
807
3.02k
  }
808
809
3.03k
  memset(&ctx_param, 0, sizeof(sc_context_param_t));
810
3.03k
  ctx_param.app_name = app_name;
811
3.03k
  ctx_param.debug    = verbose;
812
3.03k
  if (verbose)
813
3.03k
    ctx_param.debug_file = stderr;
814
815
3.03k
  r = sc_context_create(&ctx, &ctx_param);
816
3.03k
  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.03k
  if (action_count <= 0)
822
0
    goto end;
823
824
  /* force PIV card driver */
825
3.03k
  err = sc_set_card_driver(ctx, "PIV-II");
826
3.03k
  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.03k
  err = util_connect_card(ctx, &card, opt_reader, opt_wait);
833
3.03k
  if (err)
834
1.33k
    goto end;
835
836
  /* fail if card is not a PIV card */
837
1.70k
  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.70k
  if (do_admin_mode) {
844
235
    if ((err = admin_mode(admin_info)))
845
235
      goto end;
846
0
    action_count--;
847
0
  }
848
1.46k
  if (do_send_apdu) {   /* can use pin before load cert for a beta card */
849
885
    if ((err = send_apdu()))
850
489
      goto end;
851
396
    action_count--;
852
396
  }
853
976
  if (do_gen_key) {
854
283
    if ((err = gen_key(key_info)))
855
281
      goto end;
856
2
    action_count--;
857
2
  }
858
695
  if (do_load_object) {
859
4
    if ((err = load_object(object_id, in_file)))
860
4
      goto end;
861
0
    action_count--;
862
0
  }
863
691
  if (do_load_cert) {
864
25
    if ((err = load_cert(cert_id, in_file, compress_cert)))
865
25
      goto end;
866
0
    action_count--;
867
0
  }
868
666
  if (do_print_serial) {
869
223
    if (verbose)
870
223
      printf("Card serial number:");
871
223
    print_serial(card);
872
223
    action_count--;
873
223
  }
874
666
  if (do_print_name) {
875
152
    if (verbose)
876
152
      printf("Card name: ");
877
152
    printf("%s\n", card->name);
878
152
    action_count--;
879
152
  }
880
3.04k
end:
881
3.04k
  if (bp)
882
3.04k
    BIO_free(bp);
883
3.04k
  if (card) {
884
1.70k
    sc_unlock(card);
885
1.70k
    sc_disconnect_card(card);
886
1.70k
  }
887
3.04k
  if (opt_apdus)
888
1.03k
    free(opt_apdus);
889
3.04k
  sc_release_context(ctx);
890
891
3.04k
  ERR_print_errors_fp(stderr);
892
3.04k
  return err;
893
666
}