Coverage Report

Created: 2026-04-09 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/pkcs15init/pkcs15-epass2003.c
Line
Count
Source
1
/*
2
 * Support for ePass2003 smart cards
3
 *
4
 * Copyright (C) 2008, Weitao Sun <weitao@ftsafe.com>
5
 * Copyright (C) 2011, Xiaoshuo Wu <xiaoshuo@ftsafe.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 <sys/types.h>
25
#include <stdlib.h>
26
#include <string.h>
27
#include <stdarg.h>
28
29
#include "libopensc/log.h"
30
#include "libopensc/opensc.h"
31
#include "libopensc/cardctl.h"
32
#include "libopensc/cards.h"
33
#include "pkcs15-init.h"
34
#include "profile.h"
35
static int epass2003_pkcs15_erase_card(struct sc_profile *profile,
36
               struct sc_pkcs15_card *p15card)
37
284
{
38
284
  SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
39
40
284
  if (sc_select_file(p15card->card, sc_get_mf_path(), NULL) < 0)
41
266
    return SC_SUCCESS;
42
43
18
  return sc_card_ctl(p15card->card, SC_CARDCTL_ERASE_CARD, 0);
44
284
}
45
46
static int epass2003_pkcs15_init_card(struct sc_profile *profile,
47
              struct sc_pkcs15_card *p15card)
48
82
{
49
82
  struct sc_card *card = p15card->card;
50
82
  int ret;
51
52
82
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
53
82
  sc_do_log(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,NULL,0,NULL,
54
82
      "ePass2003 doesn't support SO-PIN and SO-PUK. You can unblock key with PUK. \n");
55
82
  {     /* MF */
56
82
    struct sc_file *mf_file;
57
82
    struct sc_file *skey_file;
58
59
82
    ret = sc_profile_get_file(profile, "MF", &mf_file);
60
82
    LOG_TEST_RET(card->ctx, ret,
61
82
          "Get MF info failed");
62
82
    ret = sc_create_file(card, mf_file);
63
82
    sc_file_free(mf_file);
64
82
    LOG_TEST_RET(card->ctx, ret,
65
1
          "Create MF failed");
66
67
1
    ret = sc_profile_get_file(profile, "SKey-MF", &skey_file);
68
1
    LOG_TEST_RET(card->ctx, ret,
69
0
          "Get SKey info failed");
70
0
    ret = sc_create_file(card, skey_file);
71
0
    sc_file_free(skey_file);
72
0
    LOG_TEST_RET(card->ctx, ret,
73
0
          "Create SKey failed");
74
75
0
  }
76
77
0
  {     /* EF(DIR) */
78
0
    struct sc_file *dir_file;
79
80
    /* get dir profile */
81
0
    ret = sc_profile_get_file(profile, "DIR", &dir_file);
82
0
    LOG_TEST_RET(card->ctx, ret,
83
0
          "Get EF(DIR) info failed");
84
0
    ret = sc_create_file(card, dir_file);
85
0
    sc_file_free(dir_file);
86
0
    LOG_TEST_RET(card->ctx, ret,
87
0
          "Create EF(DIR) failed");
88
89
0
    sc_free_apps(card);
90
0
  }
91
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
92
0
}
93
94
static int epass2003_pkcs15_create_dir(struct sc_profile *profile,
95
               struct sc_pkcs15_card *p15card,
96
               struct sc_file *df)
