Coverage Report

Created: 2026-08-31 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/pkcs15init/pkcs15-iasecc.c
Line
Count
Source
1
/*
2
 * IAS/ECC specific operations for PKCS #15 initialization
3
 *
4
 * Copyright (C) 2002  Juha Yrjölä <juha.yrjola@iki.fi>
5
 * Copyright (C) 2010  Viktor Tarasov <vtarasov@opentrust.com>
6
 *          OpenTrust <www.opentrust.com>
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
23
#ifdef HAVE_CONFIG_H
24
#include <config.h>
25
#endif
26
27
#ifndef FIX_UNUSED
28
#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */
29
#endif
30
31
#ifdef ENABLE_OPENSSL   /* empty file without openssl */
32
33
#include <stdlib.h>
34
#include <string.h>
35
#include <sys/types.h>
36
#include <ctype.h>
37
#include <errno.h>
38
#include <stdio.h>
39
40
#include "../libopensc/opensc.h"
41
#include "../libopensc/cardctl.h"
42
#include "../libopensc/log.h"
43
#include "../libopensc/pkcs15.h"
44
#include "../libopensc/cards.h"
45
#include "../libopensc/iasecc.h"
46
#include "../libopensc/iasecc-sdo.h"
47
48
#include "pkcs15-init.h"
49
#include "profile.h"
50
51
#define IASECC_TITLE "IASECC"
52
53
int iasecc_pkcs15_delete_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_file *df);
54
static int iasecc_md_gemalto_delete_prvkey(struct sc_pkcs15_card *, struct sc_profile *, struct sc_pkcs15_object *);
55
56
static void
57
iasecc_reference_to_pkcs15_id (unsigned int ref, struct sc_pkcs15_id *id)
58
0
{
59
0
  int ii, sz;
60
61
0
  for (ii=0, sz = 0; (unsigned)ii < sizeof(unsigned int); ii++)
62
0
    if (ref >> 8*ii)
63
0
      sz++;
64
65
0
  for (ii=0; ii < sz; ii++)
66
0
    id->value[sz - ii - 1] = (ref >> 8*ii) & 0xFF;
67
68
0
  id->len = sz;
69
0
}
70
71
72
int
73
iasecc_pkcs15_delete_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
74
    struct sc_file *df)
75
0
{
76
0
  struct sc_context *ctx = p15card->card->ctx;
77
0
  struct sc_card *card = p15card->card;
78
0
  struct sc_path  path;
79
0
  unsigned long caps = card->caps;
80
0
  int rv = 0;
81
82
0
  LOG_FUNC_CALLED(ctx);
83
84
0
  sc_log(ctx, "iasecc_pkcs15_delete_file() id %04X\n", df->id);
85
86
0
  card->caps |= SC_CARD_CAP_USE_FCI_AC;
87
0
  rv = sc_pkcs15init_authenticate(profile, p15card, df, SC_AC_OP_DELETE);
88
0
  card->caps = caps;
89
90
0
  LOG_TEST_RET(ctx, rv, "Cannot authenticate SC_AC_OP_DELETE");
91
92
0
  memset(&path, 0, sizeof(path));
93
0
  path.type = SC_PATH_TYPE_FILE_ID;
94
0
  path.value[0] = df->id >> 8;
95
0
  path.value[1] = df->id & 0xFF;
96
0
  path.len = 2;
97
98
0
  rv = sc_delete_file(card, &path);
99
0
  LOG_FUNC_RETURN(ctx, rv);
100
0
}
101
102
103
/*
104
 * Erase the card
105
 *
106
 */
107
static int
108
iasecc_pkcs15_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card)
109
0
{
110
0
  struct sc_context *ctx = p15card->card->ctx;
111
0
  struct sc_file  *file = NULL;
112
0
  struct sc_path  path;
113
0
  struct sc_pkcs15_df *df;
114
0
  int rv;
115
116
0
  LOG_FUNC_CALLED(ctx);
117
118
0
  if (p15card->app && p15card->app->ddo.aid.len)   {
119
0
    memset(&path, 0, sizeof(struct sc_path));
120
0
    path.type = SC_PATH_TYPE_DF_NAME;
121
0
    memcpy(path.value, p15card->app->ddo.aid.value, p15card->app->ddo.aid.len);
122
0
    path.len = p15card->app->ddo.aid.len;
123
124
0
    sc_log(ctx, "Select DDO AID: %s", sc_print_path(&path));
125
0
    rv = sc_select_file(p15card->card, &path, NULL);
126
0
    LOG_TEST_RET(ctx, rv, "Erase application error: cannot select DDO AID");
127
0
  }
128
129
0
  for (df = p15card->df_list; df; df = df->next)   {
130
0
    struct sc_pkcs15_object *objs[32];
131
0
    unsigned obj_type = 0;
132
0
    int ii;
133
134
0
    if (df->type == SC_PKCS15_PRKDF)
135
0
      obj_type = SC_PKCS15_TYPE_PRKEY;
136
0
    else if (df->type == SC_PKCS15_PUKDF)
137
0
      obj_type = SC_PKCS15_TYPE_PUBKEY;
138
0
    else if (df->type == SC_PKCS15_CDF)
139
0
      obj_type = SC_PKCS15_TYPE_CERT;
140
0
    else if (df->type == SC_PKCS15_DODF)
141
0
      obj_type = SC_PKCS15_TYPE_DATA_OBJECT;
142
0
    else
143
0
      continue;
144
145
0
    rv = sc_pkcs15_get_objects(p15card, obj_type, objs, 32);
146
0
    LOG_TEST_RET(ctx, rv, "Failed to get PKCS#15 objects to remove");
147
148
0
    for (ii=0; ii<rv; ii++)   {
149
0
      if (obj_type == SC_PKCS15_TYPE_CERT)   {
150
0
        struct sc_path path = ((struct sc_pkcs15_cert_info *)(objs[ii]->data))->path;
151
0
        rv = sc_delete_file(p15card->card, &path);
152
0
      }
153
0
      else if (obj_type == SC_PKCS15_TYPE_DATA_OBJECT)   {
154
0
        struct sc_path path = ((struct sc_pkcs15_data_info *)(objs[ii]->data))->path;
155
0
        rv = sc_delete_file(p15card->card, &path);
156
0
      }
157
158
0
      sc_pkcs15_remove_object(p15card, objs[ii]);
159
0
      sc_pkcs15_free_object(objs[ii]);
160
0
    }
161
162
0
    rv = sc_select_file(p15card->card, &df->path, &file);
163
0
    if (rv == SC_ERROR_FILE_NOT_FOUND)
164
0
      continue;
165
0
    LOG_TEST_RET(ctx, rv, "Cannot select object file");
166
167
0
    profile->dirty = 1;
168
169
0
    rv = sc_erase_binary(p15card->card, 0, file->size, 0);
170
0
    if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED)   {
171
0
      rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
172
0
      LOG_TEST_RET(ctx, rv, "SC_AC_OP_UPDATE authentication failed");
173
174
0
      rv = sc_erase_binary(p15card->card, 0, file->size, 0);
175
0
    }
176
0
    LOG_TEST_RET(ctx, rv, "Binary erase error");
177
178
0
    sc_file_free(file);
179
0
  }
180
181
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
182
0
}
183
184
185
/*
186
 * Allocate a file
187
 */
188
static int
189
iasecc_pkcs15_new_file(struct sc_profile *profile, struct sc_card *card,
190
    unsigned int type, unsigned int num, struct sc_file **out)
191
0
{
192
0
  struct sc_context *ctx = card->ctx;
193
0
  struct sc_file  *file = NULL;
194
0
  const char *_template = NULL;
195
0
  int rv;
196
197
0
  LOG_FUNC_CALLED(ctx);
198
0
  sc_log(ctx, "type %X; num %i\n", type, num);
199
0
  switch (type) {
200
0
    case SC_PKCS15_TYPE_PRKEY_RSA:
201
0
      _template = "private-key";
202
0
      break;
203
0
    case SC_PKCS15_TYPE_PUBKEY_RSA:
204
0
      _template = "public-key";
205
0
      break;
206
0
    case SC_PKCS15_TYPE_CERT:
207
0
      _template = "certificate";
208
0
      break;
209
0
    case SC_PKCS15_TYPE_DATA_OBJECT:
210
0
      _template = "public-data";
211
0
      break;
212
0
    default:
213
0
      LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Profile template not supported");
214
0
  }
215
216
0
  sc_log(ctx, "df_info path '%s'\n", sc_print_path(&profile->df_info->file->path));
217
0
  rv = sc_profile_get_file(profile, _template, &file);
218
0
  if (rv == SC_ERROR_FILE_NOT_FOUND)   {
219
0
    struct sc_pkcs15_id     id;
220
221
0
    id.len = 1;
222
0
    id.value[0] = num & 0xFF;
223
0
    rv = sc_profile_instantiate_template(profile, "key-domain", &profile->df_info->file->path,
224
0
        _template, &id, &file);
225
0
  }
226
0
  LOG_TEST_RET(ctx, rv, "Error when getting file from template");
227
228
0
  sc_log(ctx, "path(type:%X;path:%s)\n", file->path.type, sc_print_path(&file->path));
229
230
0
  file->id = (file->id & 0xFF00) | (num & 0xFF);
231
0
  if (file->path.len == 0)   {
232
0
    file->path.type = SC_PATH_TYPE_FILE_ID;
233
0
    file->path.len = 2;
234
0
  }
235
0
  file->path.value[file->path.len - 2] = (file->id >> 8) & 0xFF;
236
0
  file->path.value[file->path.len - 1] = file->id & 0xFF;
237
0
  file->path.count = -1;
238
239
0
  sc_log(ctx, "file size %zu; ef type %i/%i; id %04X",
240
0
      file->size, file->type, file->ef_structure, file->id);
241
0
  sc_log(ctx, "path type %X; path '%s'", file->path.type, sc_print_path(&file->path));
242
243
0
  if (out)
244
0
    *out = file;
245
0
  else
246
0
    sc_file_free(file);
247
248
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
249
0
}
250
251
252
/*
253
 * Select a key reference
254
 */
255
static int
256
iasecc_pkcs15_select_key_reference(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
257
    struct sc_pkcs15_prkey_info *key_info)
