Coverage Report

Created: 2025-07-18 06:10

/src/opensc/src/pkcs15init/pkcs15-cardos.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * CardOS specific operation for PKCS15 initialization
3
 *
4
 * Copyright (C) 2005 Nils Larsch <nils@larsch.net>
5
 * Copyright (C) 2002 Olaf Kirch <okir@suse.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
#include "config.h"
23
24
#include <sys/types.h>
25
#include <stdlib.h>
26
#include <string.h>
27
#include <assert.h>
28
#include <stdarg.h>
29
30
#include "libopensc/opensc.h"
31
#include "libopensc/cardctl.h"
32
#include "libopensc/log.h"
33
#include "libopensc/cards.h"
34
#include "libopensc/asn1.h"
35
#include "pkcs15-init.h"
36
#include "profile.h"
37
38
#ifndef MIN
39
0
# define MIN(a, b)  (((a) < (b))? (a) : (b))
40
#endif
41
42
struct tlv {
43
  unsigned char *   base;
44
  unsigned char *   end;
45
  unsigned char *   current;
46
  unsigned char *   next;
47
};
48
49
/*
50
 * Local functions
51
 */
52
static int  cardos_store_pin(sc_profile_t *profile, sc_card_t *card,
53
      sc_pkcs15_auth_info_t *auth_info, int puk_id,
54
      const u8 *pin, size_t pin_len);
55
static int  cardos_create_sec_env(sc_profile_t *, sc_card_t *,
56
      unsigned int, unsigned int);
57
static int  cardos_put_key(struct sc_profile *, sc_pkcs15_card_t *,
58
      int, sc_pkcs15_prkey_info_t *,
59
            struct sc_pkcs15_prkey_rsa *);
60
static int  cardos_key_algorithm(unsigned int, size_t, int *);
61
static int  cardos_extract_pubkey(sc_card_t *, sc_pkcs15_pubkey_t *,
62
      sc_file_t *, int);
63
static int  do_cardos_extract_pubkey(sc_card_t *card, int nr, u8 tag,
64
      sc_pkcs15_bignum_t *bn);
65
static int  cardos_have_verifyrc_package(sc_card_t *card);
66
67
/* Object IDs for PIN objects.
68
 * SO PIN = 0x01, SO PUK = 0x02
69
 * each user pin is 2*N+1, each corresponding PUK is 2*N+2
70
 */
71
0
#define CARDOS_PIN_ID_MIN 1
72
0
#define CARDOS_PIN_ID_MAX 15
73
0
#define CARDOS_KEY_ID_MIN 16
74
0
#define CARDOS_KEY_ID_MAX 31
75
0
#define CARDOS_AC_NEVER   0xFF
76
77
#define CARDOS_ALGO_RSA     0x08
78
0
#define CARDOS_ALGO_RSA_PURE    0x0C
79
#define CARDOS_ALGO_RSA_SIG   0x88
80
0
#define CARDOS_ALGO_RSA_PURE_SIG  0x8C
81
#define CARDOS_ALGO_RSA_SIG_SHA1  0xC8
82
#define CARDOS_ALGO_RSA_PURE_SIG_SHA1 0xCC
83
0
#define CARDOS_ALGO_EXT_RSA_PURE  0x0a
84
0
#define CARDOS_ALGO_EXT_RSA_SIG_PURE  0x8a
85
0
#define CARDOS_ALGO_PIN     0x87
86
87
static void tlv_init(struct tlv *tlv, u8 *base, size_t size)
88
0
{
89
0
  tlv->base = base;
90
0
  tlv->end = base + size;
91
0
  tlv->current = tlv->next = base;
92
0
}
93
94
static int tlv_next(struct tlv *tlv, u8 tag)
95
0
{
96
0
  if (tlv->next + 2 >= tlv->end)
97
0
    return SC_ERROR_INTERNAL;
98
0
  tlv->current = tlv->next;
99
0
  *(tlv->next++) = tag;
100
0
  *(tlv->next++) = 0;
101
0
  return SC_SUCCESS;
102
0
}
103
104
static int tlv_add(struct tlv *tlv, u8 val)
105
0
{
106
0
  if (tlv->next + 1 >= tlv->end)
107
0
    return SC_ERROR_INTERNAL;
108
0
  *(tlv->next++) = val;
109
0
  tlv->current[1]++;
110
0
  return SC_SUCCESS;
111
0
}
112
113
static size_t
114
tlv_len(struct tlv *tlv)
115
0
{
116
0
  return tlv->next - tlv->base;
117
0
}
118
119
/*
120
 * Try to delete pkcs15 structure
121
 * This is not quite the same as erasing the whole token, but
122
 * it's close enough to be useful.
123
 */
124
static int
125
cardos_erase(struct sc_profile *profile, sc_pkcs15_card_t *p15card)
126
0
{
127
0
  return sc_pkcs15init_erase_card_recursively(p15card, profile);
128
0
}
129
130
/*
131
 * Create the Application DF
132
 */