97
0
{
98
0
  struct sc_card *card = p15card->card;
99
0
  int ret;
100
101
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
102
103
0
  {     /* p15 DF */
104
0
    struct sc_file *df_file;
105
0
    struct sc_file *skey_file;
106
0
    struct sc_file *ef_file;
107
0
    u8 max_counter[2] = { 0 };
108
0
    int id;
109
0
    u8 user_maxtries = 0;
110
0
    u8 so_maxtries = 0;
111
112
0
    ret = sc_profile_get_file(profile, "PKCS15-AppDF", &df_file);
113
0
    LOG_TEST_RET(card->ctx, ret,
114
0
          "Get PKCS15-AppDF info failed");
115
0
    ret = sc_create_file(card, df_file);
116
0
    sc_file_free(df_file);
117
0
    LOG_TEST_RET(card->ctx, ret,
118
0
          "Create PKCS15-AppDF failed");
119
120
0
    ret = sc_profile_get_file(profile, "SKey-AppDF", &skey_file);
121
0
    LOG_TEST_RET(card->ctx, ret,
122
0
          "Get SKey info failed");
123
0
    ret = sc_create_file(card, skey_file);
124
0
    sc_file_free(skey_file);
125
0
    LOG_TEST_RET(card->ctx, ret,
126
0
          "Create SKey info failed");
127
128
0
    ret = sc_profile_get_file(profile, "MAXPIN", &ef_file);
129
0
    LOG_TEST_RET(card->ctx, ret,
130
0
          "Get MAXPIN info failed");
131
0
    ret = sc_create_file(card, ef_file);
132
0
    LOG_TEST_RET(card->ctx, ret,
133
0
          "Create MAXPIN failed");
134
0
    ret = sc_select_file(card, &(ef_file->path), &ef_file);
135
0
    LOG_TEST_RET(card->ctx, ret,
136
0
          "Select MAXPIN failed");
137
138
0
    ret = sc_profile_get_pin_id(profile, 2, &id);
139
0
    LOG_TEST_RET(card->ctx, ret,
140
0
          "Get User PIN id error!");
141
0
    user_maxtries = (u8) sc_profile_get_pin_retries(profile, id);
142
143
0
    ret = sc_profile_get_pin_id(profile, 1, &id);
144
0
    LOG_TEST_RET(card->ctx, ret,
145
0
          "Get User PIN id error!");
146
0
    so_maxtries = (u8) sc_profile_get_pin_retries(profile, id);
147
148
0
    max_counter[0] = user_maxtries;
149
0
    max_counter[1] = so_maxtries;
150
151
0
    ret = sc_update_binary(card, 0, max_counter, 2, 0);
152
153
0
    LOG_TEST_RET(card->ctx, ret,
154
0
          "Update MAXPIN failed");
155
0
    sc_file_free(ef_file);
156
0
  }
157
158
0
  {     /* p15 efs */
159
0
    char *create_efs[] = {
160
0
      "PKCS15-ODF",
161
0
      "PKCS15-TokenInfo",
162
0
      "PKCS15-UnusedSpace",
163
0
      "PKCS15-AODF",
164
0
      "PKCS15-PrKDF",
165
0
      "PKCS15-PuKDF",
166
0
      "PKCS15-CDF",
167
0
      "PKCS15-DODF",
168
0
      NULL,
169
0
    };
170
0
    int i;
171
0
    struct sc_file *file = 0;
172
173
0
    for (i = 0; create_efs[i]; ++i) {
174
0
      if (sc_profile_get_file(profile, create_efs[i], &file)) {
175
0
        sc_log(card->ctx,
176
0
           "Inconsistent profile: cannot find %s",
177
0
           create_efs[i]);
178
0
        SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,
179
0
                 SC_ERROR_INCONSISTENT_PROFILE);
180
0
      }
181
0
      ret = sc_create_file(card, file);
182
0
      sc_file_free(file);
183
0
      LOG_TEST_RET(card->ctx, ret,
184
0
            "Create pkcs15 file failed");
185
0
    }
186
0
  }
187
188
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, ret);
189
0
}
190
191
static int epass2003_pkcs15_pin_reference(struct sc_profile *profile,
192
            struct sc_pkcs15_card *p15card,
193
            struct sc_pkcs15_auth_info *auth_info)
194
409
{
195
409
  SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
196
197
409
  if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
198
0
    return SC_ERROR_OBJECT_NOT_VALID;
199
200
409
  if (auth_info->attrs.pin.reference < ENTERSAFE_USER_PIN_ID
201
150
      || auth_info->attrs.pin.reference > ENTERSAFE_SO_PIN_ID)
202
295
    return SC_ERROR_INVALID_PIN_REFERENCE;
203
204
114
  SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
205
114
}
206
207
static int epass2003_pkcs15_create_pin(struct sc_profile *profile,
208
               struct sc_pkcs15_card *p15card,
209
               struct sc_file *df,
210
               struct sc_pkcs15_object *pin_obj,
211
               const unsigned char *pin, size_t pin_len,
212
               const unsigned char *puk, size_t puk_len)