258
0
{
259
0
  struct sc_context *ctx = p15card->card->ctx;
260
0
  struct sc_card *card = p15card->card;
261
0
  struct sc_file  *file = NULL;
262
0
  int rv = 0, idx = key_info->key_reference & ~IASECC_OBJECT_REF_LOCAL;
263
264
0
  LOG_FUNC_CALLED(ctx);
265
0
  sc_log(ctx, "'seed' key reference %i; path %s", key_info->key_reference & ~IASECC_OBJECT_REF_LOCAL,
266
0
      sc_print_path(&key_info->path));
267
268
0
  rv = sc_select_file(card, &key_info->path, &file);
269
0
  sc_file_free(file);
270
0
  LOG_TEST_RET(ctx, rv, "Cannot select DF to select key reference in");
271
272
  /* 1 <= ObjReference <= 31 */
273
0
  if (idx < IASECC_OBJECT_REF_MIN)
274
0
    idx = IASECC_OBJECT_REF_MIN;
275
276
  /* Look for the suitable slot */
277
0
  if (idx <= IASECC_OBJECT_REF_MAX)   {
278
0
    struct iasecc_ctl_get_free_reference ctl_data;
279
280
0
    ctl_data.key_size = key_info->modulus_length;
281
0
    ctl_data.usage = key_info->usage;
282
0
    ctl_data.access = key_info->access_flags;
283
0
    ctl_data.index = idx;
284
285
0
    rv = sc_card_ctl(card, SC_CARDCTL_IASECC_GET_FREE_KEY_REFERENCE, &ctl_data);
286
0
    if (!rv)
287
0
      sc_log(ctx, "found allocated slot %i", idx);
288
0
    else if (rv == SC_ERROR_DATA_OBJECT_NOT_FOUND && idx <= IASECC_OBJECT_REF_MAX)
289
0
      sc_log(ctx, "found empty slot %i", idx);
290
0
    else
291
0
      LOG_TEST_RET(ctx, rv, "Cannot select key reference");
292
293
0
    idx = ctl_data.index;
294
0
  }
295
296
  /* All card objects but PINs are locals */
297
0
  key_info->key_reference = idx | IASECC_OBJECT_REF_LOCAL;
298
0
  sc_log(ctx, "selected key reference %i", key_info->key_reference);
299
300
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
301
0
}
302
303
304
static int
305
iasecc_sdo_get_data(struct sc_card *card, struct iasecc_sdo *sdo)
306
0
{
307
0
  struct sc_context *ctx = card->ctx;
308
0
  int rv;
309
310
0
  LOG_FUNC_CALLED(ctx);
311
0
  rv = sc_card_ctl(card, SC_CARDCTL_IASECC_SDO_GET_DATA, sdo);
312
0
  LOG_TEST_RET(ctx, rv, "IasEcc: GET DATA error");
313
314
0
  LOG_FUNC_RETURN(ctx, rv);
315
0
}
316
317
318
static int
319
iasecc_file_convert_acls(struct sc_context *ctx, struct sc_profile *profile, struct sc_file *file)
320
0
{
321
0
  int ii;
322
323
0
  for (ii=0; ii<SC_MAX_AC_OPS;ii++)   {
324
    /* FIXME the acl object must not be modified, it is only defined in
325
     * sc_file_get_acl_entry. Accessing it here means we have a race
326
     * condition. */
327
0
    struct sc_acl_entry *acl = (struct sc_acl_entry *) sc_file_get_acl_entry(file, ii);
328
329
0
    if (acl)   {
330
0
      switch (acl->method)   {
331
0
      case SC_AC_IDA:
332
0
        sc_log(ctx, "'IDA' not actually supported");
333
0
        return SC_ERROR_NOT_SUPPORTED;
334
0
      case SC_AC_SCB:
335
0
        if ((acl->key_ref & IASECC_SCB_METHOD_MASK) == IASECC_SCB_METHOD_USER_AUTH)   {
336
0
          acl->method = SC_AC_SEN;
337
0
          acl->key_ref &= IASECC_SCB_METHOD_MASK_REF;
338
0
        }
339
0
        else if ((acl->key_ref & IASECC_SCB_METHOD_MASK) == IASECC_SCB_METHOD_SM)   {
340
0
          acl->method = SC_AC_PRO;
341
0
          acl->key_ref &= IASECC_SCB_METHOD_MASK_REF;
342
0
        }
343
0
      }
344
0
    }
345
0
  }
346
347
0
  return 0;
348
0
}
349
350
static int
351
iasecc_sdo_set_key_acls_from_profile(struct sc_profile *profile, struct sc_card *card,
352
    const char *template, struct iasecc_sdo *sdo)
353
0
{
354
0
  struct sc_context *ctx = card->ctx;
355
0
  struct sc_file  *file = NULL;
356
0
  unsigned char ops_prvkey[7] = {
357
0
    SC_AC_OP_PSO_COMPUTE_SIGNATURE, SC_AC_OP_INTERNAL_AUTHENTICATE, SC_AC_OP_PSO_DECRYPT,
358
0
    SC_AC_OP_GENERATE, 0xFF, SC_AC_OP_UPDATE, SC_AC_OP_READ
359
0
  };
360
0
  unsigned char ops_pubkey[7] = {
361
0
    0xFF, SC_AC_OP_EXTERNAL_AUTHENTICATE, 0xFF,
362
0
    SC_AC_OP_GENERATE, 0xFF, SC_AC_OP_UPDATE, SC_AC_OP_READ
363
0
  };
364
0
  unsigned char amb, scb[16], mask;
365
0
  int rv, ii, cntr;
366
367
0
  LOG_FUNC_CALLED(ctx);
368
369
  /* Get ACLs from profile template */
370
0
  rv = sc_profile_get_file(profile, template, &file);
371
0
  LOG_TEST_RET(ctx, rv, "IasEcc: cannot instantiate private key file");
372
373
  /* Convert PKCS15 ACLs to SE ACLs */
374
0
  rv = iasecc_file_convert_acls(ctx, profile, file);
375
0
  if (rv < 0)
376
0
    sc_file_free(file);
377
0
  LOG_TEST_RET(ctx, rv, "Cannot convert profile ACLs");
378
379
0
  memset(scb, 0, sizeof(scb));
380
0
  for (ii = 0, mask = 0x80, amb = 0x80, cntr = 0; ii < 7; ii++) {
381
0
    const sc_acl_entry_t *acl;
382
0
    unsigned char op = sdo->sdo_class == IASECC_SDO_CLASS_RSA_PRIVATE ? ops_prvkey[ii] : ops_pubkey[ii];
383
384
0
    mask >>= 1;
385
386
0
    if (op == 0xFF)
387
0
      continue;
388
389
0
    acl = sc_file_get_acl_entry(file, op);
390
0
    sc_log(ctx, "ACL: 0x%X:0x%X", acl->method, acl->key_ref);
391
392
0
    if (acl->method == SC_AC_NEVER)   {
393
0
    }
394
0
    else if (acl->method == SC_AC_NONE)   {
395
0
      amb |= mask;
396
0
      scb[cntr++] = 0x00;
397
0
    }
398
0
    else if (acl->method == SC_AC_SEN || acl->method == SC_AC_PRO || acl->method == SC_AC_AUT)   {
399
0
      if ((acl->key_ref & 0xF) == 0 || (acl->key_ref & 0xF) == 0xF)   {
400
0
        sc_file_free(file);
401
0
        LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid SE reference");
402
0
      }
403
404
0
      amb |= mask;
405
406
0
      if (acl->method == SC_AC_SEN)
407
0
        scb[cntr++] = acl->key_ref | IASECC_SCB_METHOD_USER_AUTH;
408
0
      else if (acl->method == SC_AC_PRO)
409
0
        scb[cntr++] = acl->key_ref | IASECC_SCB_METHOD_SM;
410
0
      else
411
0
        scb[cntr++] = acl->key_ref | IASECC_SCB_METHOD_EXT_AUTH;
412
0
    }
413
0
    else   {
414
0
      sc_file_free(file);
415
0
      LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Unknown SCB method");
416
0
    }
417
0
  }
418
419
0
  sc_file_free(file);
420
421
  /* Copy ACLs into the DOCP*/
422
0
  sdo->docp.acls_contact.tag = IASECC_DOCP_TAG_ACLS_CONTACT;
423
0
  sdo->docp.acls_contact.size = cntr + 1;
424
0
  sdo->docp.acls_contact.value = calloc(1, sdo->docp.acls_contact.size);
425
0
  if (!sdo->docp.acls_contact.value)
426
0
    return SC_ERROR_OUT_OF_MEMORY;
427
0
  *(sdo->docp.acls_contact.value + 0) = amb;
428
0
  memcpy(sdo->docp.acls_contact.value + 1, scb, cntr);
429
430
0
  sc_log(ctx, "AMB: %X, CNTR %i, %x %x %x %x %x %x %x",
431
0
         amb, cntr, scb[0], scb[1], scb[2], scb[3], scb[4], scb[5], scb[6]);
432
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
433
0
}
434
435
436
static int
437
iasecc_sdo_allocate_prvkey(struct sc_profile *profile, struct sc_card *card,
438
    struct sc_pkcs15_prkey_info *key_info, struct iasecc_sdo **out)
439
0
{
440
0
  struct sc_context *ctx = card->ctx;
441
0
  struct iasecc_sdo *sdo = NULL;
442
0
  size_t sz = key_info->modulus_length / 8;
443
0
  int rv;
444
445
0
  LOG_FUNC_CALLED(ctx);
446
447
0
  sdo = calloc(1, sizeof(struct iasecc_sdo));
448
0
  if (!sdo)
449
0
    LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate 'iasecc_sdo'");
450
451
0
  sdo->magic = SC_CARDCTL_IASECC_SDO_MAGIC;
452
0
  sdo->sdo_ref = key_info->key_reference & 0x3F;
453
0
  sdo->sdo_class = IASECC_SDO_CLASS_RSA_PRIVATE;
454
0
  sdo->usage = key_info->usage;
455
456
0
  sc_log(ctx, "sdo->sdo_class 0x%X; sdo->usage 0x%X", sdo->sdo_class, sdo->usage);
457
458
0
  rv = iasecc_sdo_get_data(card, sdo);
459
0
  if (rv == SC_ERROR_DATA_OBJECT_NOT_FOUND)   {
460
0
    sdo->not_on_card = 1;
461
462
0
    rv = iasecc_sdo_set_key_acls_from_profile(profile, card, "private-key", sdo);
463
0
    if (rv != SC_SUCCESS)
464
0
      iasecc_sdo_free(card, sdo);
465
0
    LOG_TEST_RET(ctx, rv, "IasEcc: cannot set ACLs for SDO from the 'private-key'");
466
467
    /* FIXME: set here sdo->docp.name and sdo->docp.idata */
468
469
0
    sdo->docp.non_repudiation.value = calloc(1, 1);
470
0
    if (!sdo->docp.non_repudiation.value)   {
471
0
      iasecc_sdo_free(card, sdo);
472
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
473
0
    }
474
0
    sdo->docp.non_repudiation.tag = IASECC_DOCP_TAG_NON_REPUDIATION;
475
0
    sdo->docp.non_repudiation.size = 1;
476
477
0
    sdo->data.prv_key.compulsory.value = calloc(1, 1);
478
0
    if (!sdo->data.prv_key.compulsory.value)   {
479
0
      iasecc_sdo_free(card, sdo);
480
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
481
0
    }
482
0
    sdo->data.prv_key.compulsory.tag = IASECC_SDO_PRVKEY_TAG_COMPULSORY;
483
0
    sdo->data.prv_key.compulsory.size = 1;
484
485
0
    sdo->docp.size.value = calloc(1, 2);
486
0
    if (!sdo->docp.size.value)   {
487
0
      iasecc_sdo_free(card, sdo);
488
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
489
0
    }
490
0
    sdo->docp.size.tag = IASECC_DOCP_TAG_SIZE;
491
0
    sdo->docp.size.size = 2;
492
0
    *(sdo->docp.size.value + 0) = (sz >> 8) & 0xFF;
493
0
    *(sdo->docp.size.value + 1) = sz & 0xFF;
494
/*
495
      FIXME: Manage CRT key types: IASECC_GEN_KEY_TYPE_*: X509_usage
496
    Optional PRIVATE KEY SDO attribute 'Algorithm to compulsorily use' can have one of the three values:
497
    0(any usage), B6(Sign), A4(Authentication), B8(Confidentiality).
498
    If present, this attribute has to be the same in the 'GENERATE KEY' template data.
499
*/
500
0
    if (!(key_info->access_flags & SC_PKCS15_PRKEY_ACCESS_LOCAL) && (key_info->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION))
501
0
      sc_log(ctx, "Non fatal error: NON_REPUDIATION can be used only for the locally generated keys");
502
503
0
    if ((key_info->access_flags & SC_PKCS15_PRKEY_ACCESS_LOCAL)
504
0
        && (key_info->usage & SC_PKCS15_PRKEY_USAGE_SIGN)
505
0
        && (key_info->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION))   {
506
0
      *(sdo->docp.non_repudiation.value + 0) = 1;
507
0
      *(sdo->data.prv_key.compulsory.value + 0) = IASECC_CRT_TAG_DST;
508
0
    }
509
510
0
    sc_log(ctx, "non_repudiation %i", *(sdo->docp.non_repudiation.value + 0));
511
0
    sc_log(ctx, "compulsory 0x%X", *(sdo->data.prv_key.compulsory.value + 0));
512
0
  }
513
0
  else if (rv < 0) {
514
0
    iasecc_sdo_free(card, sdo);
515
0
    LOG_TEST_RET(ctx, rv, "IasEcc: error while getting private key SDO data");
516
0
  }
517
518
0
  if (out)
519
0
    *out = sdo;
520
0
  else
521
0
    iasecc_sdo_free(card, sdo);
522
523
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
524
0
}
525
526
527
static int
528
iasecc_sdo_allocate_pubkey(struct sc_profile *profile, struct sc_card *card, struct sc_pkcs15_pubkey_info *key_info,
529
    struct iasecc_sdo **out)
