Coverage Report

Created: 2026-02-26 06:59

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
0
{
38
0
  SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
39
40
0
  if (sc_select_file(p15card->card, sc_get_mf_path(), NULL) < 0)
41
0
    return SC_SUCCESS;
42
43
0
  return sc_card_ctl(p15card->card, SC_CARDCTL_ERASE_CARD, 0);
44
0
}
45
46
static int epass2003_pkcs15_init_card(struct sc_profile *profile,
47
              struct sc_pkcs15_card *p15card)
48
0
{
49
0
  struct sc_card *card = p15card->card;
50
0
  int ret;
51
52
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
53
0
  sc_do_log(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,NULL,0,NULL,
54
0
      "ePass2003 doesn't support SO-PIN and SO-PUK. You can unblock key with PUK. \n");
55
0
  {     /* MF */
56
0
    struct sc_file *mf_file;
57
0
    struct sc_file *skey_file;
58
59
0
    ret = sc_profile_get_file(profile, "MF", &mf_file);
60
0
    LOG_TEST_RET(card->ctx, ret,
61
0
          "Get MF info failed");
62
0
    ret = sc_create_file(card, mf_file);
63
0
    sc_file_free(mf_file);
64
0
    LOG_TEST_RET(card->ctx, ret,
65
0
          "Create MF failed");
66
67
0
    ret = sc_profile_get_file(profile, "SKey-MF", &skey_file);
68
0
    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
0
{
195
0
  SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
196
197
0
  if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
198
0
    return SC_ERROR_OBJECT_NOT_VALID;
199
200
0
  if (auth_info->attrs.pin.reference < ENTERSAFE_USER_PIN_ID
201
0
      || auth_info->attrs.pin.reference > ENTERSAFE_SO_PIN_ID)
202
0
    return SC_ERROR_INVALID_PIN_REFERENCE;
203
204
0
  SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
205
0
}
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
0
{
214
0
  struct sc_card *card = p15card->card;
215
0
  int r;
216
0
  struct sc_pkcs15_auth_info *auth_info;
217
218
0
  if (NULL == pin_obj)
219
0
    return SC_ERROR_INVALID_ARGUMENTS;
220
221
0
  auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data;
222
223
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
224
225
0
  if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
226
0
    return SC_ERROR_OBJECT_NOT_VALID;
227
228
0
  {     /*pin */
229
0
    sc_epass2003_wkey_data data;
230
0
    int id;
231
232
0
    if (!pin || !pin_len || pin_len > 16)
233
0
      return SC_ERROR_INVALID_ARGUMENTS;
234
235
0
    data.type = SC_EPASS2003_SECRET_PIN;
236
0
    data.key_data.es_secret.kid = auth_info->attrs.pin.reference;
237
0
    data.key_data.es_secret.ac[0] =
238
0
        EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE;
239
0
    data.key_data.es_secret.ac[1] =
240
0
        EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_USER;
241
242
0
    r = sc_profile_get_pin_id(profile, 2, &id);
243
0
    LOG_TEST_RET(card->ctx, r,
244
0
          "Get User PIN id error!");
245
0
    data.key_data.es_secret.EC =
246
0
        sc_profile_get_pin_retries(profile, id);
247
248
    /* pad pin with 0 */
249
0
    memset(data.key_data.es_secret.key_val, 0,
250
0
           sizeof(data.key_data.es_secret.key_val));
251
0
    memcpy(data.key_data.es_secret.key_val, pin, pin_len);
252
0
    data.key_data.es_secret.key_len = pin_len;
253
254
0
    r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
255
0
    if (r < 0)
256
0
      SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
257
0
    if (pin_obj) {
258
      /* Cache new PIN value. */
259
0
      sc_pkcs15_pincache_add(p15card, pin_obj, pin, pin_len);
260
0
    }
261
0
  }
262
263
0
  {     /*puk */
264
0
    sc_epass2003_wkey_data data;
265
0
    int id;
266
267
0
    if (!puk || !puk_len || puk_len > 16)
268
0
      return SC_ERROR_INVALID_ARGUMENTS;
269
270
0
    data.type = SC_EPASS2003_SECRET_PIN;
271
0
    data.key_data.es_secret.kid =
272
0
        auth_info->attrs.pin.reference + 1;
273
0
    data.key_data.es_secret.ac[0] =
274
0
        EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE;
275
0
    data.key_data.es_secret.ac[1] =
276
0
        EPASS2003_AC_MAC_EQUAL | EPASS2003_AC_SO;
277
278
0
    r = sc_profile_get_pin_id(profile, 1, &id);
279
0
    LOG_TEST_RET(card->ctx, r,
280
0
          "Get User PIN id error!");
281
0
    data.key_data.es_secret.EC =
282
0
        sc_profile_get_pin_retries(profile, id);
283
284
    /* pad pin with 0 */
285
0
    memset(data.key_data.es_secret.key_val, 0,
286
0
           sizeof(data.key_data.es_secret.key_val));
287
0
    memcpy(data.key_data.es_secret.key_val, puk, puk_len);
288
0
    data.key_data.es_secret.key_len = puk_len;
289
290
0
    r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
291
0
  }
292
293
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
294
0
}
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
0
{
300
0
  SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
301
0
  if (prkey->path.len == 0)
302
0
    SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
303
0
  prkey->key_reference = prkey->path.value[prkey->path.len - 1];
304
0
  SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
305
0
}
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
0
{
312
0
  struct sc_file *file = NULL;
313
0
  const char *_template = NULL, *desc = NULL;
314
0
  unsigned int structure = 0xFFFFFFFF;
315
316
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
317
0
  sc_log(card->ctx,  "type %X; num %i\n", type,
318
0
     num);
319
0
  while (1) {
320
0
    switch (type) {
321
0
    case SC_PKCS15_TYPE_PRKEY_EC:
322
0
      desc = "EC private key";
323
0
      _template = "private-key";
324
0
      structure = SC_CARDCTL_OBERTHUR_KEY_EC_CRT;
325
0
      break;
326
0
    case SC_PKCS15_TYPE_PUBKEY_EC:
327
0
      desc = "EC public key";
328
0
      _template = "public-key";
329
0
      structure = SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC;
330
0
      break;
331
0
    case SC_PKCS15_TYPE_PRKEY_RSA:
332
0
      desc = "RSA private key";
333
0
      _template = "private-key";
334
0
      structure = SC_CARDCTL_OBERTHUR_KEY_RSA_CRT;
335
0
      break;
336
0
    case SC_PKCS15_TYPE_PUBKEY_RSA:
337
0
      desc = "RSA public key";
338
0
      _template = "public-key";
339
0
      structure = SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC;
340
0
      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
0
    }
354
0
    if (_template)
355
0
      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
0
  sc_log(card->ctx,  "template %s; num %i\n",
370
0
     _template, num);
371
0
  if (sc_profile_get_file(profile, _template, &file) < 0) {
372
0
    sc_log(card->ctx,
373
0
       "Profile doesn't define %s template '%s'\n", desc,
374
0
       _template);
375
0
    return SC_ERROR_NOT_SUPPORTED;
376
0
  }
377
378
0
  if (file->path.len < 1) {
379
0
    sc_file_free(file);
380
0
    return SC_ERROR_INTERNAL;
381
0
  }
382
383
0
  file->id &= 0xFF00;
384
0
  file->id |= (num & 0x00FF);
385
386
0
  file->path.value[file->path.len - 1] = (num & 0xFF);
387
0
  file->type = SC_FILE_TYPE_INTERNAL_EF;
388
0
  file->ef_structure = structure;
389
390
0
  sc_log(card->ctx,
391
0
     "file size %"SC_FORMAT_LEN_SIZE_T"u; ef type %i/%i; id %04X, path_len %"SC_FORMAT_LEN_SIZE_T"u\n",
392
0
     file->size, file->type, file->ef_structure, file->id,
393
0
     file->path.len);
394
0
  sc_log(card->ctx,  "file path: %s",
395
0
     sc_print_path(&(file->path)));
396
0
  *out = file;
397
398
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
399
0
}
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
0
{
405
0
  struct sc_card *card = p15card->card;
406
407
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
408
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
409
0
}
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
0
{
503
0
  struct sc_card *card = p15card->card;
504
0
  int r;
505
0
  sc_epass2003_gen_key_data gendat;
506
0
  struct sc_pkcs15_prkey_info *key_info =
507
0
      (struct sc_pkcs15_prkey_info *)obj->data;
508
0
  int idx = key_info->key_reference;
509
0
  size_t keybits = key_info->modulus_length;
510
0
  struct sc_file *tfile = NULL, *pukf = NULL;
511
0
  struct sc_path path;
512
0
  struct sc_file *file = NULL;
513
0
  int fidl = 0;
514
515
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
516
517
0
  if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA && obj->type != SC_PKCS15_TYPE_PRKEY_EC)
518
0
    return SC_ERROR_NOT_SUPPORTED;
519
520
0
  if(obj->type == SC_PKCS15_TYPE_PRKEY_EC && keybits == 0)
521
0
    keybits = 256;   //EC key length is 256 ...
522
523
  /* allocate key object */
524
0
  r = cosm_new_file(profile, card, obj->type, idx, &file); //replace SC_PKCS15_TYPE_PRKEY_RSA with obj->type
525
0
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
526
0
        "create key: failed to allocate new key object");
527
0
  file->size = keybits;
528
0
  sc_log(card->ctx,  "private key path: %s",
529
0
     sc_print_path(&file->path));
530
0
  sc_log(card->ctx,  "private key_info path: %s",
531
0
     sc_print_path(&(key_info->path)));
532
533
0
  r = sc_pkcs15init_authenticate(profile, p15card, file,
534
0
               SC_AC_OP_DELETE);
535
0
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
536
0
        "generate key: pkcs15init_authenticate(SC_AC_OP_DELETE) failed");
537
538
0
  sc_delete_file(p15card->card, &file->path);
539
  /* create */
540
0
  r = sc_pkcs15init_create_file(profile, p15card, file);
541
0
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
542
0
        "create key: failed to create key file");