213
28
{
214
28
  struct sc_card *card = p15card->card;
215
28
  int r;
216
28
  struct sc_pkcs15_auth_info *auth_info;
217
218
28
  if (NULL == pin_obj)
219
0
    return SC_ERROR_INVALID_ARGUMENTS;
220
221
28
  auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data;
222
223
28
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
224
225
28
  if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
226
0
    return SC_ERROR_OBJECT_NOT_VALID;
227
228
28
  {     /*pin */
229
28
    sc_epass2003_wkey_data data;
230
28
    int id;
231
232
28
    if (!pin || !pin_len || pin_len > 16)
233
0
      return SC_ERROR_INVALID_ARGUMENTS;
234
235
28
    data.type = SC_EPASS2003_SECRET_PIN;
236
28
    data.key_data.es_secret.kid = auth_info->attrs.pin.reference;
237
28
    data.key_data.es_secret.ac[0] =
238
28
        EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE;
239
28
    data.key_data.es_secret.ac[1] =
240
28
        EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_USER;
241
242
28
    r = sc_profile_get_pin_id(profile, 2, &id);
243
28
    LOG_TEST_RET(card->ctx, r,
244
17
          "Get User PIN id error!");
245
17
    data.key_data.es_secret.EC =
246
17
        sc_profile_get_pin_retries(profile, id);
247
248
    /* pad pin with 0 */
249
17
    memset(data.key_data.es_secret.key_val, 0,
250
17
           sizeof(data.key_data.es_secret.key_val));
251
17
    memcpy(data.key_data.es_secret.key_val, pin, pin_len);
252
17
    data.key_data.es_secret.key_len = pin_len;
253
254
17
    r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
255
17
    if (r < 0)
256
12
      SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
257
5
    if (pin_obj) {
258
      /* Cache new PIN value. */
259
5
      sc_pkcs15_pincache_add(p15card, pin_obj, pin, pin_len);
260
5
    }
261
5
  }
262
263
0
  {     /*puk */
264
5
    sc_epass2003_wkey_data data;
265
5
    int id;
266
267
5
    if (!puk || !puk_len || puk_len > 16)
268
0
      return SC_ERROR_INVALID_ARGUMENTS;
269
270
5
    data.type = SC_EPASS2003_SECRET_PIN;
271
5
    data.key_data.es_secret.kid =
272
5
        auth_info->attrs.pin.reference + 1;
273
5
    data.key_data.es_secret.ac[0] =
274
5
        EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE;
275
5
    data.key_data.es_secret.ac[1] =
276
5
        EPASS2003_AC_MAC_EQUAL | EPASS2003_AC_SO;
277
278
5
    r = sc_profile_get_pin_id(profile, 1, &id);
279
5
    LOG_TEST_RET(card->ctx, r,
280
2
          "Get User PIN id error!");
281
2
    data.key_data.es_secret.EC =
282
2
        sc_profile_get_pin_retries(profile, id);
283
284
    /* pad pin with 0 */
285
2
    memset(data.key_data.es_secret.key_val, 0,
286
2
           sizeof(data.key_data.es_secret.key_val));
287
2
    memcpy(data.key_data.es_secret.key_val, puk, puk_len);
288
2
    data.key_data.es_secret.key_len = puk_len;
289
290
2
    r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
291
2
  }
292
293
2
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
294
2
}
295
296
static int epass2003_pkcs15_key_reference(struct sc_profile *profile,
297
            struct sc_pkcs15_card *p15card,
298
            struct sc_pkcs15_prkey_info *prkey)
299
556
{
300
556
  SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
301
556
  if (prkey->path.len == 0)
302
148
    SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
303
408
  prkey->key_reference = prkey->path.value[prkey->path.len - 1];
304
408
  SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
305
408
}
306
307
/* from pkcs15-oberthur.c, modified */
308
static int
309
cosm_new_file(struct sc_profile *profile, struct sc_card *card,
310
        unsigned int type, unsigned int num, struct sc_file **out)