530
0
{
531
0
  struct sc_context *ctx = card->ctx;
532
0
  struct iasecc_sdo *sdo = NULL;
533
0
  size_t sz = key_info->modulus_length / 8;
534
0
  int rv;
535
536
0
  LOG_FUNC_CALLED(ctx);
537
0
  sdo = calloc(1, sizeof(struct iasecc_sdo));
538
0
  if (!sdo)
539
0
    return SC_ERROR_OUT_OF_MEMORY;
540
541
0
  sdo->magic = SC_CARDCTL_IASECC_SDO_MAGIC;
542
0
  sdo->sdo_ref = key_info->key_reference & 0x3F;
543
0
  sdo->sdo_class = IASECC_SDO_CLASS_RSA_PUBLIC;
544
545
0
  rv = iasecc_sdo_get_data(card, sdo);
546
0
  sc_log(ctx, "get Public Key SDO(class:%X) data returned %i", sdo->sdo_class, rv);
547
0
  if (rv == SC_ERROR_DATA_OBJECT_NOT_FOUND)   {
548
0
    sdo->not_on_card = 1;
549
550
0
    rv = iasecc_sdo_set_key_acls_from_profile(profile, card, "public-key", sdo);
551
0
    if (rv != SC_SUCCESS)
552
0
      iasecc_sdo_free(card, sdo);
553
0
    LOG_TEST_RET(ctx, rv, "iasecc_sdo_allocate_pubkey() cannot set ACLs for SDO from the 'public-key'");
554
555
0
    sdo->docp.size.value = calloc(1, 2);
556
0
    if (!sdo->docp.size.value)   {
557
0
      iasecc_sdo_free(card, sdo);
558
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
559
0
    }
560
0
    sdo->docp.size.size = 2;
561
0
    sdo->docp.size.tag = IASECC_DOCP_TAG_SIZE;
562
0
    *(sdo->docp.size.value + 0) = (sz >> 8) & 0xFF;
563
0
    *(sdo->docp.size.value + 1) = sz & 0xFF;
564
565
0
    if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR)   {
566
      /* TODO: Disabled for the tests of the Oberthur card */
567
0
    }
568
0
    else   {
569
0
      sdo->data.pub_key.cha.value = calloc(1, 2);
570
0
      if (!sdo->data.pub_key.cha.value)   {
571
0
        iasecc_sdo_free(card, sdo);
572
0
        LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
573
0
      }
574
0
      sdo->data.pub_key.cha.size = 2;
575
0
      sdo->data.pub_key.cha.tag = IASECC_SDO_PUBKEY_TAG_CHA;
576
0
    }
577
578
0
    sdo->data.pub_key.compulsory.value = calloc(1, 1);
579
0
    if (!sdo->data.pub_key.compulsory.value)   {
580
0
      iasecc_sdo_free(card, sdo);
581
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
582
0
    }
583
0
    sdo->data.pub_key.compulsory.tag = IASECC_SDO_PUBKEY_TAG_COMPULSORY;
584
0
    sdo->data.pub_key.compulsory.size = 1;
585
0
  }
586
0
  else if (rv < 0) {
587
0
    iasecc_sdo_free(card, sdo);
588
0
    LOG_TEST_RET(ctx, rv, "iasecc_sdo_allocate_pubkey() error while getting public key SDO data");
589
0
  }
590
591
0
  if (out)
592
0
    *out = sdo;
593
0
  else
594
0
    iasecc_sdo_free(card, sdo);
595
596
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
597
0
}
598
599
600
static int
601
iasecc_sdo_convert_to_file(struct sc_card *card, struct iasecc_sdo *sdo, struct sc_file **out)
602
0
{
603
0
  struct sc_context *ctx;
604
0
  struct sc_file *file;
605
0
  unsigned ii;
606
0
  int rv;
607
608
0
  if (!card || !sdo)
609
0
    return SC_ERROR_INVALID_ARGUMENTS;
610
611
0
  ctx = card->ctx;
612
0
  LOG_FUNC_CALLED(ctx);
613
614
0
  file = sc_file_new();
615
0
  if (!file)
616
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
617
618
0
  sc_log(ctx, "SDO class 0x%X", sdo->sdo_class);
619
620
0
  if (sdo->sdo_class == IASECC_SDO_CLASS_RSA_PRIVATE)   {
621
0
    unsigned char ops[] = {
622
0
      SC_AC_OP_PSO_COMPUTE_SIGNATURE, SC_AC_OP_INTERNAL_AUTHENTICATE, SC_AC_OP_PSO_DECRYPT,
623
0
      SC_AC_OP_GENERATE, SC_AC_OP_UPDATE, SC_AC_OP_READ
624
0
    };
625
626
0
    for (ii=0; ii<sizeof(ops)/sizeof(ops[0]);ii++)   {
627
0
      unsigned op_method, op_ref;
628
629
0
      rv = iasecc_sdo_convert_acl(card, sdo, ops[ii], &op_method, &op_ref);
630
0
      if (rv < 0)   {
631
0
        sc_file_free(file);
632
0
        LOG_TEST_RET(ctx, rv, "IasEcc: cannot convert ACL");
633
0
      }
634
635
0
      sc_log(ctx, "ii:%i, method:%X, ref:%X", ii, op_method, op_ref);
636
0
      sc_file_add_acl_entry(file, ops[ii], op_method, op_ref);
637
0
    }
638
0
  }
639
640
0
  if (out)
641
0
    *out = file;
642
0
  else
643
0
    sc_file_free(file);
644
645
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
646
0
}
647
648
649
static int
650
iasecc_pkcs15_add_access_rule(struct sc_pkcs15_object *object, unsigned access_mode, struct sc_pkcs15_id *auth_id)
651
0
{
652
0
  int ii;
653
654
0
  for (ii=0;ii<SC_PKCS15_MAX_ACCESS_RULES;ii++)   {
655
0
    if (!object->access_rules[ii].access_mode)   {
656
0
      object->access_rules[ii].access_mode = access_mode;
657
0
      if (auth_id)
658
0
        object->access_rules[ii].auth_id = *auth_id;
659
0
      else
660
0
        object->access_rules[ii].auth_id.len = 0;
661
0
      break;
662
0
    }
663
0
    else if (!auth_id && !object->access_rules[ii].auth_id.len)   {
664
0
      object->access_rules[ii].access_mode |= access_mode;
665
0
      break;
666
0
    }
667
0
    else if (auth_id && sc_pkcs15_compare_id(&object->access_rules[ii].auth_id, auth_id))   {
668
0
      object->access_rules[ii].access_mode |= access_mode;
669
0
      break;
670
0
    }
671
0
  }
672
673
0
  if (ii==SC_PKCS15_MAX_ACCESS_RULES)
674
0
    return SC_ERROR_TOO_MANY_OBJECTS;
675
676
0
  return SC_SUCCESS;
677
0
}
678
679
680
static int
681
iasecc_pkcs15_get_auth_id_from_se(struct sc_pkcs15_card *p15card, unsigned char scb,
682
    struct sc_pkcs15_id *auth_id)
683
0
{
684
0
  struct sc_context *ctx = p15card->card->ctx;
685
0
  struct sc_pkcs15_object *pin_objs[32];
686
0
  int rv, ii, nn_pins, se_ref, pin_ref;
687
688
0
  LOG_FUNC_CALLED(ctx);
689
0
  if (!auth_id)
690
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
691
692
0
  memset(auth_id, 0, sizeof(struct sc_pkcs15_id));
693
694
0
  if (!(scb & IASECC_SCB_METHOD_USER_AUTH))
695
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
696
697
0
  rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, pin_objs, 32);
698
0
  LOG_TEST_RET(ctx, rv, "Error while getting AUTH objects");
699
0
  nn_pins = rv;
700
701
0
  se_ref = scb & 0x0F;
702
0
  rv = sc_card_ctl(p15card->card, SC_CARDCTL_GET_CHV_REFERENCE_IN_SE, (void *)(&se_ref));
703
0
  LOG_TEST_RET(ctx, rv, "Card CTL error: cannot get CHV reference from SE");
704
0
  pin_ref = rv;
705
0
  for (ii=0; ii<nn_pins; ii++)   {
706
0
    const struct sc_pkcs15_auth_info *auth_info = (const struct sc_pkcs15_auth_info *) pin_objs[ii]->data;
707
708
0
    if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
709
0
      continue;
710
711
0
    sc_log(ctx, "PIN refs %i/%i", pin_ref, auth_info->attrs.pin.reference);
712
0
    if (pin_ref == ((auth_info->attrs.pin.reference + 0x100) % 0x100))   {
713
0
      *auth_id = auth_info->auth_id;
714
0
      break;
715
0
    }
716
0
  }
717
0
  if (ii == nn_pins)
718
0
    LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "No AUTH object found");
719
720
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
721
0
}
722
723
724
static int
725
iasecc_pkcs15_fix_file_access_rule(struct sc_pkcs15_card *p15card, struct sc_file *file,
726
    unsigned ac_op, unsigned rule_mode, struct sc_pkcs15_object *object)
727
0
{
728
0
  struct sc_context *ctx = p15card->card->ctx;
729
0
  const struct sc_acl_entry *acl = NULL;
730
0
  struct sc_pkcs15_id id;
731
0
  unsigned ref;
732
0
  int rv;
733
734
0
  LOG_FUNC_CALLED(ctx);
735
0
  acl = sc_file_get_acl_entry(file, ac_op);
736
0
  sc_log(ctx, "Fix file access rule: AC_OP:%i, ACL(method:0x%X,ref:0x%X)", ac_op, acl->method, acl->key_ref);
737
0
  if (acl->method == SC_AC_NONE)   {
738
0
    sc_log(ctx, "rule-mode:0x%X, auth-ID:NONE", rule_mode);
739
0
    rv = iasecc_pkcs15_add_access_rule(object, rule_mode, NULL);
740
0
    LOG_TEST_RET(ctx, rv, "Fix file access rule error");
741
0
  }
742
0
  else   {
743
0
    if (acl->method == SC_AC_IDA)   {
744
0
      ref = acl->key_ref;
745
0
      iasecc_reference_to_pkcs15_id (ref, &id);
746
0
    }
747
0
    else if (acl->method == SC_AC_SCB)   {
748
0
      rv = iasecc_pkcs15_get_auth_id_from_se(p15card, acl->key_ref, &id);
749
0
      LOG_TEST_RET(ctx, rv, "Cannot get AUTH.ID from SE");
750
0
    }
751
0
    else if (acl->method == SC_AC_PRO)   {
752
0
      ref = IASECC_SCB_METHOD_SM * 0x100 + acl->key_ref;
753
0
      iasecc_reference_to_pkcs15_id (ref, &id);
754
0
    }
755
0
    else   {
756
0
      LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Fix file access error");
757
0
    }
758
759
0
    sc_log(ctx, "rule-mode:0x%X, auth-ID:%s", rule_mode, sc_pkcs15_print_id(&id));
760
0
    rv = iasecc_pkcs15_add_access_rule(object, rule_mode, &id);
761
0
    LOG_TEST_RET(ctx, rv, "Fix file access rule error");
762
0
  }
763
764
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
765
0
}
766
767
768
static int
769
iasecc_pkcs15_fix_file_access(struct sc_pkcs15_card *p15card, struct sc_file *file,
770
    struct sc_pkcs15_object *object)
771
0
{
772
0
  struct sc_context *ctx = p15card->card->ctx;
773
0
  int rv;
774
775
0
  LOG_FUNC_CALLED(ctx);
776
0
  sc_log(ctx, "authID %s", sc_pkcs15_print_id(&object->auth_id));
777
778
0
  memset(object->access_rules, 0, sizeof(object->access_rules));
779
780
0
  rv = iasecc_pkcs15_fix_file_access_rule(p15card, file, SC_AC_OP_READ, SC_PKCS15_ACCESS_RULE_MODE_READ, object);
781
0
  LOG_TEST_RET(ctx, rv, "Fix file READ access error");
782
783
0
  rv = iasecc_pkcs15_fix_file_access_rule(p15card, file, SC_AC_OP_UPDATE, SC_PKCS15_ACCESS_RULE_MODE_UPDATE, object);
784
0
  LOG_TEST_RET(ctx, rv, "Fix file READ access error");
785
786
0
  rv = iasecc_pkcs15_fix_file_access_rule(p15card, file, SC_AC_OP_DELETE, SC_PKCS15_ACCESS_RULE_MODE_DELETE, object);
787
0
  LOG_TEST_RET(ctx, rv, "Fix file READ access error");
788
789
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
790
0
}
791
792
793
int
794
iasecc_pkcs15_encode_supported_algos(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object)
795
0
{
796
0
  struct sc_context *ctx = p15card->card->ctx;
797
0
  struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *) object->data;
798
0
  struct sc_supported_algo_info *algo;
799
0
  int rv = SC_SUCCESS, ii;