133
static int
134
cardos_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df)
135
0
{
136
0
  int r;
137
138
  /* Create the application DF */
139
0
  if ((r = sc_pkcs15init_create_file(profile, p15card, df)) < 0)
140
0
    return r;
141
142
0
  if ((r = sc_select_file(p15card->card, &df->path, NULL)) < 0)
143
0
    return r;
144
145
  /* Create a default security environment for this DF.
146
   * This SE automatically becomes the current SE when the
147
   * DF is selected. */
148
0
  if ((r = cardos_create_sec_env(profile, p15card->card, 0x01, 0x00)) < 0)
149
0
    return r;
150
151
0
  return 0;
152
0
}
153
154
/*
155
 * Caller passes in a suggested PIN reference.
156
 * See if it's good, and if it isn't, propose something better
157
 */
158
static int
159
cardos_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
160
    sc_pkcs15_auth_info_t *auth_info)
161
0
{
162
0
  int preferred, current;
163
164
0
  if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
165
0
    return SC_ERROR_OBJECT_NOT_VALID;
166
167
0
  if ((current = auth_info->attrs.pin.reference) < 0)
168
0
    current = CARDOS_PIN_ID_MIN;
169
170
0
  if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) {
171
0
    preferred = 1;
172
0
    if (current > preferred)
173
0
      return SC_ERROR_TOO_MANY_OBJECTS;
174
0
  } else {
175
0
    preferred = current;
176
    /* PINs are even numbered, PUKs are odd */
177
0
    if (!(preferred & 1))
178
0
      preferred++;
179
0
  }
180
181
0
  if (preferred > CARDOS_PIN_ID_MAX)
182
0
    return SC_ERROR_TOO_MANY_OBJECTS;
183
0
  auth_info->attrs.pin.reference = preferred;
184
185
0
  return SC_SUCCESS;
186
0
}
187
188
/*
189
 * Store a PIN
190
 */
191
static int
192
cardos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df,
193
    sc_pkcs15_object_t *pin_obj,
194
    const u8 *pin, size_t pin_len,
195
    const u8 *puk, size_t puk_len)
196
0
{
197
0
  sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data;
198
0
  struct sc_card *card = p15card->card;
199
0
  unsigned int  puk_id = CARDOS_AC_NEVER;
200
0
  int   r;
201
202
0
  if (!pin || !pin_len)
203
0
    return SC_ERROR_INVALID_ARGUMENTS;
204
205
0
  if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
206
0
    return SC_ERROR_OBJECT_NOT_VALID;
207
208
0
  r = sc_select_file(card, auth_info->attrs.pin.reference & 0x80 ? &df->path : sc_get_mf_path(), NULL);
209
0
  if (r < 0)
210
0
    return r;
211
212
0
  if (puk && puk_len) {
213
0
    struct sc_pkcs15_auth_info puk_ainfo = {0};
214
215
0
    sc_profile_get_pin_info(profile,
216
0
        SC_PKCS15INIT_USER_PUK, &puk_ainfo);
217
0
    puk_ainfo.attrs.pin.reference = puk_id = auth_info->attrs.pin.reference + 1;
218
0
    r = cardos_store_pin(profile, card,
219
0
        &puk_ainfo, CARDOS_AC_NEVER,
220
0
        puk, puk_len);
221
0
  }
222
223
0
  if (r >= 0) {
224
0
    r = cardos_store_pin(profile, card,
225
0
        auth_info, puk_id, pin, pin_len);
226
0
  }
227
228
0
  return r;
229
0
}
230
231
/*
232
 * Select a key reference
233
 */
234
static int
235
cardos_select_key_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
236
      sc_pkcs15_prkey_info_t *key_info)
237
0
{
238
0
  if (key_info->key_reference < CARDOS_KEY_ID_MIN)
239
0
    key_info->key_reference = CARDOS_KEY_ID_MIN;
240
0
  if (key_info->key_reference > CARDOS_KEY_ID_MAX)
241
0
    return SC_ERROR_TOO_MANY_OBJECTS;
242
0
  return 0;
243
0
}
244
245
/*
246
 * Create a private key object.
247
 * This is a no-op.
248
 */
249
static int
250
cardos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
251
      sc_pkcs15_object_t *obj)
252
0
{
253
0
  return 0;
254
0
}
255
256
/*
257
 * Store a private key object.
258
 */
259
static int
260
cardos_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
261
      sc_pkcs15_object_t *obj,
262
      sc_pkcs15_prkey_t *key)
263
0
{
264
0
  struct sc_context *ctx = p15card->card->ctx;
265
0
  sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
266
0
  struct sc_file *file = NULL;
267
0
  int   algorithm = 0, r;
268
269
0
  if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
270
0
    sc_log(ctx,  "CardOS supports RSA keys only.");
271
0
    return SC_ERROR_NOT_SUPPORTED;
272
0
  }
273
274
0
  if (cardos_key_algorithm(key_info->usage, key_info->modulus_length, &algorithm) < 0) {
275
0
    sc_log(ctx,  "CardOS does not support keys "
276
0
             "that can both sign _and_ decrypt.");
277
0
    return SC_ERROR_NOT_SUPPORTED;
278
0
  }
279
280
0
  r = sc_select_file(p15card->card, &key_info->path, &file);
281
0
  if (r)   {
282
0
    sc_log(ctx,  "Failed to store key: cannot select parent DF");
283
0
    return r;
284
0
  }
285
286
0
  r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
287
0
  sc_file_free(file);
288
0
  if (r)   {
289
0
    sc_log(ctx,  "Failed to store key: 'UPDATE' authentication failed");
290
0
    return r;
291
0
  }