311
532
{
312
532
  struct sc_file *file = NULL;
313
532
  const char *_template = NULL, *desc = NULL;
314
532
  unsigned int structure = 0xFFFFFFFF;
315
316
532
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
317
532
  sc_log(card->ctx,  "type %X; num %i\n", type,
318
532
     num);
319
532
  while (1) {
320
532
    switch (type) {
321
204
    case SC_PKCS15_TYPE_PRKEY_EC:
322
204
      desc = "EC private key";
323
204
      _template = "private-key";
324
204
      structure = SC_CARDCTL_OBERTHUR_KEY_EC_CRT;
325
204
      break;
326
64
    case SC_PKCS15_TYPE_PUBKEY_EC:
327
64
      desc = "EC public key";
328
64
      _template = "public-key";
329
64
      structure = SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC;
330
64
      break;
331
204
    case SC_PKCS15_TYPE_PRKEY_RSA:
332
204
      desc = "RSA private key";
333
204
      _template = "private-key";
334
204
      structure = SC_CARDCTL_OBERTHUR_KEY_RSA_CRT;
335
204
      break;
336
60
    case SC_PKCS15_TYPE_PUBKEY_RSA:
337
60
      desc = "RSA public key";
338
60
      _template = "public-key";
339
60
      structure = SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC;
340
60
      break;
341
0
    case SC_PKCS15_TYPE_PRKEY:
342
0
      desc = "extractable private key";
343
0
      _template = "extractable-key";
344
0
      break;
345
0
    case SC_PKCS15_TYPE_CERT:
346
0
      desc = "certificate";
347
0
      _template = "certificate";
348
0
      break;
349
0
    case SC_PKCS15_TYPE_DATA_OBJECT:
350
0
      desc = "data object";
351
0
      _template = "data";
352
0
      break;
353
532
    }
354
532
    if (_template)
355
532
      break;
356
    /* If this is a specific type such as
357
     * SC_PKCS15_TYPE_CERT_FOOBAR, fall back to
358
     * the generic class (SC_PKCS15_TYPE_CERT)
359
     */
360
0
    if (!(type & ~SC_PKCS15_TYPE_CLASS_MASK)) {
361
0
      sc_log(card->ctx,
362
0
         "File type %X not supported by card driver",
363
0
         type);
364
0
      return SC_ERROR_INVALID_ARGUMENTS;
365
0
    }
366
0
    type &= SC_PKCS15_TYPE_CLASS_MASK;
367
0
  }
368
369
532
  sc_log(card->ctx,  "template %s; num %i\n",
370
532
     _template, num);
371
532
  if (sc_profile_get_file(profile, _template, &file) < 0) {
372
98
    sc_log(card->ctx,
373
98
       "Profile doesn't define %s template '%s'\n", desc,
374
98
       _template);
375
98
    return SC_ERROR_NOT_SUPPORTED;
376
98
  }
377
378
434
  if (file->path.len < 1) {
379
17
    sc_file_free(file);
380
17
    return SC_ERROR_INTERNAL;
381
17
  }
382
383
417
  file->id &= 0xFF00;
384
417
  file->id |= (num & 0x00FF);
385
386
417
  file->path.value[file->path.len - 1] = (num & 0xFF);
387
417
  file->type = SC_FILE_TYPE_INTERNAL_EF;
388
417
  file->ef_structure = structure;
389
390
417
  sc_log(card->ctx,
391
417
     "file size %"SC_FORMAT_LEN_SIZE_T"u; ef type %i/%i; id %04X, path_len %"SC_FORMAT_LEN_SIZE_T"u\n",
392
417
     file->size, file->type, file->ef_structure, file->id,
393
417
     file->path.len);
394
417
  sc_log(card->ctx,  "file path: %s",
395
417
     sc_print_path(&(file->path)));
396
417
  *out = file;
397
398
417
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
399
417
}
400
401
static int epass2003_pkcs15_create_key(struct sc_profile *profile,
402
               struct sc_pkcs15_card *p15card,
403
               struct sc_pkcs15_object *obj)
404
408
{
405
408
  struct sc_card *card = p15card->card;
406
407
408
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
408
408
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
409
408
}
410
411
static int epass2003_pkcs15_store_key(struct sc_profile *profile,
412
              struct sc_pkcs15_card *p15card,
413
              struct sc_pkcs15_object *obj,
414
              struct sc_pkcs15_prkey *key)