800
801
0
  LOG_FUNC_CALLED(ctx);
802
0
  sc_log(ctx, "encode supported algos for object(%s,type:%X)", object->label, object->type);
803
0
  switch (object->type)   {
804
0
  case SC_PKCS15_TYPE_PRKEY_RSA:
805
0
    sc_log(ctx, "PrKey Usage:%X,Access:%X", prkey_info->usage, prkey_info->access_flags);
806
0
    if (prkey_info->usage & (SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP))   {
807
0
      algo = sc_pkcs15_get_supported_algo(p15card, SC_PKCS15_ALGO_OP_DECIPHER, CKM_RSA_PKCS);
808
0
      rv = sc_pkcs15_add_supported_algo_ref(object, algo);
809
0
      LOG_TEST_RET(ctx, rv, "cannot add supported algorithm DECIPHER:CKM_RSA_PKCS");
810
0
    }
811
812
0
    if (prkey_info->usage & (SC_PKCS15_PRKEY_USAGE_SIGN |
813
0
                             SC_PKCS15_PRKEY_USAGE_NONREPUDIATION))   {
814
0
      if (prkey_info->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)   {
815
0
        algo = sc_pkcs15_get_supported_algo(p15card, SC_PKCS15_ALGO_OP_COMPUTE_SIGNATURE, CKM_SHA1_RSA_PKCS);
816
0
        rv = sc_pkcs15_add_supported_algo_ref(object, algo);
817
0
        LOG_TEST_RET(ctx, rv, "cannot add supported algorithm SIGN:CKM_SHA1_RSA_PKCS");
818
819
0
        algo = sc_pkcs15_get_supported_algo(p15card, SC_PKCS15_ALGO_OP_COMPUTE_SIGNATURE, CKM_SHA256_RSA_PKCS);
820
0
        rv = sc_pkcs15_add_supported_algo_ref(object, algo);
821
0
        LOG_TEST_RET(ctx, rv, "cannot add supported algorithm SIGN:CKM_SHA256_RSA_PKCS");
822
0
      }
823
0
      else   {
824
0
        algo = sc_pkcs15_get_supported_algo(p15card, SC_PKCS15_ALGO_OP_COMPUTE_SIGNATURE, CKM_RSA_PKCS);
825
0
        rv = sc_pkcs15_add_supported_algo_ref(object, algo);
826
0
        LOG_TEST_RET(ctx, rv, "cannot add supported algorithm SIGN:CKM_RSA_PKCS");
827
0
      }
828
0
    }
829
830
0
    for (ii=0; ii<SC_MAX_SUPPORTED_ALGORITHMS && prkey_info->algo_refs[ii]; ii++)
831
0
      sc_log(ctx, "algoReference %i", prkey_info->algo_refs[ii]);
832
0
    break;
833
0
  default:
834
0
    rv = SC_ERROR_NOT_SUPPORTED;
835
0
    break;
836
0
  }
837
838
0
  LOG_FUNC_RETURN(ctx, rv);
839
0
}
840
841
842
/*
843
 * Store SDO key RSA
844
 */
845
static int
846
iasecc_sdo_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
847
    struct iasecc_sdo *sdo_prvkey, struct iasecc_sdo *sdo_pubkey,
848
    struct sc_pkcs15_prkey_rsa *rsa)
849
0
{
850
0
  struct sc_context *ctx = p15card->card->ctx;
851
0
  struct sc_card *card = p15card->card;
852
0
  unsigned long caps = card->caps;
853
0
  struct iasecc_sdo_rsa_update update;
854
0
  struct sc_file  *dummy_file = NULL;
855
0
  int rv;
856
857
0
  LOG_FUNC_CALLED(ctx);
858
859
0
  if (!sdo_prvkey && !sdo_pubkey)
860
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "At least one SDO has to be supplied");
861
862
0
  rv = iasecc_sdo_convert_to_file(card, sdo_prvkey ? sdo_prvkey : sdo_pubkey, &dummy_file);
863
0
  LOG_TEST_RET(ctx, rv, "Cannot convert SDO PRIVATE KEY to file");
864
865
0
  card->caps &= ~SC_CARD_CAP_USE_FCI_AC;
866
0
  rv = sc_pkcs15init_authenticate(profile, p15card, dummy_file, SC_AC_OP_UPDATE);
867
0
  card->caps = caps;
868
0
  sc_file_free(dummy_file);
869
870
0
  LOG_TEST_RET(ctx, rv, "SDO PRIVATE KEY UPDATE authentication failed");
871
872
0
  memset(&update, 0, sizeof(update));
873
874
0
  update.sdo_prv_key = sdo_prvkey;
875
0
  update.sdo_pub_key = sdo_pubkey;
876
0
  update.p15_rsa = rsa;
877
0
  update.magic = IASECC_SDO_MAGIC_UPDATE_RSA;
878
879
0
  rv = sc_card_ctl(card, SC_CARDCTL_IASECC_SDO_KEY_RSA_PUT_DATA, &update);
880
0
  LOG_TEST_RET(ctx, rv, "store IAS SDO PRIVATE KEY failed");
881
882
0
  LOG_FUNC_RETURN(ctx, rv);
883
0
}
884
885
886
static int
887
iasecc_pkcs15_add_algorithm_reference(struct sc_pkcs15_card *p15card,
888
    struct sc_pkcs15_prkey_info *key_info, unsigned algo_ref)
889
0
{
890
0
  int ii, jj;
891
892
0
  for (jj=0;jj<SC_MAX_SUPPORTED_ALGORITHMS && key_info->algo_refs[jj];jj++)
893
0
    ;
894
0
  if (jj == SC_MAX_SUPPORTED_ALGORITHMS)
895
0
    return SC_ERROR_TOO_MANY_OBJECTS;
896
897
0
  for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS;ii++)
898
0
    if (p15card->tokeninfo->supported_algos[ii].algo_ref == algo_ref)
899
0
      break;
900
0
  if (ii == SC_MAX_SUPPORTED_ALGORITHMS)
901
0
    return SC_ERROR_OBJECT_NOT_FOUND;
902
903
0
  key_info->algo_refs[jj] = p15card->tokeninfo->supported_algos[ii].reference;
904
0
  return SC_SUCCESS;
905
0
}
906
907
908
static int
909
iasecc_pkcs15_fix_private_key_attributes(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
910
          struct sc_pkcs15_object *object,
911
          struct iasecc_sdo *sdo_prvkey)
912
0
{
913
0
  struct sc_card *card = p15card->card;
914
0
  struct sc_context *ctx = card->ctx;
915
0
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data;
916
0
  int rv = 0, ii;
917
0
  unsigned keys_access_modes[IASECC_MAX_SCBS] = {
918
0
    SC_PKCS15_ACCESS_RULE_MODE_PSO_CDS, SC_PKCS15_ACCESS_RULE_MODE_INT_AUTH, SC_PKCS15_ACCESS_RULE_MODE_PSO_DECRYPT,
919
0
    SC_PKCS15_ACCESS_RULE_MODE_EXECUTE, 0x00, SC_PKCS15_ACCESS_RULE_MODE_UPDATE, SC_PKCS15_ACCESS_RULE_MODE_READ
920
0
  };
921
922
0
  LOG_FUNC_CALLED(ctx);
923
0
  if (!object->content.value || object->content.len != sizeof(struct iasecc_sdo))
924
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "store IAS SDO PRIVATE KEY failed");
925
926
0
  if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
927
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported object type");
928
929
0
  key_info->access_flags |= SC_PKCS15_PRKEY_ACCESS_SENSITIVE;
930
931
0
  sc_log(ctx, "SDO(class:%X,ref:%X,usage:%X)",
932
0
      sdo_prvkey->sdo_class, sdo_prvkey->sdo_ref, sdo_prvkey->usage);
933
0
  sc_log(ctx, "SDO ACLs(%zu):%s", sdo_prvkey->docp.acls_contact.size,
934
0
      sc_dump_hex(sdo_prvkey->docp.acls_contact.value, sdo_prvkey->docp.acls_contact.size));
935
0
  sc_log(ctx, "SDO AMB:%X, SCBS:%s", sdo_prvkey->docp.amb,
936
0
      sc_dump_hex(sdo_prvkey->docp.scbs, IASECC_MAX_SCBS));
937
938
0
  for (ii=0;ii<IASECC_MAX_SCBS;ii++)   {
939
0
    sc_log(ctx, "SBC(%i):%X", ii, sdo_prvkey->docp.scbs[ii]);
940
0
    if (sdo_prvkey->docp.scbs[ii] == 0xFF)   {
941
0
      continue;
942
0
    }
943
0
    else if (sdo_prvkey->docp.scbs[ii] == 0x00)   {
944
0
      rv = iasecc_pkcs15_add_access_rule(object, keys_access_modes[ii], NULL);
945
0
      LOG_TEST_RET(ctx, rv, "Cannot add access rule");
946
0
    }
947
0
    else if (sdo_prvkey->docp.scbs[ii] & IASECC_SCB_METHOD_USER_AUTH)   {
948
0
      struct sc_pkcs15_id auth_id;
949
950
0
      rv = iasecc_pkcs15_get_auth_id_from_se(p15card, sdo_prvkey->docp.scbs[ii], &auth_id);
951
0
      LOG_TEST_RET(ctx, rv, "Cannot get AUTH.ID from SE");
952
953
0
      rv = iasecc_pkcs15_add_access_rule(object, keys_access_modes[ii], &auth_id);
954
0
      LOG_TEST_RET(ctx, rv, "Cannot add access rule");
955
956
0
      if (ii == IASECC_ACLS_RSAKEY_PSO_SIGN || ii == IASECC_ACLS_RSAKEY_INTERNAL_AUTH
957
0
          || ii == IASECC_ACLS_RSAKEY_PSO_DECIPHER)   {
958
0
        if (!sc_pkcs15_compare_id(&object->auth_id, &auth_id))   {
959
          /* Sorry, this will silently overwrite the profile option.*/
960
0
          sc_log(ctx, "Change object's authId for the one that really protects crypto operation.");
961
0
          object->auth_id = auth_id;
962
0
        }
963
964
0
        rv = iasecc_pkcs15_add_access_rule(object, SC_PKCS15_ACCESS_RULE_MODE_EXECUTE, &auth_id);
965
0
        LOG_TEST_RET(ctx, rv, "Cannot add 'EXECUTE' access rule");
966
0
      }
967
0
    }
968
969
0
    if (ii == IASECC_ACLS_RSAKEY_PSO_SIGN)   {
970
0
      rv = iasecc_pkcs15_add_algorithm_reference(p15card, key_info,
971
0
          IASECC_ALGORITHM_RSA_PKCS | IASECC_ALGORITHM_SHA1);
972
0
      LOG_TEST_RET(ctx, rv, "Cannot add RSA_PKCS SHA1 supported mechanism");
973
974
0
      rv = iasecc_pkcs15_add_algorithm_reference(p15card, key_info,
975
0
          IASECC_ALGORITHM_RSA_PKCS | IASECC_ALGORITHM_SHA2);
976
0
      LOG_TEST_RET(ctx, rv, "Cannot add RSA_PKCS SHA2 supported mechanism");
977
978
0
      if (sdo_prvkey->docp.non_repudiation.value && sdo_prvkey->docp.non_repudiation.value[0])   {
979
0
        object->user_consent = 1;
980
0
      }
981
0
    }
982
0
    else if (ii == IASECC_ACLS_RSAKEY_INTERNAL_AUTH)   {
983
0
      rv = iasecc_pkcs15_add_algorithm_reference(p15card, key_info, IASECC_ALGORITHM_RSA_PKCS);
984
0
      LOG_TEST_RET(ctx, rv, "Cannot add RSA_PKCS supported mechanism");
985
986
0
    }
987
0
    else if (ii == IASECC_ACLS_RSAKEY_PSO_DECIPHER)   {
988
0
      rv = iasecc_pkcs15_add_algorithm_reference(p15card, key_info,
989
0
          IASECC_ALGORITHM_RSA_PKCS_DECRYPT | IASECC_ALGORITHM_SHA1);
990
0
      LOG_TEST_RET(ctx, rv, "Cannot add decipher RSA_PKCS supported mechanism");
991
992
0
    }
993
0
  }
994
995
0
  LOG_FUNC_RETURN(ctx, rv);