292
293
0
  r = cardos_put_key(profile, p15card, algorithm, key_info, &key->u.rsa);
294
295
0
  return r;
296
0
}
297
298
static void init_key_object(struct sc_pkcs15_prkey_rsa *key,
299
  u8 *data, size_t len)
300
0
{
301
  /* Create a key object, initializing components to 0xff */
302
0
  memset(key,  0x00, sizeof(*key));
303
0
  memset(data, 0xff, len);
304
0
  key->modulus.data = data;
305
0
  key->modulus.len  = len;
306
0
  key->d.data       = data;
307
0
  key->d.len        = len;
308
0
  key->p.len        = len >> 1;
309
0
  key->p.data       = data;
310
0
  key->q.len        = len >> 1;
311
0
  key->q.data       = data;
312
0
  key->iqmp.len     = len >> 1;
313
0
  key->iqmp.data    = data;
314
0
  key->dmp1.len     = len >> 1;
315
0
  key->dmp1.data    = data;
316
0
  key->dmq1.len     = len >> 1;
317
0
  key->dmq1.data    = data;
318
0
}
319
320
/*
321
 * Key generation
322
 */
323
static int
324
cardos_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
325
    sc_pkcs15_object_t *obj,
326
    sc_pkcs15_pubkey_t *pubkey)
327
0
{
328
0
  struct sc_context *ctx = p15card->card->ctx;
329
0
  struct sc_pkcs15_prkey_info *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
330
0
  struct sc_pkcs15_prkey_rsa key_obj;
331
0
  struct sc_cardctl_cardos_genkey_info args;
332
0
  struct sc_file  *temp;
333
0
  u8    abignum[256];
334
0
  int   algorithm = 0, r, delete_it = 0, use_ext_rsa = 0;
335
0
  size_t    keybits, rsa_max_size;
336
0
  int             pin_id = -1;
337
338
0
  if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA)
339
0
    return SC_ERROR_NOT_SUPPORTED;
340
341
0
  rsa_max_size = (sc_card_find_rsa_alg(p15card->card, 2048) != NULL) ? 2048 : 1024;
342
0
  keybits = key_info->modulus_length & ~7UL;
343
0
  if (keybits > rsa_max_size) {
344
0
    sc_log(ctx,  "Unable to generate key, max size is %lu",
345
0
      (unsigned long) rsa_max_size);
346
0
    return SC_ERROR_INVALID_ARGUMENTS;
347
0
  }
348
349
0
  if (keybits > 1024)
350
0
    use_ext_rsa = 1;
351
352
0
  if (cardos_key_algorithm(key_info->usage, keybits, &algorithm) < 0) {
353
0
    sc_log(ctx,  "CardOS does not support keys "
354
0
             "that can both sign _and_ decrypt.");
355
0
    return SC_ERROR_NOT_SUPPORTED;
356
0
  }
357
358
0
  if (sc_profile_get_file(profile, "tempfile", &temp) < 0) {
359
0
    sc_log(ctx,  "Profile doesn't define temporary file "
360
0
        "for key generation.");
361
0
    return SC_ERROR_NOT_SUPPORTED;
362
0
  }
363
364
0
  pin_id = sc_pkcs15init_get_pin_reference(p15card, profile,
365
0
      SC_AC_SYMBOLIC, SC_PKCS15INIT_USER_PIN);
366
0
  if (pin_id >= 0) {
367
0
    r = sc_pkcs15init_verify_secret(profile, p15card, NULL, SC_AC_CHV, pin_id);
368
0
    if (r < 0)
369
0
      return r;
370
0
  }
371
0
  if (use_ext_rsa == 0)
372
0
    temp->ef_structure = SC_FILE_EF_LINEAR_VARIABLE_TLV;
373
0
  else
374
0
    temp->ef_structure = SC_FILE_EF_TRANSPARENT;
375
376
0
  if ((r = sc_pkcs15init_create_file(profile, p15card, temp)) < 0)
377
0
    goto out;
378
0
  delete_it = 1;
379
380
0
  init_key_object(&key_obj, abignum, keybits >> 3);
381
382
0
  r = cardos_put_key(profile, p15card, algorithm, key_info, &key_obj);
383
0
  if (r < 0)
384
0
    goto out;
385
386
0
  memset(&args, 0, sizeof(args));
387
0
  args.key_id = key_info->key_reference;
388
0
  args.key_bits = keybits;
389
0
  args.fid = temp->id;
390
0
  r = sc_card_ctl(p15card->card, SC_CARDCTL_CARDOS_GENERATE_KEY, &args);
391
0
  if (r < 0)
392
0
    goto out;
393
394
0
  r = cardos_extract_pubkey(p15card->card, pubkey, temp, use_ext_rsa);
395
0
out:
396
0
  if (delete_it != 0)
397
0
    sc_pkcs15init_rmdir(p15card, profile, temp);
398
0
  sc_file_free(temp);
399
400
0
  if (r < 0) {
401
0
    if (pubkey->u.rsa.modulus.data)
402
0
      free (pubkey->u.rsa.modulus.data);
403
0
    if (pubkey->u.rsa.exponent.data)
404
0
      free (pubkey->u.rsa.exponent.data);
405
0
  }
406
0
  return r;
407
0
}
408
409
/*
410
 * Object deletion.
411
 */
