Coverage Report

Created: 2025-11-06 06:35

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