Coverage Report

Created: 2025-07-12 06:53

/src/opensc/src/tools/pkcs15-crypt.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * pkcs15-crypt.c: Tool for cryptography operations with smart cards
3
 *
4
 * Copyright (C) 2001  Juha Yrjölä <juha.yrjola@iki.fi>
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
21
#include "config.h"
22
23
#include <stdio.h>
24
#include <stdlib.h>
25
#ifdef HAVE_UNISTD_H
26
#include <unistd.h>
27
#endif
28
#include <errno.h>
29
#include <string.h>
30
31
#include "common/compat_getpass.h"
32
#include "libopensc/internal.h"
33
#include "libopensc/opensc.h"
34
#include "libopensc/pkcs15.h"
35
#include "libopensc/asn1.h"
36
#include "util.h"
37
38
static const char *app_name = "pkcs15-crypt";
39
40
static int verbose = 0, opt_wait = 0, opt_raw = 0;
41
static char * opt_reader;
42
static char * opt_pincode = NULL, * opt_key_id = NULL;
43
static char * opt_input = NULL, * opt_output = NULL;
44
static char * opt_bind_to_aid = NULL;
45
static char * opt_sig_format = NULL;
46
static int opt_crypt_flags = 0;
47
48
enum {
49
  OPT_SHA1 =  0x100,
50
  OPT_SHA256,
51
  OPT_SHA384,
52
  OPT_SHA512,
53
  OPT_SHA224,
54
  OPT_MD5,
55
  OPT_PKCS1,
56
  OPT_BIND_TO_AID,
57
  OPT_VERSION,
58
};
59
60
static const struct option options[] = {
61
  { "version",    0, NULL,    OPT_VERSION },
62
  { "sign",   0, NULL,    's' },
63
  { "decipher",   0, NULL,    'c' },
64
  { "key",    1, NULL,    'k' },
65
  { "reader",   1, NULL,    'r' },
66
  { "input",    1, NULL,    'i' },
67
  { "output",   1, NULL,    'o' },
68
  { "signature-format", 1, NULL,    'f' },
69
  { "raw",    0, NULL,    'R' },
70
  { "sha-1",    0, NULL,    OPT_SHA1 },
71
  { "sha-256",    0, NULL,    OPT_SHA256 },
72
  { "sha-384",    0, NULL,    OPT_SHA384 },
73
  { "sha-512",    0, NULL,    OPT_SHA512 },
74
  { "sha-224",    0, NULL,    OPT_SHA224 },
75
  { "md5",    0, NULL,    OPT_MD5 },
76
  { "pkcs1",    0, NULL,    OPT_PKCS1 },
77
  { "pin",    1, NULL,    'p' },
78
  { "aid",    1, NULL,    OPT_BIND_TO_AID },
79
  { "wait",   0, NULL,    'w' },
80
  { "verbose",    0, NULL,    'v' },
81
  { NULL, 0, NULL, 0 }
82
};
83
84
static const char *option_help[] = {
85
  "Print OpenSC package version",
86
  "Performs digital signature operation",
87
  "Decipher operation",
88
  "Selects the private key ID to use",
89
  "Uses reader number <arg>",
90
  "Selects the input file to use (defaults to stdin)",
91
  "Outputs to file <arg> (defaults to stdout)",
92
  "Format for ECDSA signature <arg>: 'rs' (default), 'sequence', 'openssl'",
93
  "Outputs raw 8 bit data",
94
  "Input file is a SHA-1 hash",
95
  "Input file is a SHA-256 hash",
96
  "Input file is a SHA-384 hash",
97
  "Input file is a SHA-512 hash",
98
  "Input file is a SHA-224 hash",
99
  "Input file is a MD5 hash",
100
  "Use PKCS #1 v1.5 padding",
101
  "Uses password (PIN) <arg> (use - for reading PIN from STDIN)",
102
  "Specify AID of the on-card PKCS#15 application to be binded to (in hexadecimal form)",
103
  "Wait for card insertion",
104
  "Verbose operation, may be used several times",
105
};
106
107
static sc_context_t *ctx = NULL;
108
static sc_card_t *card = NULL;
109
static struct sc_pkcs15_card *p15card = NULL;
110
111
static char *readpin_stdin(void)
112
2
{
113
2
  char buf[128];
114
2
  char *p;
115
116
2
  p = fgets(buf, sizeof(buf), stdin);
117
2
  if (p != NULL) {
118
0
    p = strchr(buf, '\n');
119
0
    if (p != NULL)
120
0
      *p = '\0';
121
0
    return strdup(buf);
122
0
  }
123
2
  return NULL;
124
2
}
125
126
static char * get_pin(struct sc_pkcs15_object *obj)
127
412
{
128
412
  char buf[(sizeof obj->label) + 20];
129
412
  char *pincode;
130
412
  struct sc_pkcs15_auth_info *pinfo;
131
132
412
  if (!obj)
133
0
    return NULL;
134
135
412
  pinfo = (struct sc_pkcs15_auth_info *) obj->data;
136
412
  if (pinfo->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
137
0
    return NULL;
138
139
412
  if (opt_pincode != NULL) {
140
412
    if (strcmp(opt_pincode, "-") == 0)
141
2
      return readpin_stdin();
142
410
    else
143
410
      return strdup(opt_pincode);
144
412
  }
145
146
0
  snprintf(buf, sizeof(buf), "Enter PIN [%.*s]: ",
147
0
    (int) sizeof obj->label, obj->label);
148
0
  while (1) {
149
0
    pincode = getpass(buf);
150
0
    if (strlen(pincode) == 0)
151
0
      return NULL;
152
0
    if (strlen(pincode) < pinfo->attrs.pin.min_length ||
153
0
        strlen(pincode) > pinfo->attrs.pin.max_length)
154
0
      continue;
155
0
    return strdup(pincode);
156
0
  }
157
0
}
158
159
static size_t read_input(u8 *buf, int buflen)
160
621
{
161
621
  FILE *inf;
162
621
  size_t c;
163
164
621
  if (opt_input==NULL) {
165
0
    inf = stdin;
166
621
  } else {
167
621
    inf = fopen(opt_input, "rb");
168
621
    if (inf == NULL) {
169
39
      fprintf(stderr, "Unable to open '%s' for reading.\n", opt_input);
170
39
      return 0;
171
39
    }
172
621
  }
173
582
  c = fread(buf, 1, buflen, inf);
174
582
  if (inf!=stdin) {
175
582
    fclose(inf);
176
582
  }
177
582
  if (c <= 0) {
178
0
    perror("read");
179
0
    return 0;
180
0
  }
181
582
  return c;
182
582
}
183
184
static int write_output(const u8 *buf, size_t len)
185
94
{
186
94
  FILE *outf;
187
94
  int output_binary = (opt_output == NULL && opt_raw == 0 ? 0 : 1);
188
189
94
  if (opt_output != NULL) {
190
0
    outf = fopen(opt_output, "wb");
191
0
    if (outf == NULL) {
192
0
      fprintf(stderr, "Unable to open '%s' for writing.\n", opt_output);
193
0
      return -1;
194
0
    }
195
94
  } else {
196
94
    outf = stdout;
197
94
  }
198
199
94
  if (output_binary == 0)
200
94
    util_print_binary(outf, buf, len);
201
0
  else
202
0
    fwrite(buf, len, 1, outf);
203
204
94
  if (outf != stdout)
205
0
    fclose(outf);
206
94
  return 0;
207
94
}
208
209
static int sign(struct sc_pkcs15_object *obj)
210
249
{
211
249
  u8 buf[1024], out[1024];
212
249
  struct sc_pkcs15_prkey_info *key = (struct sc_pkcs15_prkey_info *) obj->data;
213
249
  int r, flags;
214
249
  size_t c, len;
215
216
249
  if (opt_input == NULL) {
217
0
    fprintf(stderr, "No input file specified. Reading from stdin\n");
218
0
  }
219
220
249
  c = read_input(buf, sizeof(buf));
221
249
  if (c <= 0)
222
15
    return 2;
223
234
  len = sizeof(out);
224
234
  if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA
225
234
      && !(opt_crypt_flags & SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01)
226
234
      && (size_t)c != key->modulus_length/8) {
227
8
    fprintf(stderr, "Input has to be exactly %lu bytes, when using no padding.\n",
228
8
      (unsigned long) key->modulus_length/8);
229
8
    return 2;
230
8
  }
231
226
  if (!key->native) {
232
1
    fprintf(stderr, "Deprecated non-native key detected! Upgrade your smart cards.\n");
233
1
    return SC_ERROR_NOT_SUPPORTED;
234
1
  }
235
236
225
  flags = opt_crypt_flags & ~SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_02;
237
225
  r = sc_pkcs15_compute_signature(p15card, obj, flags, buf, c, out, len, NULL);
238
225
  if (r < 0) {
239
180
    fprintf(stderr, "Compute signature failed: %s\n", sc_strerror(r));
240
180
    return 1;
241
180
  }
242
45
  len = r;
243
244
45
  if (obj->type == SC_PKCS15_TYPE_PRKEY_EC)   {
245
12
    if (opt_sig_format &&  (!strcmp(opt_sig_format, "openssl") || !strcmp(opt_sig_format, "sequence")))   {
246
11
      unsigned char *seq;
247
11
      size_t seqlen;
248
249
11
      if (sc_asn1_sig_value_rs_to_sequence(ctx, out, len, &seq, &seqlen))   {
250
0
        fprintf(stderr, "Failed to convert signature to ASN1 sequence format.\n");
251
0
        return 2;
252
0
      }
253
254
11
      memcpy(out, seq, seqlen);
255
11
      len = seqlen;
256
257
11
      free(seq);
258
11
    }
259
12
  }
260
261
45
  r = write_output(out, len);
262
263
45
  return r;
264
45
}
265
266
static int decipher(struct sc_pkcs15_object *obj)
267
372
{
268
372
  u8 buf[1024], out[1024];
269
372
  int r, len, flags;
270
372
  size_t c;
271
272
372
  if (opt_input == NULL) {
273
0
    fprintf(stderr, "No input file specified. Reading from stdin\n");
274
0
  }
275
372
  c = read_input(buf, sizeof(buf));
276
372
  if (c <= 0)
277
24
    return 2;
278
279
348
  len = sizeof(out);
280
348
  if (!((struct sc_pkcs15_prkey_info *) obj->data)->native) {
281
1
                fprintf(stderr, "Deprecated non-native key detected! Upgrade your smart cards.\n");
282
1
    return SC_ERROR_NOT_SUPPORTED;
283
1
  }
284
285
347
  flags = opt_crypt_flags & ~SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01;
286
347
  r = sc_pkcs15_decipher(p15card, obj, flags, buf, c, out, len, NULL);
287
347
  if (r < 0) {
288
298
    fprintf(stderr, "Decrypt failed: %s\n", sc_strerror(r));
289
298
    return 1;
290
298
  }
291
49
  r = write_output(out, r);
292
293
49
  return r;
294
347
}
295
296
static int get_key(unsigned int usage, sc_pkcs15_object_t **result)
297
4.23k
{
298
4.23k
  sc_pkcs15_object_t *key, *pin = NULL;
299
4.23k
  const char  *usage_name;
300
4.23k
  sc_pkcs15_id_t  id;
301
4.23k
  int   r;
302
303
4.23k
  usage_name = (usage & SC_PKCS15_PRKEY_USAGE_SIGN)? "signature" : "decryption";
304
305
4.23k
  if (opt_key_id != NULL) {
306
34
    sc_pkcs15_hex_string_to_id(opt_key_id, &id);
307
34
    r = sc_pkcs15_find_prkey_by_id_usage(p15card, &id, usage, &key);
308
34
    if (r < 0) {
309
33
      fprintf(stderr, "Unable to find private %s key '%s': %s\n",
310
33
        usage_name, opt_key_id, sc_strerror(r));
311
33
      return 2;
312
33
    }
313
4.20k
  } else {
314
4.20k
    r = sc_pkcs15_find_prkey_by_id_usage(p15card, NULL, usage, &key);
315
4.20k
    if (r < 0) {
316
3.31k
      fprintf(stderr, "Unable to find any private %s key: %s\n",
317
3.31k
        usage_name, sc_strerror(r));
318
3.31k
      return 2;
319
3.31k
    }
320
4.20k
  }
321
322
890
  *result = key;
323
324
890
  if (key->auth_id.len) {
325
647
    static sc_pkcs15_object_t *prev_pin = NULL;
326
647
    char  *pincode;
327
328
647
    r = sc_pkcs15_find_pin_by_auth_id(p15card, &key->auth_id, &pin);
329
647
    if (r) {
330
13
      fprintf(stderr, "Unable to find PIN code for private key: %s\n",
331
13
        sc_strerror(r));
332
13
      return 1;
333
13
    }
334
335
    /* Pin already verified previously */
336
634
    if (pin == prev_pin && key->user_consent == 0)
337
222
      return 0;
338
339
412
    pincode = get_pin(pin);
340
412
    if (((pincode == NULL || *pincode == '\0')) &&
341
412
        !(p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD)) {
342
2
      free(pincode);
343
2
      return 5;
344
2
    }
345
346
    /*
347
     * Do what PKCS#11 would do for keys requiring CKA_ALWAYS_AUTHENTICATE
348
     * and CKU_CONTEXT_SPECIFIC login to let driver know this verify will be followed by
349
     * a crypto operation.  Card drivers can test for SC_AC_CONTEXT_SPECIFIC
350
     * to do any special handling.
351
     */
352
410
    if (key->user_consent && pin) {
353
39
      int auth_meth_saved;
354
39
      struct sc_pkcs15_auth_info *pinfo = (struct sc_pkcs15_auth_info *) pin->data;
355
356
39
      auth_meth_saved = pinfo->auth_method;
357
358
39
      pinfo->auth_method = SC_AC_CONTEXT_SPECIFIC;
359
39
      r = sc_pkcs15_verify_pin(p15card, pin, (const u8 *)pincode, pincode ? strlen(pincode) : 0);
360
39
      pinfo->auth_method = auth_meth_saved;
361
39
    } else
362
371
      r = sc_pkcs15_verify_pin(p15card, pin, (const u8 *)pincode, pincode ? strlen(pincode) : 0);
363
364
410
    free(pincode);
365
410
    if (r) {
366
254
      fprintf(stderr, "PIN code verification failed: %s\n", sc_strerror(r));
367
254
      return 5;
368
254
    }
369
156
    if (verbose)
370
1
      fprintf(stderr, "PIN code correct.\n");
371
156
    prev_pin = pin;
372
156
  }
373
374
399
  return 0;
375
890
}
376
377
int main(int argc, char *argv[])
378
13.8k
{
379
13.8k
  int err = 0, r, c, long_optind = 0;
380
13.8k
  int do_decipher = 0;
381
13.8k
  int do_sign = 0;
382
13.8k
  int do_print_version = 0;
383
13.8k
  int action_count = 0;
384
13.8k
  struct sc_pkcs15_object *key;
385
13.8k
  sc_context_param_t ctx_param;
386
387
5.04M
  while (1) {
388
5.04M
    c = getopt_long(argc, argv, "sck:r:i:o:f:Rp:vw", options, &long_optind);
389
5.04M
    if (c == -1)
390
13.8k
      break;
391
5.02M
    if (c == '?') {
392
10
      util_print_usage(app_name, options, option_help, NULL);
393
10
      return 2;
394
10
    }
395
5.02M
    switch (c) {
396
0
    case OPT_VERSION:
397
0
      do_print_version = 1;
398
0
      action_count++;
399
0
      break;
400
9.77k
    case 's':
401
9.77k
      do_sign++;
402
9.77k
      action_count++;
403
9.77k
      break;
404
12.3k
    case 'c':
405
12.3k
      do_decipher++;
406
12.3k
      action_count++;
407
12.3k
      break;
408
852
    case 'k':
409
852
      opt_key_id = optarg;
410
852
      action_count++;
411
852
      break;
412
279
    case 'r':
413
279
      opt_reader = optarg;
414
279
      break;
415
4.84k
    case 'i':
416
4.84k
      opt_input = optarg;
417
4.84k
      break;
418
484
    case 'o':
419
484
      opt_output = optarg;
420
484
      break;
421
4.80k
    case 'f':
422
4.80k
      opt_sig_format = optarg;
423
4.80k
      break;
424
738
    case 'R':
425
738
      opt_raw = 1;
426
738
      break;
427
1.87k
    case OPT_SHA1:
428
1.87k
      opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1;
429
1.87k
      break;
430
659
    case OPT_SHA256:
431
659
      opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256;
432
659
      break;
433
297
    case OPT_SHA384:
434
297
      opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384;
435
297
      break;
436
452
    case OPT_SHA512:
437
452
      opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512;
438
452
      break;
439
377
    case OPT_SHA224:
440
377
      opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA224;
441
377
      break;
442
945
    case OPT_MD5:
443
945
      opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5;
444
945
      break;
445
2.56k
    case OPT_PKCS1:
446
2.56k
      opt_crypt_flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
447
2.56k
      break;
448
4.97M
    case 'v':
449
4.97M
      verbose++;
450
4.97M
      break;
451
4.66k
    case 'p':
452
4.66k
      opt_pincode = optarg;
453
4.66k
      break;
454
601
    case OPT_BIND_TO_AID:
455
601
      opt_bind_to_aid = optarg;
456
601
      break;
457
1.04k
    case 'w':
458
1.04k
      opt_wait = 1;
459
1.04k
      break;
460
5.02M
    }
461
5.02M
  }
462
13.8k
  if (action_count == 0) {
463
82
    util_print_usage(app_name, options, option_help, NULL);
464
82
    return 2;
465
82
  }
466
467
13.8k
  if (do_print_version)   {
468
0
    printf("%s\n", OPENSC_SCM_REVISION);
469
0
    action_count--;
470
0
  }
471
472
13.8k
  if (!(opt_crypt_flags & SC_ALGORITHM_RSA_HASHES))
473
9.39k
    opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_NONE;
474
475
13.8k
  memset(&ctx_param, 0, sizeof(ctx_param));
476
13.8k
  ctx_param.ver      = 0;
477
13.8k
  ctx_param.app_name = app_name;
478
13.8k
  ctx_param.debug    = verbose;
479
13.8k
  if (verbose)
480
94
    ctx_param.debug_file = stderr;
481
482
13.8k
  r = sc_context_create(&ctx, &ctx_param);
483
13.8k
  if (r) {
484
0
    fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r));