412
static int
413
cardos_delete_object(sc_profile_t *profile, struct sc_pkcs15_card *p15card,
414
    struct sc_pkcs15_object *obj, const struct sc_path *path)
415
0
{
416
0
  int r = SC_SUCCESS, stored_in_ef = 0, algorithm = 0;
417
0
  size_t keybits;
418
0
  sc_file_t *file = NULL;
419
0
  struct sc_pkcs15_prkey_info *key_info;
420
0
  struct sc_pkcs15_prkey_rsa key_obj;
421
0
  struct sc_context *ctx = p15card->card->ctx;
422
0
  uint8_t abignum[256];
423
424
0
  LOG_FUNC_CALLED(ctx);
425
  /*
426
   * If we are deleting a private key, overwrite it so it can't be used.
427
   */
428
0
  if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY) {
429
0
    key_info = obj->data;
430
0
    keybits = key_info->modulus_length & ~7UL;
431
0
    init_key_object(&key_obj, abignum, keybits >> 3);
432
0
    r = cardos_key_algorithm(key_info->usage, keybits, &algorithm);
433
0
    LOG_TEST_RET(ctx, r, "cardos_key_algorithm failed");
434
435
0
    r = sc_select_file(p15card->card, &key_info->path, &file);
436
0
    LOG_TEST_RET(ctx, r, "Failed to store key: cannot select parent DF");
437
438
0
    r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
439
0
    sc_file_free(file);
440
0
    LOG_TEST_RET(ctx, r, "Failed to store key: UPDATE authentication failed");
441
442
0
    r = cardos_put_key(profile, p15card, algorithm, key_info, &key_obj);
443
0
    LOG_TEST_RET(ctx, r, "cardos_put_key failed");
444
0
  }
445
446
  /* Delete object from the PKCS15 file system. */
447
0
  if (path->len || path->aid.len)   {
448
0
    r = sc_select_file(p15card->card, path, &file);
449
0
    if (r != SC_ERROR_FILE_NOT_FOUND)
450
0
      LOG_TEST_RET(ctx, r, "select object path failed");
451
452
0
    stored_in_ef = (file->type != SC_FILE_TYPE_DF);
453
0
    sc_file_free(file);
454
0
  }
455
456
  /* If the object is stored in a normal EF, try to delete the EF. */
457
0
  if (r == SC_SUCCESS && stored_in_ef) {
458
0
    r = sc_pkcs15init_delete_by_path(profile, p15card, path);
459
0
    LOG_TEST_RET(ctx, r, "Failed to delete object by path");
460
0
  }
461
462
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
463
0
}
464
465
/*
466
 * Store a PIN or PUK
467
 */
468
static int
469
cardos_store_pin(sc_profile_t *profile, sc_card_t *card,
470
    sc_pkcs15_auth_info_t *auth_info, int puk_id,
471
    const u8 *pin, size_t pin_len)