543
544
0
  sc_log(card->ctx,
545
0
     "index %u; keybits %"SC_FORMAT_LEN_SIZE_T"u\n",
546
0
     idx, keybits);
547
0
  if (keybits < 1024 || keybits > 2048 || (keybits % 0x20)) {
548
0
    if(obj->type == SC_PKCS15_TYPE_PRKEY_EC && keybits == 256)
549
0
    {
550
0
      sc_log(card->ctx, "current Alg is EC,Only support 256 ..\n");
551
0
    }
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
0
  }
561
562
0
  path = key_info->path;
563
0
  path.len -= 2;
564
565
0
  r = sc_select_file(card, &path, &tfile);
566
0
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
567
0
        "generate key: no private object DF");
568
569
0
  r = sc_pkcs15init_authenticate(profile, p15card, tfile,
570
0
               SC_AC_OP_CRYPTO);
571
0
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
572
0
        "generate key: pkcs15init_authenticate(SC_AC_OP_CRYPTO) failed");
573
574
0
  r = sc_pkcs15init_authenticate(profile, p15card, tfile,
575
0
               SC_AC_OP_CREATE);
576
0
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
577
0
        "generate key: pkcs15init_authenticate(SC_AC_OP_CREATE) failed");
578
579
0
  if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA )
580
0
  {
581
0
    r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PUBKEY_EC, idx, &pukf);