415
0
{
416
0
  struct sc_card *card = p15card->card;
417
0
  struct sc_pkcs15_prkey_info *key_info =
418
0
      (struct sc_pkcs15_prkey_info *)obj->data;
419
0
  size_t idx = key_info->key_reference;
420
0
  size_t keybits = key_info->modulus_length;
421
0
  struct sc_path path;
422
0
  struct sc_file *tfile = NULL;
423
0
  struct sc_file *file = NULL;
424
0
  sc_epass2003_wkey_data data;
425
0
  int r;
426
0
  int fidl = 0;
427
428
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
429
430
0
  sc_log(card->ctx,
431
0
     "index %"SC_FORMAT_LEN_SIZE_T"u; id %s\n", idx,
432
0
     sc_pkcs15_print_id(&key_info->id));
433
0
  if (key->algorithm != SC_ALGORITHM_RSA
434
0
      || key->algorithm != SC_ALGORITHM_RSA)
435
0
    LOG_TEST_RET(card->ctx,
436
0
          SC_ERROR_NOT_SUPPORTED,
437
0
          "store key: only support RSA");
438
439
0
  sc_log(card->ctx,
440
0
     "store key: with ID:%s and path:%s",
441
0
     sc_pkcs15_print_id(&key_info->id),
442
0
     sc_print_path(&key_info->path));
443
444
  /* allocate key object */
445
0
  r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA,
446
0
        key_info->key_reference, &file);
447
0
  LOG_TEST_RET(card->ctx, r,
448
0
        "create key: failed to allocate new key object");
449
0
  file->size = keybits;
450
0
  sc_log(card->ctx,  "private key path: %s",
451
0
     sc_print_path(&(file->path)));
452
0
  sc_log(card->ctx,  "private key_info path: %s",
453
0
     sc_print_path(&(key_info->path)));
454
0
  sc_delete_file(p15card->card, &file->path);
455
  /* create */
456
0
  r = sc_pkcs15init_create_file(profile, p15card, file);
457
0
  LOG_TEST_RET(card->ctx, r,
458
0
        "create key: failed to create key file");
459
460
0
  sc_log(card->ctx,
461
0
     "index %"SC_FORMAT_LEN_SIZE_T"u; keybits %"SC_FORMAT_LEN_SIZE_T"u\n",
462
0
     idx, keybits);
463
0
  if (keybits < 1024 || keybits > 2048 || (keybits % 0x20)) {
464
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,
465
0
       "Unsupported key size %"SC_FORMAT_LEN_SIZE_T"u\n",
466
0
       keybits);
467
0
    return SC_ERROR_INVALID_ARGUMENTS;
468
0
  }
469
470
0
  path = key_info->path;
471
0
  path.len -= 2;
472
473
0
  r = sc_select_file(card, &path, &tfile);
474
0
  LOG_TEST_RET(card->ctx, r,
475
0
        "generate key: no private object DF");
476
477
0
  r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
478
0
  LOG_TEST_RET(card->ctx, r,
479
0
        "No authorisation to store private key");
480
481
0
  sc_file_free(tfile);
482
483
0
  fidl = (file->id & 0xff) * FID_STEP;
484
0
  file->id = (file->id & 0xff00) + fidl;
485
0
  data.type = SC_EPASS2003_KEY_RSA;
486
0
  data.key_data.es_key.fid = file->id;
487
0
  data.key_data.es_key.rsa = (void *)&key->u.rsa;
488
489
0
  r = sc_card_ctl(p15card->card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
490
0
  LOG_TEST_RET(card->ctx, r,
491
0
        "store key: cannot update private key");
492
493
0
  sc_file_free(file);
494
495
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
496
0
}
497
498
static int epass2003_pkcs15_generate_key(struct sc_profile *profile,
499
           struct sc_pkcs15_card *p15card,
500
           struct sc_pkcs15_object *obj,
501
           struct sc_pkcs15_pubkey *pubkey)
502
408
{
503
408
  struct sc_card *card = p15card->card;
504
408
  int r;
505
408
  sc_epass2003_gen_key_data gendat;
506
408
  struct sc_pkcs15_prkey_info *key_info =
507
408
      (struct sc_pkcs15_prkey_info *)obj->data;
508
408
  int idx = key_info->key_reference;
509
408
  size_t keybits = key_info->modulus_length;
510
408
  struct sc_file *tfile = NULL, *pukf = NULL;
511
408
  struct sc_path path;
512
408
  struct sc_file *file = NULL;
513
408
  int fidl = 0;
514
515
408
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
516
517
408
  if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA && obj->type != SC_PKCS15_TYPE_PRKEY_EC)
518
0
    return SC_ERROR_NOT_SUPPORTED;
519
520
408
  if(obj->type == SC_PKCS15_TYPE_PRKEY_EC && keybits == 0)