472
0
{
473
0
  struct sc_cardctl_cardos_obj_info args;
474
0
  unsigned char buffer[256];
475
0
  unsigned char pinpadded[256];
476
0
  struct tlv  tlv;
477
0
  unsigned int  attempts, maxlen;
478
0
  u8 minlen;
479
0
  int   r, hasverifyrc;
480
481
0
  if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
482
0
    return SC_ERROR_OBJECT_NOT_VALID;
483
484
  /* We need to do padding because pkcs15-lib.c does it.
485
   * Would be nice to have a flag in the profile that says
486
   * "no padding required". */
487
0
  maxlen = MIN(profile->pin_maxlen, sizeof(pinpadded));
488
0
  if (pin_len > maxlen) {
489
0
    sc_log(card->ctx,
490
0
       "invalid pin length: %"SC_FORMAT_LEN_SIZE_T"u (max %u)\n",
491
0
       pin_len, maxlen);
492
0
    return SC_ERROR_INVALID_ARGUMENTS;
493
0
  }
494
0
  memcpy(pinpadded, pin, pin_len);
495
0
  while (pin_len < maxlen)
496
0
    pinpadded[pin_len++] = profile->pin_pad_char;
497
0
  pin = pinpadded;
498
499
0
  attempts = auth_info->tries_left;
500
0
  minlen = (u8)auth_info->attrs.pin.min_length;
501
502
0
  tlv_init(&tlv, buffer, sizeof(buffer));
503
504
  /* object address: class, id */
505
0
  if (tlv_next(&tlv, 0x83) != SC_SUCCESS
506
0
      || tlv_add(&tlv, 0x00) != SC_SUCCESS /* class byte: usage TEST, k=0 */
507
0
      || tlv_add(&tlv, auth_info->attrs.pin.reference & 0x7f) != SC_SUCCESS)
508
0
    return SC_ERROR_INTERNAL;
509
510
  /* parameters */
511
0
  if (tlv_next(&tlv, 0x85)
512
0
      || tlv_add(&tlv, 0x02) /* options byte */)
513
0
    return SC_ERROR_INTERNAL;
514
515
0
  hasverifyrc = cardos_have_verifyrc_package(card);
516
0
  if (hasverifyrc == 1)
517
    /* Use 9 byte OCI parameters to be able to set VerifyRC bit */
518
0
    if (tlv_add(&tlv, 0x04) != SC_SUCCESS /* options_2 byte with bit 2 set to return CurrentErrorCounter */)
519
0
      return SC_ERROR_INTERNAL;
520
521
0
  if (tlv_add(&tlv, attempts & 0xf) != SC_SUCCESS /* flags byte */
522
0
      || tlv_add(&tlv, CARDOS_ALGO_PIN) != SC_SUCCESS /* algorithm = pin-test */
523
0
      || tlv_add(&tlv, attempts & 0xf) != SC_SUCCESS /* errcount = attempts */)
524
0
    return SC_ERROR_INTERNAL;
525
526
  /* usecount: not documented, but seems to work like this:
527
   *  - value of 0xff means pin can be presented any number
528
   *  of times
529
   *  - anything less: max # of times before BS object is blocked.
530
   */
531
0
  if (tlv_add(&tlv, 0xff) != SC_SUCCESS)
532
0
    return SC_ERROR_INTERNAL;
533
534
  /* DEK: not documented, no idea what it means */
535
0
  if (tlv_add(&tlv, 0xff) != SC_SUCCESS)
536
0
    return SC_ERROR_INTERNAL;
537
538
  /* ARA counter: number of times the test object can be used before
539
   *              another verification is required (~ user consent)
540
   *              (0x00 unlimited usage)
541
   */
542
0
  if (tlv_add(&tlv, 0x00) != SC_SUCCESS
543
0
      || tlv_add(&tlv, minlen) != SC_SUCCESS /* minlen */)
544
0
    return SC_ERROR_INTERNAL;
545
546
  /* AC conditions */
547
0
  if (tlv_next(&tlv, 0x86) != SC_SUCCESS
548
0
      || tlv_add(&tlv, 0x00) != SC_SUCCESS /* use: always */
549
0
      || tlv_add(&tlv, auth_info->attrs.pin.reference) != SC_SUCCESS /* change: PIN */
550
0
      || tlv_add(&tlv, puk_id) != SC_SUCCESS /* unblock: PUK */)
551
0
    return SC_ERROR_INTERNAL;
552
553
  /* data: PIN */
554
0
  if (tlv_next(&tlv, 0x8f) != SC_SUCCESS)
555
0
    return SC_ERROR_INTERNAL;
556
0
  while (pin_len--)
557
0
    if (tlv_add(&tlv, *pin++) != SC_SUCCESS)
558
0
      return SC_ERROR_INTERNAL;
559
560
0
  args.data = buffer;
561
0
  args.len = tlv_len(&tlv);
562
563
  /* ensure we are in the correct lifecycle */
564
0
  r = sc_pkcs15init_set_lifecycle(card, SC_CARDCTRL_LIFECYCLE_ADMIN);
565
0
  if (r < 0 && r != SC_ERROR_NOT_SUPPORTED)
566
0
    return r;
567
568
0
  return sc_card_ctl(card, SC_CARDCTL_CARDOS_PUT_DATA_OCI, &args);
569
0
}
570
571
/*
572
 * Create an empty security environment
573
 */
574
static int
575
cardos_create_sec_env(struct sc_profile *profile, sc_card_t *card,
576
    unsigned int se_id, unsigned int key_id)
577
0
{
578
0
  struct sc_cardctl_cardos_obj_info args;
579
0
  struct tlv  tlv;
580
0
  unsigned char buffer[64];
581
0
  int   r;
582
583
0
  tlv_init(&tlv, buffer, sizeof(buffer));
584
0
  if (tlv_next(&tlv, 0x83) != SC_SUCCESS
585
0
      || tlv_add(&tlv, se_id) != SC_SUCCESS
586
0
      || tlv_next(&tlv, 0x86) != SC_SUCCESS
587
0
      || tlv_add(&tlv, 0) != SC_SUCCESS
588
0
      || tlv_add(&tlv, 0) != SC_SUCCESS
589
0
      || tlv_next(&tlv, 0x8f) != SC_SUCCESS
590
0
      || tlv_add(&tlv, key_id) != SC_SUCCESS
591
0
      || tlv_add(&tlv, key_id) != SC_SUCCESS
592
0
      || tlv_add(&tlv, key_id) != SC_SUCCESS
593
0
      || tlv_add(&tlv, key_id) != SC_SUCCESS
594
0
      || tlv_add(&tlv, key_id) != SC_SUCCESS
595
0
      || tlv_add(&tlv, key_id) != SC_SUCCESS)
596
0
    return SC_ERROR_INTERNAL;
597
598
0
  args.data = buffer;
599
0
  args.len = tlv_len(&tlv);
600
601
  /* ensure we are in the correct lifecycle */
602
0
  r = sc_pkcs15init_set_lifecycle(card, SC_CARDCTRL_LIFECYCLE_ADMIN);
603
0
  if (r < 0 && r != SC_ERROR_NOT_SUPPORTED)
604
0
    return r;
605
606
0
  return sc_card_ctl(card, SC_CARDCTL_CARDOS_PUT_DATA_SECI, &args);
607
0
}
608
609
/*
610
 * Determine the key algorithm based on the intended usage
611
 * Note that CardOS/M4 does not support keys that can be used
612
 * for signing _and_ decipherment
613
 */
614
0
#define USAGE_ANY_SIGN    (SC_PKCS15_PRKEY_USAGE_SIGN|\
615
0
         SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)
616
0
#define USAGE_ANY_DECIPHER  (SC_PKCS15_PRKEY_USAGE_DECRYPT|\
617
0
         SC_PKCS15_PRKEY_USAGE_UNWRAP)