582
0
  }
583
0
  else
584
0
  {
585
0
    r = cosm_new_file(profile, card, SC_PKCS15_TYPE_PUBKEY_RSA, idx, &pukf);
586
0
  }
587
588
0
  if (r < 0) {
589
0
    sc_log(card->ctx,
590
0
       "generate key: create temporary pukf failed\n");
591
0
    goto err;
592
0
  }
593
594
0
  pukf->size = keybits;
595
0
  pukf->id = pukf->path.value[pukf->path.len - 2] * 0x100
596
0
      + pukf->path.value[pukf->path.len - 1];
597
598
0
  sc_log(card->ctx,
599
0
     "public key size %"SC_FORMAT_LEN_SIZE_T"u; ef type %i/%i; id %04X; path: %s",
600
0
     pukf->size, pukf->type, pukf->ef_structure, pukf->id,
601
0
     sc_print_path(&pukf->path));
602
603
0
  r = sc_select_file(p15card->card, &pukf->path, NULL);
604
  /* if exist, delete */
605
0
  if (r == SC_SUCCESS) {
606
0
    r = sc_pkcs15init_authenticate(profile, p15card, pukf,
607
0
           SC_AC_OP_DELETE);
608
0
    SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
609
0
        "generate key - pubkey: pkcs15init_authenticate(SC_AC_OP_DELETE) failed");
610
611
0
    r = sc_pkcs15init_delete_by_path(profile, p15card, &pukf->path);
612
0
    if (r != SC_SUCCESS) {
613
0
      sc_log(card->ctx,
614
0
         "generate key: failed to delete existing key file\n");
615
0
      goto err;
616
0
    }
617
0
  }
618
  /* create */
619
0
  r = sc_pkcs15init_create_file(profile, p15card, pukf);
620
0
  if (r != SC_SUCCESS) {
621
0
    sc_log(card->ctx,
622
0
       "generate key: pukf create file failed\n");
623
0
    goto err;
624
0
  }
625
626
0
  r = sc_pkcs15init_authenticate(profile, p15card, pukf,
627
0
               SC_AC_OP_UPDATE);
628
0
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
629
0
        "generate key - pubkey: pkcs15init_authenticate(SC_AC_OP_UPDATE) failed");