996
0
}
997
998
999
static int
1000
iasecc_pkcs15_create_key_slot(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
1001
    struct iasecc_sdo *sdo_prvkey, struct iasecc_sdo *sdo_pubkey,
1002
    struct sc_pkcs15_prkey_info *key_info)
1003
0
{
1004
0
  struct sc_context *ctx = p15card->card->ctx;
1005
0
  struct sc_card *card = p15card->card;
1006
0
  struct sc_file  *file_p_pubkey = NULL, *file_p_prvkey = NULL, *parent = NULL;
1007
0
  unsigned long save_card_caps = p15card->card->caps;
1008
0
  int rv;
1009
1010
0
  LOG_FUNC_CALLED(ctx);
1011
1012
0
  rv = iasecc_pkcs15_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file_p_prvkey);
1013
0
  LOG_TEST_GOTO_ERR(ctx, rv, "create key slot: cannot instantiate PRKEY_RSA file");
1014
1015
0
  rv = iasecc_pkcs15_new_file(profile, card, SC_PKCS15_TYPE_PUBKEY_RSA, key_info->key_reference, &file_p_pubkey);
1016
0
  LOG_TEST_GOTO_ERR(ctx, rv, "create key slot: cannot instantiate PUBKEY_RSA file");
1017
1018
0
  rv = iasecc_file_convert_acls(ctx, profile, file_p_prvkey);
1019
0
  LOG_TEST_GOTO_ERR(ctx, rv, "create key slot: cannot convert ACLs of the private key file");
1020
1021
0
  rv = iasecc_file_convert_acls(ctx, profile, file_p_pubkey);
1022
0
  LOG_TEST_GOTO_ERR(ctx, rv, "create key slot: cannot convert ACLs of the public key file");
1023
1024
0
  rv = sc_profile_get_parent(profile, "private-key", &parent);
1025
0
  LOG_TEST_GOTO_ERR(ctx, rv, "create key slot: cannot get parent of private key file");
1026
1027
0
  rv = iasecc_file_convert_acls(ctx, profile, parent);
1028
0
  LOG_TEST_GOTO_ERR(ctx, rv, "create key slot: cannot convert parent's ACLs");
1029
1030
  /* Oberthur's card do not returns FCP for selected application DF.
1031
   * That's why for the following authentication use the 'CREATE' ACL defined in the application profile. */
1032
0
  if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR)
1033
0
    p15card->card->caps &= ~SC_CARD_CAP_USE_FCI_AC;
1034
0
  rv = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_CREATE);
1035
0
  p15card->card->caps  = save_card_caps;
1036
0
  LOG_TEST_GOTO_ERR(ctx, rv, "create key slot: SC_AC_OP_CREATE authentication failed");
1037
1038
0
  if (!sdo_prvkey->not_on_card)
1039
0
    sc_log(ctx, "create key slot: SDO private key already present");
1040
0
  else
1041
0
    rv = sc_card_ctl(card, SC_CARDCTL_IASECC_SDO_CREATE, sdo_prvkey);
1042
0
  LOG_TEST_GOTO_ERR(ctx, rv, "create key slot: cannot create private key: ctl failed");
1043
1044
0
  if (!sdo_pubkey->not_on_card)
1045
0
    sc_log(ctx, "create key slot: SDO public key already present");
1046
0
  else
1047
0
    rv = sc_card_ctl(card, SC_CARDCTL_IASECC_SDO_CREATE, sdo_pubkey);
1048
0
  LOG_TEST_GOTO_ERR(ctx, rv, "create key slot: cannot create public key: ctl failed");
1049
1050
0
err:
1051
0
  sc_file_free(file_p_prvkey);
1052
0
  sc_file_free(file_p_pubkey);
1053
0
  sc_file_free(parent);
1054
1055
0
  LOG_FUNC_RETURN(ctx, rv);
1056
0
}
1057
1058
static int
1059
iasecc_pkcs15_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
1060
          struct sc_pkcs15_object *object)
1061
0
{
1062
0
  struct sc_card *card = p15card->card;
1063
0
  struct sc_context *ctx = card->ctx;
1064
0
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data;
1065
0
  struct iasecc_sdo *sdo_prvkey = NULL, *sdo_pubkey = NULL;
1066
0
  size_t keybits = key_info->modulus_length;
1067
0
  unsigned char zeros[0x200];
1068
0
  int  rv;
1069
1070
0
  LOG_FUNC_CALLED(ctx);
1071
0
  sc_log(ctx, "create private key(keybits:%zu,usage:%X,access:%X,ref:%X)",
1072
0
      keybits, key_info->usage, key_info->access_flags, key_info->key_reference);
1073
0
  if (keybits < 1024 || keybits > 2048 || (keybits % 256))   {
1074
0
    sc_log(ctx, "Unsupported key size %zu", keybits);
1075
0
    return SC_ERROR_INVALID_ARGUMENTS;
1076
0
  }
1077
1078
0
  memset(zeros, 0, sizeof(zeros));
1079
1080
0
  rv = iasecc_sdo_allocate_pubkey(profile, card, (struct sc_pkcs15_pubkey_info *)key_info, &sdo_pubkey);
1081
0
  LOG_TEST_RET(ctx, rv, "IasEcc: allocate SDO public key failed");
1082
0
  sc_log(ctx, "iasecc_pkcs15_create_key() sdo_pubkey->not_on_card %i", sdo_pubkey->not_on_card);
1083
1084
0
  rv = iasecc_sdo_allocate_prvkey(profile, card, key_info, &sdo_prvkey);
1085
0
  LOG_TEST_GOTO_ERR(ctx, rv, "IasEcc: init SDO private key failed");
1086
0
  sc_log(ctx, "iasecc_pkcs15_create_key() sdo_prvkey->not_on_card %i", sdo_prvkey->not_on_card);
1087
1088
0
  if (!sdo_prvkey->not_on_card && !sdo_pubkey->not_on_card)   {
1089
0
    sc_log(ctx, "Key ref %i already allocated", key_info->key_reference);
1090
0
  }
1091
0
  else   {
1092
0
    rv = iasecc_pkcs15_create_key_slot(profile, p15card, sdo_prvkey, sdo_pubkey, key_info);
1093
0
    LOG_TEST_GOTO_ERR(ctx, rv, "Cannot create key slot");
1094
0
  }
1095
1096
0
  rv = sc_pkcs15_allocate_object_content(ctx, object, (unsigned char *)sdo_prvkey, sizeof(struct iasecc_sdo));
1097
0
  LOG_TEST_GOTO_ERR(ctx, rv, "Failed to allocate PrvKey SDO as object content");
1098
1099
0
  rv = iasecc_pkcs15_fix_private_key_attributes(profile, p15card, object, (struct iasecc_sdo *)object->content.value);
1100
0
  LOG_TEST_GOTO_ERR(ctx, rv, "Failed to fix private key PKCS#15 attributes");
1101
1102
0
  key_info->path.len = 0;
1103
1104
0
err:
1105
0
  iasecc_sdo_free(card, sdo_pubkey);
1106
0
  iasecc_sdo_free(card, sdo_prvkey);
1107
1108
0
  LOG_FUNC_RETURN(ctx, rv);
1109
0
}
1110
1111
1112
/*
1113
 * RSA key generation
1114
 */
1115
static int
1116
iasecc_pkcs15_generate_key(struct sc_profile *profile, sc_pkcs15_card_t *p15card,
1117
    struct sc_pkcs15_object *object, struct sc_pkcs15_pubkey *pubkey)
1118
0
{
1119
0
  struct sc_card *card = p15card->card;
1120
0
  struct sc_context *ctx = card->ctx;
1121
0
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data;
1122
0
  size_t keybits = key_info->modulus_length;
1123
0
  struct iasecc_sdo *sdo_prvkey = NULL;
1124
0
  struct iasecc_sdo *sdo_pubkey = NULL;
1125
0
  struct sc_file  *file = NULL;
1126
0
  unsigned char *tmp = NULL;
1127
0
  size_t tmp_len;
1128
0
  unsigned long caps;
1129
0
  int rv;
1130
1131
0
  LOG_FUNC_CALLED(ctx);
1132
0
  sc_log(ctx, "generate key(bits:%zu,path:%s,AuthID:%s",
1133
0
      keybits, sc_print_path(&key_info->path), sc_pkcs15_print_id(&object->auth_id));
1134
1135
0
  if (!object->content.value || object->content.len != sizeof(struct iasecc_sdo))
1136
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid PrKey SDO data");
1137
1138
0
  sdo_prvkey = (struct iasecc_sdo *)object->content.value;
1139
0
  if (sdo_prvkey->magic != SC_CARDCTL_IASECC_SDO_MAGIC)
1140
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "'Magic' control failed for SDO PrvKey");
1141
1142
0
  if (keybits < 1024 || keybits > 2048 || (keybits%0x100))   {
1143
0
    sc_log(ctx, "Unsupported key size %zu\n", keybits);
1144
0
    return SC_ERROR_INVALID_ARGUMENTS;
1145
0
  }
1146
1147
  /* TODO: Check if native IAS middleware accepts the meaningful path value. */
1148
0
  rv = sc_profile_get_parent(profile, "private-key", &file);
1149
0
  LOG_TEST_RET(ctx, rv, "IasEcc: cannot get private key parent file");
1150
1151
0
  rv = sc_select_file(card, &file->path, NULL);
1152
0
  LOG_TEST_RET(ctx, rv, "DF for private objects not defined");
1153
1154
0
  sc_file_free(file);
1155
1156
0
  rv = iasecc_sdo_convert_to_file(card, sdo_prvkey, &file);
1157
0
  LOG_TEST_RET(ctx, rv, "Cannot convert SDO PRIVKEY to file");
1158
1159
0
  caps = card->caps;
1160
0
  card->caps &= ~SC_CARD_CAP_USE_FCI_AC;
1161
0
  rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_GENERATE);
1162
0
  card->caps = caps;
1163
0
  LOG_TEST_RET(ctx, rv, "SC_AC_OP_GENERATE authentication failed");
1164
1165
0
  key_info->access_flags |= SC_PKCS15_PRKEY_ACCESS_LOCAL;
1166
0
  key_info->access_flags |= SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE;
1167
0
  key_info->access_flags |= SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE;
1168
1169
0
  rv = sc_card_ctl(card, SC_CARDCTL_IASECC_SDO_GENERATE, sdo_prvkey);
1170
0
  LOG_TEST_RET(ctx, rv, "generate key failed");
1171
1172
  /* Quite dangerous -- cast of 'sc_pkcs15_prvkey_info' into 'sc_pkcs15_pubkey_info'. */
1173
0
  rv = iasecc_sdo_allocate_pubkey(profile, card, (struct sc_pkcs15_pubkey_info *)key_info, &sdo_pubkey);
1174
0
  LOG_TEST_RET(ctx, rv, "IasEcc: allocate SDO public key failed");
1175
1176
0
  pubkey->algorithm = SC_ALGORITHM_RSA;
1177
1178
0
  pubkey->u.rsa.modulus.len = sdo_pubkey->data.pub_key.n.size;
1179
0
  pubkey->u.rsa.modulus.data  = (unsigned char *) malloc(pubkey->u.rsa.modulus.len);
1180
0
  if (!pubkey->u.rsa.modulus.data)
1181
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1182
0
  memcpy(pubkey->u.rsa.modulus.data, sdo_pubkey->data.pub_key.n.value, pubkey->u.rsa.modulus.len);
1183
1184
0
  pubkey->u.rsa.exponent.len = sdo_pubkey->data.pub_key.e.size;
1185
0
  pubkey->u.rsa.exponent.data = (unsigned char *) malloc(pubkey->u.rsa.exponent.len);
1186
0
  if (!pubkey->u.rsa.exponent.data)
1187
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1188
0
  memcpy(pubkey->u.rsa.exponent.data, sdo_pubkey->data.pub_key.e.value, pubkey->u.rsa.exponent.len);
1189
1190
0
  rv = sc_pkcs15_encode_pubkey(ctx, pubkey, &tmp, &tmp_len);
1191
0
  LOG_TEST_RET(ctx, rv, "encode public key failed");
1192
1193
0
  rv = iasecc_pkcs15_encode_supported_algos(p15card, object);
1194
0
  LOG_TEST_RET(ctx, rv, "encode private key access rules failed");
1195
1196
  /* SDO PrvKey data replaced by public part of generated key */
1197
0
  rv = sc_pkcs15_allocate_object_content(ctx, object, tmp, tmp_len);