485
0
    return 1;
486
0
  }
487
488
13.8k
  err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0);
489
13.8k
  if (err)
490
2.98k
    goto end;
491
492
10.8k
  if (verbose)
493
51
    fprintf(stderr, "Trying to find a PKCS #15 compatible card...\n");
494
10.8k
  if (opt_bind_to_aid)   {
495
383
    struct sc_aid aid;
496
497
383
    aid.len = sizeof(aid.value);
498
383
    if (sc_hex_to_bin(opt_bind_to_aid, aid.value, &aid.len))   {
499
123
      fprintf(stderr, "Invalid AID value: '%s'\n", opt_bind_to_aid);
500
123
      err = 1;
501
123
      goto end;
502
123
    }
503
504
260
    r = sc_pkcs15_bind(card, &aid, &p15card);
505
260
  }
506
10.4k
  else   {
507
10.4k
    r = sc_pkcs15_bind(card, NULL, &p15card);
508
10.4k
  }
509
10.6k
  if (r) {
510
6.44k
    fprintf(stderr, "PKCS #15 binding failed: %s\n", sc_strerror(r));
511
6.44k
    err = 1;
512
6.44k
    goto end;
513
6.44k
  }
514
4.25k
  if (verbose)
515
21
    fprintf(stderr, "Found %s!\n", p15card->tokeninfo->label);
516
517
4.25k
  if (do_decipher) {
518
3.13k
    if ((err = get_key(SC_PKCS15_PRKEY_USAGE_DECRYPT|SC_PKCS15_PRKEY_USAGE_UNWRAP, &key))
519
3.13k
     || (err = decipher(key)))
520
3.08k
      goto end;
521
49
    action_count--;
522
49
  }
523
524
1.17k
  if (do_sign) {
525
1.10k
    if ((err = get_key(SC_PKCS15_PRKEY_USAGE_SIGN|
526
1.10k
           SC_PKCS15_PRKEY_USAGE_SIGNRECOVER|
527
1.10k
           SC_PKCS15_PRKEY_USAGE_NONREPUDIATION, &key))
528
1.10k
     || (err = sign(key)))
529
1.05k
      goto end;
530
45
    action_count--;
531
45
  }
532
13.8k
end:
533
13.8k
  if (p15card)
534
4.25k
    sc_pkcs15_unbind(p15card);
535
13.8k
  if (card) {
536
10.8k
    sc_disconnect_card(card);
537
10.8k
  }
538
13.8k
  if (ctx)
539
13.8k
    sc_release_context(ctx);
540
13.8k
  return err;
541
1.17k
}