618
619
static int cardos_key_algorithm(unsigned int usage, size_t keylen, int *algop)
620
0
{
621
  /* if it is sign and decipher, we use decipher and emulate sign */
622
0
  if (usage & USAGE_ANY_DECIPHER) {
623
0
    if (keylen <= 1024)
624
0
      *algop = CARDOS_ALGO_RSA_PURE;
625
0
    else
626
0
      *algop = CARDOS_ALGO_EXT_RSA_PURE;
627
0
    return 0;
628
0
  }
629
0
  if (usage & USAGE_ANY_SIGN) {
630
0
    if (keylen <= 1024)
631
0
      *algop = CARDOS_ALGO_RSA_PURE_SIG;
632
0
    else
633
0
      *algop = CARDOS_ALGO_EXT_RSA_SIG_PURE;
634
0
    return 0;
635
0
  }
636
0
  return -1;
637
0
}
638
639
/*
640
 * Create a private key object
641
 */
642
0
#define CARDOS_KEY_OPTIONS  0x02
643
0
#define CARDOS_KEY_FLAGS  0x00
644
static int
645
cardos_store_key_component(sc_card_t *card,
646
    int algorithm,
647
    unsigned int key_id, unsigned int pin_id,
648
    unsigned int num,
649
    const u8 *data, size_t len,
650
    int last, int use_prefix)
651
0
{
652
0
  struct sc_cardctl_cardos_obj_info args;
653
0
  struct tlv  tlv;
654
0
  unsigned char buffer[256];
655
#ifdef SET_SM_BYTES
656
  unsigned int  n;
657
#endif
658
0
  int   r;
659
660
  /* Initialize the TLV encoder */
661
0
  tlv_init(&tlv, buffer, sizeof(buffer));
662
663
  /* Object address */
664
0
  if (tlv_next(&tlv, 0x83) != SC_SUCCESS
665
0
      || tlv_add(&tlv, 0x20|num) != SC_SUCCESS /* PSO, n-th component */
666
0
      || tlv_add(&tlv, key_id) != SC_SUCCESS)
667
0
    return SC_ERROR_INTERNAL;
668
669
  /* Object parameters */
670
0
  if (tlv_next(&tlv, 0x85) != SC_SUCCESS
671
0
      || tlv_add(&tlv, CARDOS_KEY_OPTIONS|(last? 0x00 : 0x20)) != SC_SUCCESS
672
0
      || tlv_add(&tlv, CARDOS_KEY_FLAGS) != SC_SUCCESS
673
0
      || tlv_add(&tlv, algorithm) != SC_SUCCESS
674
0
      || tlv_add(&tlv, 0x00) != SC_SUCCESS
675
0
      || tlv_add(&tlv, 0xFF) != SC_SUCCESS /* use count */
676
0
      || tlv_add(&tlv, 0xFF) != SC_SUCCESS /* DEK (whatever this is) */
677
0
      || tlv_add(&tlv, 0x00) != SC_SUCCESS
678
0
      || tlv_add(&tlv, 0x00) != SC_SUCCESS)
679
0
    return SC_ERROR_INTERNAL;
680
681
  /* AC bytes */
682
0
  if (tlv_next(&tlv, 0x86) != SC_SUCCESS
683
0
      || tlv_add(&tlv, pin_id) != SC_SUCCESS /* AC USE */
684
0
      || tlv_add(&tlv, pin_id) != SC_SUCCESS /* AC CHANGE */
685
0
      || tlv_add(&tlv, pin_id) != SC_SUCCESS /* UNKNOWN */
686
0
      || tlv_add(&tlv, 0) != SC_SUCCESS /* rfu */
687
0
      || tlv_add(&tlv, 0) != SC_SUCCESS /* rfu */
688
0
      || tlv_add(&tlv, 0) != SC_SUCCESS /* rfu */
689
0
      || tlv_add(&tlv, 0) != SC_SUCCESS)
690
0
    return SC_ERROR_INTERNAL;
691
692
#ifdef SET_SM_BYTES
693
  /* it shouldn't be necessary to set the default value */
694
  /* SM bytes */
695
  if (tlv_next(&tlv, 0x8B) != SC_SUCCESS)
696
    return SC_ERROR_INTERNAL;
697
  for (n = 0; n < 16; n++)
698
    if (tlv_add(&tlv, 0xFF) != SC_SUCCESS)
699
      return SC_ERROR_INTERNAL;
700
#endif
701
702
  /* key component */
703
0
  if (tlv_next(&tlv, 0x8f) != SC_SUCCESS)
704
0
    return SC_ERROR_INTERNAL;
705
0
  if (use_prefix != 0) {
706
0
    if (tlv_add(&tlv, len+1) != SC_SUCCESS
707
0
    || tlv_add(&tlv, 0) != SC_SUCCESS)
708
0
      return SC_ERROR_INTERNAL;
709
0
  }
710
0
  while (len--)
711
0
    if (tlv_add(&tlv, *data++) != SC_SUCCESS)
712
0
      return SC_ERROR_INTERNAL;
713
714
0
  args.data = buffer;
715
0
  args.len = tlv_len(&tlv);
716
717
  /* ensure we are in the correct lifecycle */
718
0
  r = sc_pkcs15init_set_lifecycle(card, SC_CARDCTRL_LIFECYCLE_ADMIN);
719
0
  if (r < 0 && r != SC_ERROR_NOT_SUPPORTED)
720
0
    return r;
721
722
0
  return sc_card_ctl(card, SC_CARDCTL_CARDOS_PUT_DATA_OCI, &args);
723
0
}
724
725
726
static int
727
cardos_put_key(sc_profile_t *profile, struct sc_pkcs15_card *p15card,
728
  int algorithm, sc_pkcs15_prkey_info_t *key_info,
729
  struct sc_pkcs15_prkey_rsa *key)