521
204
    keybits = 256;   //EC key length is 256 ...
522
523
  /* allocate key object */
524
408
  r = cosm_new_file(profile, card, obj->type, idx, &file); //replace SC_PKCS15_TYPE_PRKEY_RSA with obj->type
525
408
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
526
408
        "create key: failed to allocate new key object");
527
312
  file->size = keybits;
528
312
  sc_log(card->ctx,  "private key path: %s",
529
312
     sc_print_path(&file->path));
530
312
  sc_log(card->ctx,  "private key_info path: %s",
531
312
     sc_print_path(&(key_info->path)));
532
533
312
  r = sc_pkcs15init_authenticate(profile, p15card, file,
534
312
               SC_AC_OP_DELETE);
535
312
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
536
312
        "generate key: pkcs15init_authenticate(SC_AC_OP_DELETE) failed");
537
538
308
  sc_delete_file(p15card->card, &file->path);
539
  /* create */
540
308
  r = sc_pkcs15init_create_file(profile, p15card, file);
541
308
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
542
308
        "create key: failed to create key file");
543
544
135
  sc_log(card->ctx,
545
135
     "index %u; keybits %"SC_FORMAT_LEN_SIZE_T"u\n",
546
135
     idx, keybits);
547
135
  if (keybits < 1024 || keybits > 2048 || (keybits % 0x20)) {
548
66
    if(obj->type == SC_PKCS15_TYPE_PRKEY_EC && keybits == 256)
549
66
    {
550
66
      sc_log(card->ctx, "current Alg is EC,Only support 256 ..\n");
551
66
    }
552
0
    else
553
0
    {
554
0
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,
555
0
         "Unsupported key size %"SC_FORMAT_LEN_SIZE_T"u\n",
556
0
         keybits);
557
0
      r = SC_ERROR_INVALID_ARGUMENTS;
558
0
      goto err;
559
0
    }
560
66
  }
561
562
135
  path = key_info->path;
563
135
  path.len -= 2;
564
565
135
  r = sc_select_file(card, &path, &tfile);
566
135
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
567
135
        "generate key: no private object DF");
568
569
125
  r = sc_pkcs15init_authenticate(profile, p15card, tfile,
570
125
               SC_AC_OP_CRYPTO);
571
125
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
572
125
        "generate key: pkcs15init_authenticate(SC_AC_OP_CRYPTO) failed");
573
574
125
  r = sc_pkcs15init_authenticate(profile, p15card, tfile,
575
125
               SC_AC_OP_CREATE);
576
125
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
577
125
        "generate key: pkcs15init_authenticate(SC_AC_OP_CREATE) failed");
578
579
124
  if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA )
580
64
  {
581
64
    r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PUBKEY_EC, idx, &pukf);
582
64
  }
583
60
  else
584
60
  {
585
60
    r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PUBKEY_RSA, idx, &pukf);
586
60
  }
587
588
124
  if (r < 0) {
589
19
    sc_log(card->ctx,
590
19
       "generate key: create temporary pukf failed\n");
591
19
    goto err;
592
19
  }
593
594
105
  pukf->size = keybits;
595
105
  pukf->id = pukf->path.value[pukf->path.len - 2] * 0x100
596
105
      + pukf->path.value[pukf->path.len - 1];
597
598
105
  sc_log(card->ctx,
599
105
     "public key size %"SC_FORMAT_LEN_SIZE_T"u; ef type %i/%i; id %04X; path: %s",
600
105
     pukf->size, pukf->type, pukf->ef_structure, pukf->id,
601
105
     sc_print_path(&pukf->path));
602
603
105
  r = sc_select_file(p15card->card, &pukf->path, NULL);
604
  /* if exist, delete */
605
105
  if (r == SC_SUCCESS) {
606
42
    r = sc_pkcs15init_authenticate(profile, p15card, pukf,
607
42
           SC_AC_OP_DELETE);
608
42
    SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
609
42
        "generate key - pubkey: pkcs15init_authenticate(SC_AC_OP_DELETE) failed");
610
611
39
    r = sc_pkcs15init_delete_by_path(profile, p15card, &pukf->path);
612
39
    if (r != SC_SUCCESS) {
613
29
      sc_log(card->ctx,
614
29
         "generate key: failed to delete existing key file\n");
615
29
      goto err;
616
29
    }
617
39
  }