1198
0
  LOG_TEST_RET(ctx, rv, "Failed to allocate public key as object content");
1199
1200
0
  iasecc_sdo_free(card, sdo_pubkey);
1201
1202
0
  free(tmp);
1203
0
  LOG_FUNC_RETURN(ctx, rv);
1204
0
}
1205
1206
1207
/*
1208
 * Store a private key
1209
 */
1210
static int
1211
iasecc_pkcs15_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
1212
    struct sc_pkcs15_object *object, struct sc_pkcs15_prkey *prvkey)
1213
0
{
1214
0
  struct sc_card *card = p15card->card;
1215
0
  struct sc_context *ctx = card->ctx;
1216
0
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data;
1217
0
  size_t keybits = key_info->modulus_length;
1218
0
  struct iasecc_sdo *sdo_prvkey;
1219
0
  struct iasecc_sdo *sdo_pubkey = NULL;
1220
0
  struct sc_pkcs15_prkey_rsa *rsa = &prvkey->u.rsa;
1221
0
  struct sc_file  *file = NULL;
1222
0
  int rv;
1223
1224
0
  LOG_FUNC_CALLED(ctx);
1225
0
  sc_log(ctx, "Store IAS/ECC key(keybits:%zu,AuthID:%s,path:%s)",
1226
0
      keybits, sc_pkcs15_print_id(&object->auth_id), sc_print_path(&key_info->path));
1227
1228
0
  if (!object->content.value || object->content.len != sizeof(struct iasecc_sdo))
1229
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid PrKey SDO data");
1230
0
  else if (keybits < 1024 || keybits > 2048 || (keybits%0x100))
1231
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported key size");
1232
1233
0
  sdo_prvkey = (struct iasecc_sdo *)object->content.value;
1234
0
  if (sdo_prvkey->magic != SC_CARDCTL_IASECC_SDO_MAGIC)
1235
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "'Magic' control failed for SDO PrvKey");
1236
1237
0
  sc_log(ctx, "key compulsory attr(size:%zu,on_card:%i)", sdo_prvkey->data.prv_key.compulsory.size,
1238
0
      sdo_prvkey->data.prv_key.compulsory.on_card);
1239
1240
0
  rv = sc_profile_get_parent(profile, "private-key", &file);
1241
0
  LOG_TEST_RET(ctx, rv, "cannot instantiate parent DF of the private key");
1242
1243
0
  rv = sc_select_file(card, &file->path, NULL);
1244
0
  LOG_TEST_RET(ctx, rv, "failed to select parent DF");
1245
1246
0
  sc_file_free(file);
1247
1248
0
  key_info->access_flags &= ~SC_PKCS15_PRKEY_ACCESS_LOCAL;
1249
1250
0
  rv = iasecc_sdo_allocate_pubkey(profile, card, (struct sc_pkcs15_pubkey_info *)key_info, &sdo_pubkey);
1251
0
  LOG_TEST_RET(ctx, rv, "private key store failed: cannot allocate 'SDO PUBLIC KEY'");
1252
1253
0
  rv = iasecc_sdo_store_key(profile, p15card, sdo_prvkey, sdo_pubkey, rsa);
1254
0
  LOG_TEST_RET(ctx, rv, "cannot store SDO PRIVATE/PUBLIC KEYs");
1255
1256
  /* sdo_prvkey is freed while object is freeing */
1257
0
  iasecc_sdo_free(card, sdo_pubkey);
1258
1259
0
  LOG_FUNC_RETURN(ctx, rv);
1260
0
}
1261
1262
1263
static int
1264
iasecc_pkcs15_delete_sdo (struct sc_profile *profile, struct sc_pkcs15_card *p15card,
1265
    int sdo_class, int ref)
1266
0
{
1267
0
  struct sc_context *ctx = p15card->card->ctx;
1268
0
  struct sc_card *card = p15card->card;
1269
0
  struct iasecc_sdo *sdo = NULL;
1270
0
  struct sc_pkcs15_prkey_rsa rsa;
1271
0
  struct sc_file  *dummy_file = NULL;
1272
0
  unsigned long save_card_caps = card->caps;
1273
0
  int rv;
1274
1275
0
  LOG_FUNC_CALLED(ctx);
1276
0
  sc_log(ctx, "iasecc_pkcs15_delete_sdo() class 0x%X; reference %i", sdo_class, ref);
1277
1278
0
  sdo = calloc(1, sizeof(struct iasecc_sdo));
1279
0
  if (!sdo)
1280
0
    return SC_ERROR_OUT_OF_MEMORY;
1281
1282
0
  sdo->magic = SC_CARDCTL_IASECC_SDO_MAGIC;
1283
0
  sdo->sdo_class = sdo_class;
1284
0
  sdo->sdo_ref = ref & 0x3F;
1285
1286
0
  rv = iasecc_sdo_get_data(card, sdo);
1287
0
  if (rv < 0)   {
1288
0
    if (rv == SC_ERROR_DATA_OBJECT_NOT_FOUND)
1289
0
      rv = SC_SUCCESS;
1290
1291
0
    iasecc_sdo_free(card, sdo);
1292
0
    LOG_FUNC_RETURN(ctx, rv);
1293
0
  }
1294
1295
0
  if (sdo->sdo_class == IASECC_SDO_CLASS_RSA_PUBLIC)   {
1296
0
    if (sdo->data.pub_key.cha.value)   {
1297
0
      free(sdo->data.pub_key.cha.value);
1298
0
      sdo->data.pub_key.cha.value = NULL;
1299
0
      sdo->data.pub_key.cha.size = 0;
1300
0
    }
1301
0
  }
1302
1303
0
  sc_log(ctx, "iasecc_pkcs15_delete_sdo() SDO class 0x%X, ref 0x%X", sdo->sdo_class, sdo->sdo_ref);
1304
0
  rv = iasecc_sdo_convert_to_file(card, sdo, &dummy_file);
1305
0
  if (rv < 0)   {
1306
0
    iasecc_sdo_free(card, sdo);
1307
0
    LOG_TEST_RET(ctx, rv, "iasecc_pkcs15_delete_sdo() Cannot convert SDO to file");
1308
0
  }
1309
1310
0
  card->caps &= ~SC_CARD_CAP_USE_FCI_AC;
1311
0
  rv = sc_pkcs15init_authenticate(profile, p15card, dummy_file, SC_AC_OP_UPDATE);
1312
0
  card->caps = save_card_caps;
1313
1314
0
  sc_file_free(dummy_file);
1315
1316
0
  if (rv < 0)   {
1317
0
    iasecc_sdo_free(card, sdo);
1318
0
    LOG_TEST_RET(ctx, rv, "iasecc_pkcs15_delete_sdo() UPDATE authentication failed for SDO");
1319
0
  }
1320
1321
0
  if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR)   {
1322
    /* Oberthur's card supports creation/deletion of the key slots ... */
1323
0
    rv = sc_card_ctl(card, SC_CARDCTL_IASECC_SDO_DELETE, sdo);
1324
0
  }
1325
0
  else  {
1326
    /* ... other cards not.
1327
     * Set to zero the key components . */
1328
0
    unsigned char zeros[0x200];
1329
0
    int size;
1330
1331
0
    if (!sdo->docp.size.value || sdo->docp.size.size < 2) {
1332
0
      iasecc_sdo_free(card, sdo);
1333
0
      LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Missing/invalid SDO key size");
1334
0
    }
1335
1336
0
    size = *(sdo->docp.size.value + 0) * 0x100 + *(sdo->docp.size.value + 1);
1337
0
    if (size <= 0 || size > (int)sizeof(zeros)) {
1338
0
      iasecc_sdo_free(card, sdo);
1339
0
      LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Unsupported SDO key size");
1340
0
    }
1341
1342
0
    sc_log(ctx, "iasecc_pkcs15_delete_sdo() SDO size %i bytes", size);
1343
0
    memset(zeros, 0xA5, sizeof(zeros));
1344
0
    memset(&rsa, 0, sizeof(rsa));
1345
1346
0
    rsa.modulus.data = rsa.exponent.data = zeros;
1347
0
    rsa.modulus.len = size;
1348
0
    rsa.exponent.len = 3;
1349
1350
0
    rsa.p.data = rsa.q.data = rsa.iqmp.data = rsa.dmp1.data = rsa.dmq1.data = zeros;
1351
0
    rsa.p.len = rsa.q.len = rsa.iqmp.len = rsa.dmp1.len = rsa.dmq1.len = size/2;
1352
1353
    /* Don't know why, but, clean public key do not working with Gemalto card */
1354
0
    rv = iasecc_sdo_store_key(profile, p15card, sdo, NULL, &rsa);
1355
0
  }
1356
1357
0
  iasecc_sdo_free(card, sdo);
1358
0
  LOG_FUNC_RETURN(ctx, rv);
1359
0
}
1360
1361
1362
static int
1363
iasecc_pkcs15_delete_object (struct sc_profile *profile, struct sc_pkcs15_card *p15card,
1364
    struct sc_pkcs15_object *object, const struct sc_path *path)
1365
0
{
1366
0
  struct sc_context *ctx = p15card->card->ctx;
1367
0
  struct sc_file *file = NULL;
1368
0
  int rv, key_ref;
1369
1370
0
  LOG_FUNC_CALLED(ctx);
1371
1372
0
  switch(object->type & SC_PKCS15_TYPE_CLASS_MASK)   {
1373
0
  case SC_PKCS15_TYPE_PUBKEY:
1374
0
    key_ref = ((struct sc_pkcs15_pubkey_info *)object->data)->key_reference;
1375
0
    sc_log(ctx, "Ignore delete of SDO-PubKey(ref:%X) '%s', path %s", key_ref, object->label, sc_print_path(path));
1376
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1377
0
  case SC_PKCS15_TYPE_PRKEY:
1378
0
    sc_log(ctx, "delete PrivKey '%s', path %s", object->label, sc_print_path(path));
1379
0
    if (path->len || path->aid.len)   {
1380
0
      rv = sc_select_file(p15card->card, path, NULL);
1381
0
      LOG_TEST_RET(ctx, rv, "cannot select PrivKey path");
1382
0
    }
1383
1384
0
    key_ref = ((struct sc_pkcs15_prkey_info *)object->data)->key_reference;
1385
1386
    /* Delete both parts of the RSA key */
1387
0
    rv = iasecc_pkcs15_delete_sdo (profile, p15card, IASECC_SDO_CLASS_RSA_PRIVATE, key_ref);
1388
0
    LOG_TEST_RET(ctx, rv, "Cannot delete RSA_PRIVATE SDO");
1389
1390
0
    rv = iasecc_pkcs15_delete_sdo (profile, p15card, IASECC_SDO_CLASS_RSA_PUBLIC, key_ref);
1391
0
    LOG_TEST_RET(ctx, rv, "Cannot delete RSA_PUBLIC SDO");
1392
1393
0
    if (profile->md_style == SC_PKCS15INIT_MD_STYLE_GEMALTO)   {
1394
0
      rv = iasecc_md_gemalto_delete_prvkey(p15card, profile, object);
1395
0
      LOG_TEST_RET(ctx, rv, "MD error: cannot delete private key");
1396
0
    }
1397
1398
0
    LOG_FUNC_RETURN(ctx, rv);
1399
0
  case SC_PKCS15_TYPE_CERT:
1400
0
    sc_log(ctx, "delete Certificate '%s', path %s", object->label, sc_print_path(path));
1401
0
    break;
1402
0
  case SC_PKCS15_TYPE_DATA_OBJECT:
1403
0
    sc_log(ctx, "delete DataObject '%s', path %s", object->label, sc_print_path(path));
1404
0
    break;
1405
0
  default:
1406
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
1407
0
  }
1408
1409
0
  file = sc_file_new();
1410
0
  file->type = SC_FILE_TYPE_WORKING_EF;
1411
0
  file->ef_structure = SC_FILE_EF_TRANSPARENT;
1412
0
  file->id = path->value[path->len-2] * 0x100 + path->value[path->len-1];
1413
0
  memcpy(&file->path, path, sizeof(file->path));
1414
1415
0
  rv = iasecc_pkcs15_delete_file(p15card, profile, file);
1416
1417
0
  sc_file_free(file);
1418
1419
0
  LOG_FUNC_RETURN(ctx, rv);
1420
0
}
1421
1422
1423
static int
1424
iasecc_md_gemalto_set_default(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
1425
    struct sc_pkcs15_object *key_obj)