630
631
  /* generate key pair */
632
0
  fidl = (file->id & 0xff) * FID_STEP;
633
0
  file->id = (file->id & 0xff00) + fidl;
634
0
  pukf->id = (pukf->id & 0xff00) + fidl;
635
0
  gendat.prkey_id = file->id;
636
0
  gendat.pukey_id = pukf->id;
637
0
  gendat.key_length = keybits;
638
0
  gendat.modulus = NULL;
639
0
  gendat.modulus_len = 0;
640
0
  r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_GENERATE_KEY, &gendat);
641
0
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r,
642
0
        "generate RSA key pair failed");
643
644
0
  if (!gendat.modulus) {
645
0
    r = SC_ERROR_OUT_OF_MEMORY;
646
0
    goto err;
647
0
  }
648
649
  /* get the modulus */
650
0
  if (pubkey && (obj->type == SC_PKCS15_TYPE_PRKEY_RSA)) {
651
0
    u8 *buf;
652
0
    struct sc_pkcs15_pubkey_rsa *rsa = &pubkey->u.rsa;
653
    /* set the modulus */
654
0
    rsa->modulus.data = gendat.modulus;
655
0
    rsa->modulus.len = keybits >> 3;
656
    /* set the exponent (always 0x10001) */
657
0
    buf = (u8 *) malloc(3);
658
0
    if (!buf) {
659
0
      r = SC_ERROR_OUT_OF_MEMORY;
660
0
      goto err;
661
0
    }
662
0
    buf[0] = 0x01;
663
0
    buf[1] = 0x00;
664
0
    buf[2] = 0x01;
665
0
    rsa->exponent.data = buf;
666
0
    rsa->exponent.len = 3;
667
668
0
    pubkey->algorithm = SC_ALGORITHM_RSA;
669
0
  }
670
0
  else if(pubkey && (obj->type == SC_PKCS15_TYPE_PRKEY_EC)){
671
0
    struct sc_ec_parameters *ecparams = (struct
672
0
        sc_ec_parameters *)key_info->params.data;
673
0
    pubkey->algorithm = SC_ALGORITHM_EC;
674
0
    pubkey->u.ec.ecpointQ.value = (u8 *)malloc(gendat.modulus_len + 1);
675
0
    if (!pubkey->u.ec.ecpointQ.value) {
676
0
      r = SC_ERROR_OUT_OF_MEMORY;
677
0
      goto err;
678
0
    }
679
680
0
    pubkey->u.ec.ecpointQ.value[0] = 0x04;
681
0
    memcpy(&pubkey->u.ec.ecpointQ.value[1], gendat.modulus, gendat.modulus_len);
682
0
    pubkey->u.ec.ecpointQ.len = gendat.modulus_len + 1;
683
0
    free(gendat.modulus);
684
685
0
    free(pubkey->u.ec.params.named_curve);
686
0
    pubkey->u.ec.params.named_curve = NULL;
687
688
0
    free(pubkey->u.ec.params.der.value);
689
0
    pubkey->u.ec.params.der.value = NULL;
690
0
    pubkey->u.ec.params.der.len = 0;
691
0
    pubkey->u.ec.params.named_curve = strdup(ecparams->named_curve);
692
693
0
    if (!pubkey->u.ec.params.named_curve){
694
0
      r = SC_ERROR_OUT_OF_MEMORY;
695
0
      goto err;
696
0
    }
697
698
0
    r = sc_pkcs15_fix_ec_parameters(card->ctx, &pubkey->u.ec.params);
699
0
  }
700
0
  else
701
    /* free public key */
702
0
    free(gendat.modulus);
703
704
0
err:
705
0
  sc_file_free(pukf);
706
0
  sc_file_free(file);
707
0
  sc_file_free(tfile);
708
709
0
  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
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
717
0
}
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
0
{
731
0
  struct sc_context *ctx = p15card->card->ctx;
732
0
  struct sc_pkcs15_auth_info profile_auth = {0};
733
0
  struct sc_pkcs15_object *objs[32];
734
0
  int rv, nn, ii, update_df = 0;
735
736
0
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
737
738
0
  sc_log(ctx,
739
0
     "Check and if needed update PinFlags");
740
0
  rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32);
741
0
  LOG_TEST_RET(ctx, rv, "Failed to get PINs");
742
0
  nn = rv;
743
744
0
  sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &profile_auth);
745
0
  LOG_TEST_RET(ctx, rv, "Failed to get PIN info");
746
747
0
  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
0
  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
0
  SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, rv);
781
0
}
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
5
{
803
5
  return &sc_pkcs15init_epass2003_operations;
804
5
}