618
  /* create */
619
73
  r = sc_pkcs15init_create_file(profile, p15card, pukf);
620
73
  if (r != SC_SUCCESS) {
621
23
    sc_log(card->ctx,
622
23
       "generate key: pukf create file failed\n");
623
23
    goto err;
624
23
  }
625
626
50
  r = sc_pkcs15init_authenticate(profile, p15card, pukf,
627
50
               SC_AC_OP_UPDATE);
628
50
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
629
50
        "generate key - pubkey: pkcs15init_authenticate(SC_AC_OP_UPDATE) failed");
630
631
  /* generate key pair */
632
47
  fidl = (file->id & 0xff) * FID_STEP;
633
47
  file->id = (file->id & 0xff00) + fidl;
634
47
  pukf->id = (pukf->id & 0xff00) + fidl;
635
47
  gendat.prkey_id = file->id;
636
47
  gendat.pukey_id = pukf->id;
637
47
  gendat.key_length = keybits;
638
47
  gendat.modulus = NULL;
639
47
  gendat.modulus_len = 0;
640
47
  r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_GENERATE_KEY, &gendat);
641
47
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
642
47
        "generate RSA key pair failed");
643
644
10
  if (!gendat.modulus) {
645
0
    r = SC_ERROR_OUT_OF_MEMORY;
646
0
    goto err;
647
0
  }
648
649
  /* get the modulus */
650
10
  if (pubkey && (obj->type == SC_PKCS15_TYPE_PRKEY_RSA)) {
651
8
    u8 *buf;
652
8
    struct sc_pkcs15_pubkey_rsa *rsa = &pubkey->u.rsa;
653
    /* set the modulus */
654
8
    rsa->modulus.data = gendat.modulus;
655
8
    rsa->modulus.len = keybits >> 3;
656
    /* set the exponent (always 0x10001) */
657
8
    buf = (u8 *) malloc(3);
658
8
    if (!buf) {
659
0
      r = SC_ERROR_OUT_OF_MEMORY;
660
0
      goto err;
661
0
    }
662
8
    buf[0] = 0x01;
663
8
    buf[1] = 0x00;
664
8
    buf[2] = 0x01;
665
8
    rsa->exponent.data = buf;
666
8
    rsa->exponent.len = 3;
667
668
8
    pubkey->algorithm = SC_ALGORITHM_RSA;
669
8
  }
670
2
  else if(pubkey && (obj->type == SC_PKCS15_TYPE_PRKEY_EC)){
671
2
    struct sc_ec_parameters *ecparams = (struct
672
2
        sc_ec_parameters *)key_info->params.data;
673
2
    pubkey->algorithm = SC_ALGORITHM_EC;
674
2
    pubkey->u.ec.ecpointQ.value = (u8 *)malloc(gendat.modulus_len + 1);
675
2
    if (!pubkey->u.ec.ecpointQ.value) {
676
0
      r = SC_ERROR_OUT_OF_MEMORY;
677
0
      goto err;
678
0
    }
679
680
2
    pubkey->u.ec.ecpointQ.value[0] = 0x04;
681
2
    memcpy(&pubkey->u.ec.ecpointQ.value[1], gendat.modulus, gendat.modulus_len);
682
2
    pubkey->u.ec.ecpointQ.len = gendat.modulus_len + 1;
683
2
    free(gendat.modulus);
684
685
2
    free(pubkey->u.ec.params.named_curve);
686
2
    pubkey->u.ec.params.named_curve = NULL;
687
688
2
    free(pubkey->u.ec.params.der.value);
689
2
    pubkey->u.ec.params.der.value = NULL;
690
2
    pubkey->u.ec.params.der.len = 0;
691
2
    pubkey->u.ec.params.named_curve = strdup(ecparams->named_curve);
692
693
2
    if (!pubkey->u.ec.params.named_curve){
694
0
      r = SC_ERROR_OUT_OF_MEMORY;
695
0
      goto err;
696
0
    }
697
698
2
    r = sc_pkcs15_fix_ec_parameters(card->ctx, &pubkey->u.ec.params);
699
2
  }
700
0
  else
701
    /* free public key */
702
0
    free(gendat.modulus);
703
704
408
err:
705
408
  sc_file_free(pukf);
706
408
  sc_file_free(file);
707
408
  sc_file_free(tfile);