1426
0
{
1427
0
  struct sc_context *ctx = p15card->card->ctx;
1428
0
  struct sc_pkcs15_object *data_obj = NULL;
1429
0
  struct sc_pkcs15init_dataargs data_args;
1430
0
  unsigned char guid[40];
1431
0
  size_t guid_len;
1432
0
  int rv;
1433
1434
0
  LOG_FUNC_CALLED(ctx);
1435
1436
0
  rv = sc_pkcs15_find_data_object_by_name(p15card, "CSP", "Default Key Container", &data_obj);
1437
0
  if (rv != SC_ERROR_OBJECT_NOT_FOUND)
1438
0
    LOG_TEST_RET(ctx, rv, "Find 'Default Key Container' data object error");
1439
1440
0
  memset(guid, 0, sizeof(guid));
1441
0
  guid_len = sizeof(guid);
1442
1443
0
  rv = sc_pkcs15_get_object_guid(p15card, key_obj, 1, guid, &guid_len);
1444
0
  LOG_TEST_RET(ctx, rv, "Cannot get private key GUID");
1445
1446
0
  if (!data_obj)   {
1447
0
    memset(&data_args, 0, sizeof(data_args));
1448
0
    sc_init_oid(&data_args.app_oid);
1449
0
    data_args.label = "Default Key Container";
1450
0
    data_args.app_label = "CSP";
1451
0
    data_args.der_encoded.value = guid;
1452
0
    data_args.der_encoded.len = guid_len;
1453
1454
0
    rv = sc_pkcs15init_store_data_object(p15card, profile, &data_args, NULL);
1455
0
    LOG_TEST_RET(ctx, rv, "Failed to store 'CSP'/'Default Key Container' data object");
1456
0
  }
1457
0
  else   {
1458
0
    struct sc_pkcs15_data_info *dinfo = (struct sc_pkcs15_data_info *)data_obj->data;
1459
0
    struct sc_file *file = NULL;
1460
1461
0
    sc_log(ctx, "update data object content in '%s'\n", sc_print_path(&dinfo->path));
1462
0
    rv = sc_select_file(p15card->card, &dinfo->path, &file);
1463
0
    LOG_TEST_RET(ctx, rv, "Cannot select data object file");
1464
1465
0
    rv = sc_pkcs15init_update_file(profile, p15card, file, guid, guid_len);
1466
0
    sc_file_free(file);
1467
0
    LOG_TEST_RET(ctx, rv, "Failed to update 'CSP'/'Default Key Container' data object");
1468
0
  }
1469
1470
0
  LOG_FUNC_RETURN(ctx, rv);
1471
0
}
1472
1473
1474
static int
1475
iasecc_md_gemalto_unset_default(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
1476
    struct sc_pkcs15_object *key_obj)
1477
0
{
1478
0
  struct sc_context *ctx = p15card->card->ctx;
1479
0
  struct sc_pkcs15_object *data_obj = NULL;
1480
0
  struct sc_pkcs15_data *dod = NULL;
1481
0
  struct sc_pkcs15_object *key_objs[32];
1482
0
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)key_obj->data;
1483
0
  unsigned char guid[40];
1484
0
  size_t guid_len;
1485
0
  int rv, ii, keys_num, private_obj;
1486
1487
0
  LOG_FUNC_CALLED(ctx);
1488
1489
0
  memset(guid, 0, sizeof(guid));
1490
0
  guid_len = sizeof(guid);
1491
1492
0
  rv = sc_pkcs15_get_object_guid(p15card, key_obj, 1, guid, &guid_len);
1493
0
  LOG_TEST_RET(ctx, rv, "Cannot get private key GUID");
1494
1495
0
  rv = sc_pkcs15_find_data_object_by_name(p15card, "CSP", "Default Key Container", &data_obj);
1496
0
  if (rv == SC_ERROR_OBJECT_NOT_FOUND)
1497
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1498
1499
0
  private_obj = data_obj->flags & SC_PKCS15_CO_FLAG_PRIVATE;
1500
0
  rv = sc_pkcs15_read_data_object(p15card, (struct sc_pkcs15_data_info *)data_obj->data, private_obj, &dod);
1501
0
  LOG_TEST_RET(ctx, rv, "Cannot read from 'CSP/'Default Key Container'");
1502
1503
0
  if (guid_len != dod->data_len || memcmp(guid, dod->data, guid_len)) {
1504
0
    sc_pkcs15_free_data_object(dod);
1505
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1506
0
  }
1507
0
  sc_pkcs15_free_data_object(dod);
1508
1509
0
  rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, key_objs, 32);
1510
0
  LOG_TEST_RET(ctx, rv, "Get private key PKCS#15 objects error");
1511
0
  keys_num = rv;
1512
1513
0
  if (keys_num)   {
1514
0
    for (ii=0; ii<keys_num; ii++)   {
1515
0
      struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *)key_objs[ii]->data;
1516
1517
0
      if (sc_pkcs15_compare_id(&key_info->id, &prkey_info->id))
1518
0
        continue;
1519
1520
      /* TODO: keys with inappropriate key usages should also be ignored */
1521
0
      rv = iasecc_md_gemalto_set_default(p15card, profile, key_objs[ii]);
1522
0
      LOG_TEST_RET(ctx, rv, "Cannot set default container");
1523
0
      break;
1524
0
    }
1525
1526
0
    if (ii == keys_num)   {
1527
      /* No more default container */
1528
0
      rv = sc_pkcs15init_delete_object(p15card, profile, data_obj);
1529
0
      LOG_TEST_RET(ctx, rv, "Cannot delete 'CSP'/'Default Key Container' data object");
1530
0
    }
1531
0
  }
1532
1533
0
  LOG_FUNC_RETURN(ctx, rv);
1534
0
}
1535
1536
1537
static int
1538
iasecc_md_gemalto_new_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_pkcs15_object *key_obj)
1539
0
{
1540
0
  struct sc_context *ctx = p15card->card->ctx;
1541
0
  struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *)key_obj->data;
1542
0
  struct sc_pkcs15init_dataargs data_args;
1543
0
  unsigned char data[SC_PKCS15_MAX_ID_SIZE + 6];
1544
0
  unsigned char guid[40];
1545
0
  size_t offs, guid_len;
1546
0
  int rv;
1547
1548
0
  LOG_FUNC_CALLED(ctx);
1549
1550
0
  memset(guid, 0, sizeof(guid));
1551
0
  guid_len = sizeof(guid) - 1;
1552
1553
0
  rv = sc_pkcs15_get_object_guid(p15card, key_obj, 1, guid, &guid_len);
1554
0
  LOG_TEST_RET(ctx, rv, "Cannot get private key GUID");
1555
0
  sc_log(ctx, "New key GUID: '%s'", (char *)guid);
1556
1557
0
  offs = 0;
1558
0
  data[offs++] = 0x01;
1559
0
  data[offs++] = prkey_info->id.len;
1560
0
  memcpy(&data[offs], prkey_info->id.value, prkey_info->id.len);
1561
0
  offs += prkey_info->id.len;
1562
0
  data[offs++] = 0x02;
1563
0
  data[offs++] = 0x01;
1564
0
  data[offs++] = 0x01;
1565
1566
0
  memset(&data_args, 0, sizeof(data_args));
1567
0
  sc_init_oid(&data_args.app_oid);
1568
0
  data_args.label = (char *)guid;
1569
0
  data_args.app_label = "CSP";
1570
0
  data_args.der_encoded.value = data;
1571
0
  data_args.der_encoded.len = offs;
1572
1573
0
  rv = sc_pkcs15init_store_data_object(p15card, profile, &data_args, NULL);
1574
0
  LOG_TEST_RET(ctx, rv, "Failed to store 'CSP' data object");
1575
1576
  /* For a while default container is set for the first key.
1577
   * TODO: Key usage should be taken into consideration. */
1578
0
  if (sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, NULL, 0) == 1)   {
1579
0
    rv = iasecc_md_gemalto_set_default(p15card, profile, key_obj);
1580
0
    LOG_TEST_RET(ctx, rv, "MD: cannot set default container");
1581
0
  }
1582
1583
0
  LOG_FUNC_RETURN(ctx, rv);
1584
0
}
1585
1586
1587
static int
1588
iasecc_md_gemalto_delete_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
1589
    struct sc_pkcs15_object *key_obj)
1590
0
{
1591
0
  struct sc_context *ctx = p15card->card->ctx;
1592
0
  struct sc_pkcs15_object *data_obj = NULL;
1593
0
  unsigned char guid[40];
1594
0
  size_t guid_len;
1595
0
  int rv;
1596
1597
0
  LOG_FUNC_CALLED(ctx);
1598
1599
0
  memset(guid, 0, sizeof(guid));
1600
0
  guid_len = sizeof(guid) - 1;
1601
1602
0
  rv = sc_pkcs15_get_object_guid(p15card, key_obj, 1, guid, &guid_len);
1603
0
  LOG_TEST_RET(ctx, rv, "Cannot get private key GUID");
1604
1605
0
  rv = sc_pkcs15_find_data_object_by_name(p15card, "CSP", (char *)guid, &data_obj);
1606
0
  if (rv == SC_ERROR_OBJECT_NOT_FOUND)
1607
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1608
0
  LOG_TEST_RET(ctx, rv, "Find 'CSP'/<key> data object error");
1609
1610
0
  rv = sc_pkcs15init_delete_object(p15card, profile, data_obj);
1611
0
  LOG_TEST_RET(ctx, rv, "Cannot delete 'CSP'/<key> data object");
1612
1613
  /* For a while default container is set for the first key.
1614
   * TODO: Key usage should be taken into consideration. */
1615
0
  if (sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, NULL, 0) == 1)   {
1616
0
    rv = iasecc_md_gemalto_unset_default(p15card, profile, key_obj);
1617
0
    LOG_TEST_RET(ctx, rv, "MD: cannot set default container");
1618
0
  }
1619
1620
0
  LOG_FUNC_RETURN(ctx, rv);
1621
0
}
1622
1623
1624
static int
1625
iasecc_store_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_pkcs15_object *object,
1626
    struct sc_pkcs15_der *data, struct sc_path *path)
1627
0
{
1628
0
  struct sc_context *ctx = p15card->card->ctx;
1629
0
  struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *)object->data;
1630
1631
0
  LOG_FUNC_CALLED(ctx);
1632
0
  sc_log(ctx, "Private Key id '%s'", sc_pkcs15_print_id(&prkey_info->id));
1633
0
  sc_log(ctx, "MD style '0x%X'", profile->md_style);
1634
1635
0
  if (profile->md_style == SC_PKCS15INIT_MD_STYLE_NONE)   {
1636
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1637
0
  }
1638
0
  else if (profile->md_style == SC_PKCS15INIT_MD_STYLE_GEMALTO)   {
1639
0
    int rv = iasecc_md_gemalto_new_prvkey(p15card, profile, object);
1640
0
    LOG_TEST_RET(ctx, rv, "MD: cannot add new key");
1641
0
  }
1642
0
  else   {
1643
0
    LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported MD style");
1644
0
  }
1645
1646
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1647
0
}
1648
1649
1650
static int
1651
iasecc_store_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_pkcs15_object *object,
1652
    struct sc_pkcs15_der *data, struct sc_path *path)