730
0
{
731
0
  struct sc_card *card = p15card->card;
732
0
  int r, key_id, pin_id;
733
734
0
  pin_id = sc_pkcs15init_get_pin_reference(p15card, profile, SC_AC_SYMBOLIC,
735
0
      SC_PKCS15INIT_USER_PIN);
736
0
  if (pin_id < 0)
737
0
    pin_id = 0;
738
739
0
  key_id = key_info->key_reference;
740
0
  if (key_info->modulus_length > 1024 && (card->type == SC_CARD_TYPE_CARDOS_M4_2 ||
741
0
      card->type == SC_CARD_TYPE_CARDOS_M4_3 ||card->type == SC_CARD_TYPE_CARDOS_M4_2B ||
742
0
      card->type == SC_CARD_TYPE_CARDOS_M4_2C ||card->type == SC_CARD_TYPE_CARDOS_M4_4)) {
743
0
    r = cardos_store_key_component(card, algorithm, key_id, pin_id, 0,
744
0
      key->p.data, key->p.len, 0, 0);
745
0
    if (r != SC_SUCCESS)
746
0
      return r;
747
0
    r = cardos_store_key_component(card, algorithm, key_id, pin_id, 1,
748
0
      key->q.data, key->q.len, 0, 0);
749
0
    if (r != SC_SUCCESS)
750
0
      return r;
751
0
    r = cardos_store_key_component(card, algorithm, key_id, pin_id, 2,
752
0
      key->dmp1.data, key->dmp1.len, 0, 0);
753
0
    if (r != SC_SUCCESS)
754
0
      return r;
755
0
    r = cardos_store_key_component(card, algorithm, key_id, pin_id, 3,
756
0
      key->dmq1.data, key->dmq1.len, 0, 0);
757
0
    if (r != SC_SUCCESS)
758
0
      return r;
759
0
    r = cardos_store_key_component(card, algorithm, key_id, pin_id, 4,
760
0
      key->iqmp.data, key->iqmp.len, 1, 0);
761
0
  } else {
762
0
    r = cardos_store_key_component(card, algorithm, key_id, pin_id, 0,
763
0
      key->modulus.data, key->modulus.len, 0, 1);
764
0
    if (r != SC_SUCCESS)
765
0
      return r;
766
0
    r = cardos_store_key_component(card, algorithm, key_id, pin_id, 1,
767
0
      key->d.data, key->d.len, 1, 1);
768
0
  }
769
770
0
  return r;
771
0
}
772
773
/*
774
 * Extract a key component from the public key file populated by
775
 * GENERATE KEY PAIR
776
 */
777
static int parse_ext_pubkey_file(sc_card_t *card, const u8 *data, size_t len,
778
  sc_pkcs15_pubkey_t *pubkey)
779
0
{
780
0
  const u8     *p;
781
0
  size_t       ilen = 0, tlen = 0;
782
783
0
  if (data == NULL || len < 32)
784
0
    return SC_ERROR_INVALID_ARGUMENTS;
785
0
  data = sc_asn1_find_tag(card->ctx, data, len, 0x7f49, &ilen);
786
0
  if (data == NULL) {
787
0
    sc_log(card->ctx,  "invalid public key data: missing tag");
788
0
    return SC_ERROR_INTERNAL;
789
0
  }
790
791
0
  p = sc_asn1_find_tag(card->ctx, data, ilen, 0x81, &tlen);
792
0
  if (p == NULL) {
793
0
    sc_log(card->ctx,  "invalid public key data: missing modulus");
794
0
    return SC_ERROR_INTERNAL;
795
0
  }
796
0
  pubkey->u.rsa.modulus.len  = tlen;
797
0
  pubkey->u.rsa.modulus.data = malloc(tlen);
798
0
  if (pubkey->u.rsa.modulus.data == NULL)
799
0
    return SC_ERROR_OUT_OF_MEMORY;
800
0
  memcpy(pubkey->u.rsa.modulus.data, p, tlen);
801
802
0
  p = sc_asn1_find_tag(card->ctx, data, ilen, 0x82, &tlen);
803
0
  if (p == NULL) {
804
0
    sc_log(card->ctx,  "invalid public key data: missing exponent");
805
0
    return SC_ERROR_INTERNAL;
806
0
  }
807
0
  pubkey->u.rsa.exponent.len  = tlen;
808
0
  pubkey->u.rsa.exponent.data = malloc(tlen);
809
0
  if (pubkey->u.rsa.exponent.data == NULL)
810
0
    return SC_ERROR_OUT_OF_MEMORY;
811
0
  memcpy(pubkey->u.rsa.exponent.data, p, tlen);
812
813
0
  return SC_SUCCESS;
814
0
}
815
816
static int
817
do_cardos_extract_pubkey(sc_card_t *card, int nr, u8 tag,
818
      sc_pkcs15_bignum_t *bn)