708
709
408
  if(r < 0 && pubkey->u.ec.ecpointQ.value)
710
0
  {
711
0
    free(pubkey->u.ec.ecpointQ.value);
712
0
    pubkey->u.ec.ecpointQ.value = NULL;
713
0
    pubkey->u.ec.ecpointQ.len = 0;
714
0
  }
715
716
408
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
717
408
}
718
719
static int epass2003_pkcs15_delete_object(struct sc_profile *profile,
720
            struct sc_pkcs15_card *p15card,
721
            struct sc_pkcs15_object *object,
722
            const struct sc_path *path)
723
0
{
724
0
  SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
725
0
  return sc_pkcs15init_delete_by_path(profile, p15card, path);
726
0
}
727
728
static int epass2003_pkcs15_sanity_check(sc_profile_t * profile,
729
           sc_pkcs15_card_t * p15card)
730
284
{
731
284
  struct sc_context *ctx = p15card->card->ctx;
732
284
  struct sc_pkcs15_auth_info profile_auth = {0};
733
284
  struct sc_pkcs15_object *objs[32];
734
284
  int rv, nn, ii, update_df = 0;
735
736
284
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
737
738
284
  sc_log(ctx,
739
284
     "Check and if needed update PinFlags");
740
284
  rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32);
741
284
  LOG_TEST_RET(ctx, rv, "Failed to get PINs");
742
284
  nn = rv;
743
744
284
  sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &profile_auth);
745
284
  LOG_TEST_RET(ctx, rv, "Failed to get PIN info");
746
747
284
  for (ii = 0; ii < nn; ii++) {
748
0
    struct sc_pkcs15_auth_info *ainfo =
749
0
        (struct sc_pkcs15_auth_info *)objs[ii]->data;
750
0
    struct sc_pkcs15_pin_attributes *pin_attrs = &ainfo->attrs.pin;
751
752
0
    if (ainfo->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
753
0
      continue;
754
755
0
    if (pin_attrs->reference == profile_auth.attrs.pin.reference
756
0
        && pin_attrs->flags != profile_auth.attrs.pin.flags) {
757
0
      sc_log(ctx,
758
0
         "Set flags of '%s'(flags:%X,ref:%i,id:%s) to %X",
759
0
         objs[ii]->label, pin_attrs->flags,
760
0
         pin_attrs->reference,
761
0
         sc_pkcs15_print_id(&ainfo->auth_id),
762
0
         profile_auth.attrs.pin.flags);
763
0
      pin_attrs->flags = profile_auth.attrs.pin.flags;
764
0
      update_df = 1;
765
0
    }
766
0
  }
767
284
  if (update_df) {
768
0
    struct sc_pkcs15_df *df = p15card->df_list;
769
770
0
    while (df != NULL && df->type != SC_PKCS15_AODF)
771
0
      df = df->next;
772
0
    if (!df)
773
0
      LOG_TEST_RET(ctx,
774
0
            SC_ERROR_OBJECT_NOT_FOUND,
775
0
            "Cannot find AODF");
776
0
    rv = sc_pkcs15init_update_any_df(p15card, profile, df, 0);
777
0
    LOG_TEST_RET(ctx, rv, "Update AODF error");
778
0
  }
779
780
284
  SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, rv);
781
284
}
782
783
static struct sc_pkcs15init_operations sc_pkcs15init_epass2003_operations = {
784
  epass2003_pkcs15_erase_card,
785
  epass2003_pkcs15_init_card,
786
  epass2003_pkcs15_create_dir,
787
  NULL,     /* create_domain */
788
  epass2003_pkcs15_pin_reference,
789
  epass2003_pkcs15_create_pin,
790
  epass2003_pkcs15_key_reference,
791
  epass2003_pkcs15_create_key,
792
  epass2003_pkcs15_store_key,
793
  epass2003_pkcs15_generate_key,
794
  NULL, NULL,   /* encode private/public key */
795
  NULL,     /* finalize */
796
  epass2003_pkcs15_delete_object,
797
  NULL, NULL, NULL, NULL, NULL, /* pkcs15init emulation */
798
  epass2003_pkcs15_sanity_check,
799
};
800
801
struct sc_pkcs15init_operations *sc_pkcs15init_get_epass2003_ops(void)
802
819
{
803
819
  return &sc_pkcs15init_epass2003_operations;
804
819
}