1653
0
{
1654
0
  struct sc_context *ctx = p15card->card->ctx;
1655
0
  struct sc_pkcs15_pubkey_info *pubkey_info = (struct sc_pkcs15_pubkey_info *)object->data;
1656
0
  struct sc_pkcs15_prkey_info *prkey_info = NULL;
1657
0
  struct sc_pkcs15_object *prkey_object = NULL;
1658
0
  int rv;
1659
1660
0
  LOG_FUNC_CALLED(ctx);
1661
0
  sc_log(ctx, "Public Key id '%s'", sc_pkcs15_print_id(&pubkey_info->id));
1662
1663
0
  rv = sc_pkcs15_find_prkey_by_id(p15card, &pubkey_info->id, &prkey_object);
1664
0
  LOG_TEST_RET(ctx, rv, "Find related PrKey error");
1665
1666
0
  prkey_info = (struct sc_pkcs15_prkey_info *)prkey_object->data;
1667
1668
0
  pubkey_info->key_reference = prkey_info->key_reference;
1669
1670
0
  pubkey_info->access_flags = prkey_info->access_flags & SC_PKCS15_PRKEY_ACCESS_LOCAL;
1671
0
  pubkey_info->access_flags |= SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
1672
1673
0
  pubkey_info->native = 0;
1674
1675
0
  pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_SIGN ? SC_PKCS15_PRKEY_USAGE_VERIFY : 0;
1676
0
  pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_SIGNRECOVER ? SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER : 0;
1677
0
  pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION ? SC_PKCS15_PRKEY_USAGE_VERIFY : 0;
1678
0
  pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_DECRYPT ? SC_PKCS15_PRKEY_USAGE_ENCRYPT : 0;
1679
0
  pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_UNWRAP ? SC_PKCS15_PRKEY_USAGE_WRAP : 0;
1680
1681
0
  rv = iasecc_pkcs15_add_access_rule(object, SC_PKCS15_ACCESS_RULE_MODE_READ, NULL);
1682
0
  LOG_TEST_RET(ctx, rv, "Too many access rules");
1683
1684
0
  memcpy(&pubkey_info->algo_refs[0], &prkey_info->algo_refs[0], sizeof(pubkey_info->algo_refs));
1685
1686
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1687
0
}
1688
1689
1690
static int
1691
iasecc_store_cert(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
1692
    struct sc_pkcs15_object *object, struct sc_pkcs15_der *data,
1693
    struct sc_path *path)
1694
0
{
1695
0
  struct sc_context *ctx = p15card->card->ctx;
1696
0
  struct sc_card *card = p15card->card;
1697
0
  struct sc_file *pfile = NULL;
1698
0
  struct sc_path parent_path;
1699
0
  int rv;
1700
1701
0
  LOG_FUNC_CALLED(ctx);
1702
0
  sc_log(ctx, "iasecc_store_cert() authID '%s'", sc_pkcs15_print_id(&object->auth_id));
1703
1704
0
  rv = iasecc_pkcs15_new_file(profile, card, SC_PKCS15_TYPE_CERT, 0, &pfile);
1705
0
  LOG_TEST_RET(ctx, rv, "IasEcc new CERT file error");
1706
1707
0
  parent_path = pfile->path;
1708
0
  if (parent_path.len >= 2)
1709
0
    parent_path.len -= 2;
1710
0
  if (!parent_path.len && !parent_path.aid.len)
1711
0
    sc_format_path("3F00", &parent_path);
1712
0
  rv = sc_select_file(card, &parent_path, NULL);
1713
0
  LOG_TEST_RET(ctx, rv, "cannot select parent of certificate to store");
1714
1715
0
  rv = iasecc_pkcs15_fix_file_access(p15card, pfile, object);
1716
0
  LOG_TEST_RET(ctx, rv, "encode file access rules failed");
1717
1718
0
  sc_file_free(pfile);
1719
1720
  /* NOT_IMPLEMENTED error code indicates to the upper call to execute the default 'store data' procedure */
1721
0
  LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_IMPLEMENTED);
1722
0
}
1723
1724
1725
static int
1726
iasecc_store_data_object(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
1727
    struct sc_pkcs15_object *object,
1728
    struct sc_pkcs15_der *data, struct sc_path *path)
1729
0
{
1730
0
#define MAX_DATA_OBJS 32
1731
0
  struct sc_context *ctx = p15card->card->ctx;
1732
0
  struct sc_card *card = p15card->card;
1733
0
  struct sc_pkcs15_object *p15objects[MAX_DATA_OBJS];
1734
0
  struct sc_file *cfile = NULL, *file = NULL, *parent = NULL;
1735
0
  int rv, nn_objs, index, ii;
1736
1737
0
  LOG_FUNC_CALLED(ctx);
1738
0
  sc_log(ctx, "iasecc_store_data_object() authID '%s'", sc_pkcs15_print_id(&object->auth_id));
1739
0
  nn_objs = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, p15objects, MAX_DATA_OBJS);
1740
0
  LOG_TEST_RET(ctx, nn_objs, "IasEcc get pkcs15 DATA objects error");
1741
1742
0
  for(index = 1; index < MAX_DATA_OBJS; index++)   {
1743
0
    rv = iasecc_pkcs15_new_file(profile, card, SC_PKCS15_TYPE_DATA_OBJECT, index, &file);
1744
0
    LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() pkcs15 new DATA file error");
1745
1746
0
    for (ii=0; ii<nn_objs; ii++)   {
1747
0
      struct sc_pkcs15_data_info *info = (struct sc_pkcs15_data_info *)p15objects[ii]->data;
1748
0
      int file_id = info->path.value[info->path.len - 2] * 0x100 + info->path.value[info->path.len - 1];
1749
1750
0
      sc_log(ctx, "iasecc_store_data_object() %i: file_id 0x%X, pfile->id 0x%X\n", ii, file_id, file->id);
1751
0
      if (file->id == file_id)
1752
0
         break;
1753
0
    }
1754
1755
0
    if (ii == nn_objs)
1756
0
      break;
1757
0
    sc_file_free(file);
1758
0
    file = NULL;
1759
0
  }
1760
1761
0
  if (index == MAX_DATA_OBJS)
1762
0
    LOG_TEST_GOTO_ERR(ctx, SC_ERROR_TOO_MANY_OBJECTS, "iasecc_store_data_object() too many DATA objects.");
1763
1764
0
  do  {
1765
0
    const struct sc_acl_entry *acl;
1766
1767
0
    memset(object->access_rules, 0, sizeof(object->access_rules));
1768
1769
0
    object->access_rules[0].access_mode = SC_PKCS15_ACCESS_RULE_MODE_READ;
1770
0
    acl = sc_file_get_acl_entry(file, SC_AC_OP_READ);
1771
0
    sc_log(ctx, "iasecc_store_data_object() READ method %i", acl->method);
1772
0
    if (acl->method == SC_AC_IDA)
1773
0
      iasecc_reference_to_pkcs15_id (acl->key_ref, &object->access_rules[0].auth_id);
1774
1775
0
    object->access_rules[1].access_mode = SC_PKCS15_ACCESS_RULE_MODE_UPDATE;
1776
0
    acl = sc_file_get_acl_entry(file, SC_AC_OP_UPDATE);
1777
0
    sc_log(ctx, "iasecc_store_data_object() UPDATE method %i", acl->method);
1778
0
    if (acl->method == SC_AC_IDA)
1779
0
      iasecc_reference_to_pkcs15_id (acl->key_ref, &object->access_rules[1].auth_id);
1780
1781
0
    object->access_rules[2].access_mode = SC_PKCS15_ACCESS_RULE_MODE_DELETE;
1782
0
    acl = sc_file_get_acl_entry(file, SC_AC_OP_DELETE);
1783
0
    sc_log(ctx, "iasecc_store_data_object() UPDATE method %i", acl->method);
1784
0
    if (acl->method == SC_AC_IDA)
1785
0
      iasecc_reference_to_pkcs15_id (acl->key_ref, &object->access_rules[2].auth_id);
1786
1787
0
  } while(0);
1788
1789
0
  rv = iasecc_file_convert_acls(ctx, profile, file);
1790
0
  LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() cannot convert profile ACLs");
1791
1792
0
  rv = sc_profile_get_parent(profile, "public-data", &parent);
1793
0
  LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() cannot get object parent");
1794
0
  sc_log(ctx, "iasecc_store_data_object() parent path '%s'\n", sc_print_path(&parent->path));
1795
1796
0
  rv = sc_select_file(card, &parent->path, NULL);
1797
0
  LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() cannot select parent");
1798
1799
0
  rv = sc_select_file(card, &file->path, &cfile);
1800
0
  if (!rv)   {
1801
0
    rv = sc_pkcs15init_authenticate(profile, p15card, cfile, SC_AC_OP_DELETE);
1802
0
    LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() DELETE authentication failed");
1803
1804
0
    rv = iasecc_pkcs15_delete_file(p15card, profile, cfile);
1805
0
    LOG_TEST_GOTO_ERR(ctx, rv, "s_pkcs15init_store_data_object() delete pkcs15 file error");
1806
0
  }
1807
0
  else if (rv != SC_ERROR_FILE_NOT_FOUND)   {
1808
0
    LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() select file error");
1809
0
  }
1810
1811
0
  rv = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_CREATE);
1812
0
  LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() parent CREATE authentication failed");
1813
1814
0
  file->size = data->len;
1815
0
  rv = sc_create_file(card, file);
1816
0
  LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() cannot create DATA file");
1817
1818
0
  rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
1819
0
  LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() data file UPDATE authentication failed");
1820
1821
0
  rv = sc_update_binary(card, 0, data->value, data->len, 0);
1822
0
  LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_store_data_object() update DATA file failed");
1823
1824
0
  if (path)
1825
0
    *path = file->path;
1826
0
err:
1827
0
  sc_file_free(parent);
1828
0
  sc_file_free(file);
1829
0
  sc_file_free(cfile);
1830
1831
0
  LOG_FUNC_RETURN(ctx, rv);
1832
0
#undef MAX_DATA_OBJS
1833
0
}
1834
1835
1836
static int
1837
iasecc_emu_store_data(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
1838
    struct sc_pkcs15_object *object,
1839
    struct sc_pkcs15_der *data, struct sc_path *path)
1840
1841
0
{
1842
0
  struct sc_context *ctx = p15card->card->ctx;
1843
0
  int rv = SC_ERROR_NOT_IMPLEMENTED;
1844
1845
0
  LOG_FUNC_CALLED(ctx);
1846
1847
0
  switch (object->type & SC_PKCS15_TYPE_CLASS_MASK) {
1848
0
  case SC_PKCS15_TYPE_PRKEY:
1849
0
    rv = iasecc_store_prvkey(p15card, profile, object, data, path);
1850
0
    break;
1851
0
  case SC_PKCS15_TYPE_PUBKEY:
1852
0
    rv = iasecc_store_pubkey(p15card, profile, object, data, path);
1853
0
    break;
1854
0
  case SC_PKCS15_TYPE_CERT:
1855
0
    rv = iasecc_store_cert(p15card, profile, object, data, path);
1856
0
    break;
1857
0
  case SC_PKCS15_TYPE_DATA_OBJECT:
1858
0
    rv = iasecc_store_data_object(p15card, profile, object, data, path);
1859
0
    break;
1860
0
  default:
1861
0
    rv = SC_ERROR_NOT_IMPLEMENTED;
1862
0
    break;
1863
0
  }
1864
1865
0
  LOG_FUNC_RETURN(ctx, rv);
1866
0
}
1867
1868
1869
static struct sc_pkcs15init_operations
1870
sc_pkcs15init_iasecc_operations = {
1871
  iasecc_pkcs15_erase_card,
1872
  NULL,         /* init_card  */
1873
  NULL,         /* create_dir */
1874
  NULL,         /* create_domain */
1875
  NULL,         /* select_pin_reference */
1876
  NULL,         /* create_pin */
1877
  iasecc_pkcs15_select_key_reference,
1878
  iasecc_pkcs15_create_key,
1879
  iasecc_pkcs15_store_key,
1880
  iasecc_pkcs15_generate_key,
1881
  NULL,         /* encode private key */
1882
  NULL,         /* encode public key */
1883
  NULL,         /* finalize_card */
1884
  iasecc_pkcs15_delete_object,
1885
  NULL,         /* pkcs15init emulation update_dir */
1886
  NULL,         /* pkcs15init emulation update_any_df */
1887
  NULL,         /* pkcs15init emulation update_tokeninfo */
1888
  NULL,         /* pkcs15init emulation write_info */
1889
  iasecc_emu_store_data,
1890
  NULL,         /* sanity_check */
1891
};
1892
1893
1894
struct sc_pkcs15init_operations *
1895
sc_pkcs15init_get_iasecc_ops(void)
1896
0
{
1897
0
  return &sc_pkcs15init_iasecc_operations;
1898
0
}
1899
1900
#else /* ENABLE_OPENSSL */
1901
#include "../libopensc/log.h"
1902
#include "pkcs15-init.h"
1903
1904
int
1905
iasecc_pkcs15_encode_supported_algos(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object)
1906
{
1907
  struct sc_context *ctx = p15card->card->ctx;
1908
  FIX_UNUSED(object);
1909
1910
  LOG_FUNC_CALLED(ctx);
1911
  sc_log(ctx, "OpenSC was built without OpenSSL support: skipping");
1912
  LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_IMPLEMENTED);
1913
}
1914
1915
#endif /* ENABLE_OPENSSL */