819
0
{
820
0
  u8  buf[256];
821
0
  int r, count;
822
823
0
  r = sc_read_record(card, nr, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR);
824
0
  if (r < 0)
825
0
    return r;
826
0
  count = r - 4;
827
0
  if (count <= 0 || buf[0] != tag || buf[1] != count + 2
828
0
      || buf[2] != count + 1 || buf[3] != 0)
829
0
    return SC_ERROR_INTERNAL;
830
0
  bn->len = count;
831
0
  bn->data = malloc(count);
832
0
  if (bn->data == NULL)
833
0
    return SC_ERROR_OUT_OF_MEMORY;
834
0
  memcpy(bn->data, buf + 4, count);
835
0
  return SC_SUCCESS;
836
0
}
837
838
static int cardos_extract_pubkey(sc_card_t *card, sc_pkcs15_pubkey_t *pubkey,
839
  sc_file_t *tfile, int use_ext_rsa)
840
0
{
841
0
  int r;
842
843
0
  memset(pubkey, 0, sizeof(*pubkey));
844
845
0
  r = sc_select_file(card, &tfile->path, NULL);
846
0
  if (r != SC_SUCCESS)
847
0
    return r;
848
849
0
  if (use_ext_rsa == 0) {
850
0
    r = do_cardos_extract_pubkey(card, 1, 0x10, &pubkey->u.rsa.modulus);
851
0
    if (r != SC_SUCCESS)
852
0
      return r;
853
0
    r = do_cardos_extract_pubkey(card, 2, 0x11, &pubkey->u.rsa.exponent);
854
0
  } else {
855
0
    u8 *buf;
856
857
0
    buf = malloc(tfile->size);
858
0
    if (buf == NULL)
859
0
      return SC_ERROR_OUT_OF_MEMORY;
860
0
    r = sc_read_binary(card, 0, buf, tfile->size, 0);
861
0
    if (r > 0)
862
0
      r = parse_ext_pubkey_file(card, buf, (size_t)r, pubkey);
863
0
    free(buf);
864
0
  }
865
866
0
  pubkey->algorithm = SC_ALGORITHM_RSA;
867
868
0
  return r;
869
0
}
870
871
static int cardos_have_verifyrc_package(sc_card_t *card)
872
0
{
873
0
  sc_apdu_t apdu;
874
0
        u8        rbuf[SC_MAX_APDU_BUFFER_SIZE];
875
0
        int       r;
876
0
  const u8  *p = rbuf, *q, *pp;
877
0
  size_t    len, tlen = 0, ilen = 0;
878
879
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x88);
880
0
  apdu.resp    = rbuf;
881
0
  apdu.resplen = sizeof(rbuf);
882
0
  apdu.lc = 0;
883
0
  apdu.le = 256;
884
0
  r = sc_transmit_apdu(card, &apdu);
885
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
886
887
0
  if ((len = apdu.resplen) == 0)
888
    /* looks like no package has been installed  */
889
0
    return 0;
890
891
0
  while (len != 0) {
892
0
    pp = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen);
893
0
    if (pp == NULL)
894
0
      return 0;
895
0
    if (card->type == SC_CARD_TYPE_CARDOS_M4_3) {
896
      /* the verifyRC package on CardOS 4.3B use Manufacturer ID 0x01 */
897
      /* and Package Number 0x07          */
898
0
      q = sc_asn1_find_tag(card->ctx, pp, tlen, 0x01, &ilen);
899
0
      if (q == NULL || ilen != 4)
900
0
        return 0;
901
0
      if (q[0] == 0x07)
902
0
        return 1;
903
0
    } else if (card->type == SC_CARD_TYPE_CARDOS_M4_4) {
904
      /* the verifyRC package on CardOS 4.4 use Manufacturer ID 0x03  */
905
      /* and Package Number 0x02          */
906
0
      q = sc_asn1_find_tag(card->ctx, pp, tlen, 0x03, &ilen);
907
0
      if (q == NULL || ilen != 4)
908
0
        return 0;
909
0
      if (q[0] == 0x02)
910
0
        return 1;
911
0
    } else  {
912
0
      return 0;
913
0
    }
914
0
    p   += tlen;
915
0
    len -= tlen + 2;
916
0
  }
917
918
0
  return 0;
919
0
}
920
921
static struct sc_pkcs15init_operations sc_pkcs15init_cardos_operations = {
922
  cardos_erase,
923
  NULL,       /* init_card */
924
  cardos_create_dir,
925
  NULL,       /* create_domain */
926
  cardos_select_pin_reference,
927
  cardos_create_pin,
928
  cardos_select_key_reference,
929
  cardos_create_key,
930
  cardos_store_key,
931
  cardos_generate_key,
932
  NULL, NULL,       /* encode private/public key */
933
  NULL,       /* finalize_card */
934
  cardos_delete_object,
935
  NULL, NULL, NULL, NULL, NULL,   /* pkcs15init emulation */
936
  NULL        /* sanity_check */
937
};
938
939
struct sc_pkcs15init_operations *
940
sc_pkcs15init_get_cardos_ops(void)
941
0
{
942
0
  return &sc_pkcs15init_cardos_operations;
943
0
}