Coverage Report

Created: 2025-07-12 06:53

/src/opensc/src/pkcs15init/pkcs15-myeid.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * MyEID specific operations for PKCS15 initialization
3
 *
4
 * Copyright (C) 2008-2009 Aventra Ltd.
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
21
#include "config.h"
22
23
#include <assert.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <sys/types.h>
27
28
#include "libopensc/opensc.h"
29
#include "libopensc/cardctl.h"
30
#include "libopensc/internal.h"
31
#include "libopensc/log.h"
32
#include "pkcs15-init.h"
33
#include "profile.h"
34
#include "libopensc/asn1.h"
35
#include "pkcs11/pkcs11.h"
36
37
#undef KEEP_AC_NONE_FOR_INIT_APPLET
38
39
1.64k
#define MYEID_MAX_PINS   14
40
#define MYEID_MAX_RSA_KEY_LEN 4096
41
42
unsigned char MYEID_DEFAULT_PUBKEY[] = {0x01, 0x00, 0x01};
43
204
#define MYEID_DEFAULT_PUBKEY_LEN       sizeof(MYEID_DEFAULT_PUBKEY)
44
45
591
#define MYEID_PROP_INFO_2_EXCTRACTABLE      0x08;
46
#define MYEID_PROP_INFO_1_TRUSTED       0x04;
47
#define MYEID_PROP_INFO_1_WRAP_WITH_TRUSTED   0x08;
48
0
#define MYEID_PROP_INFO_2_SESSION_OBJECT    0x01;
49
50
static const struct sc_object_id id_aes128_ecb = { { 2, 16, 840, 1, 101, 3, 4, 1, 1, -1 } };
51
static const struct sc_object_id id_aes128_cbc = { { 2, 16, 840, 1, 101, 3, 4, 1, 2, -1 } };
52
static const struct sc_object_id id_aes256_ecb = { { 2, 16, 840, 1, 101, 3, 4, 1, 41, -1 } };
53
static const struct sc_object_id id_aes256_cbc = { { 2, 16, 840, 1, 101, 3, 4, 1, 42, -1 } };
54
55
static void
56
_add_supported_algo(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object,
57
        unsigned operations, unsigned mechanism, const struct sc_object_id *oid);
58
59
/* For Myeid, all objects are files that can be deleted in any order */
60
static int
61
myeid_delete_object(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
62
0
    struct sc_pkcs15_object *object, const struct sc_path *path) {
63
0
  LOG_FUNC_CALLED(p15card->card->ctx);
64
0
  return sc_pkcs15init_delete_by_path(profile, p15card, path);
65
0
}
66
67
/*
68
 * Get 'Initialize Applet' data
69
 * using the ACLs defined in card profile.
70
 */
71
static int
72
myeid_get_init_applet_data(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
73
1.06k
    unsigned char *data, size_t data_len) {
74
1.06k
  struct sc_context *ctx = p15card->card->ctx;
75
1.06k
  struct sc_file *tmp_file = NULL;
76
1.06k
  const struct sc_acl_entry *entry = NULL;
77
1.06k
  int r;
78
79
1.06k
  LOG_FUNC_CALLED(ctx);
80
81
1.06k
  if (data_len < 8)
82
1.06k
    LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Cannot get init applet data");
83
84
1.06k
  *(data + 0) = 0xFF;
85
1.06k
  *(data + 1) = 0xFF;
86
87
  /* MF acls */
88
1.06k
  sc_file_dup(&tmp_file, profile->mf_info->file);
89
1.06k
  if (tmp_file == NULL)
90
1.06k
    LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot duplicate MF file");
91
92
1.06k
  r = sc_pkcs15init_fixup_file(profile, p15card, tmp_file);
93
1.06k
  if (r < 0)
94
19
    sc_file_free(tmp_file);
95
1.06k
  LOG_TEST_RET(ctx, r, "MF fixup failed");
96
97
  /* AC 'Create DF' and 'Create EF' */
98
1.04k
  *(data + 2) = 0x00; /* 'NONE' */
99
1.04k
  entry = sc_file_get_acl_entry(tmp_file, SC_AC_OP_CREATE);
100
1.04k
  if (entry->method == SC_AC_CHV)
101
110
    *(data + 2) = entry->key_ref | (entry->key_ref << 4); /* 'CHVx'. */
102
935
  else if (entry->method == SC_AC_NEVER)
103
1
    *(data + 2) = 0xFF; /* 'NEVER'. */
104
105
  /* AC 'INITIALISE APPLET'. */
106
1.04k
  *(data + 3) = 0x0F; /* 'NONE' */
107
1.04k
#ifndef KEEP_AC_NONE_FOR_INIT_APPLET
108
1.04k
  entry = sc_file_get_acl_entry(tmp_file, SC_AC_OP_DELETE);
109
1.04k
  if (entry->method == SC_AC_CHV)
110
171
    *(data + 3) = (entry->key_ref << 4) | 0xF;
111
874
  else if (entry->method == SC_AC_NEVER)
112
1
    *(data + 3) = 0xFF;
113
1.04k
#endif
114
1.04k
  *(data + 4) = 0xFF;
115
116
1.04k
  sc_file_free(tmp_file);
117
1.04k
  tmp_file = NULL;
118
119
  /* Application DF (5015) acls */
120
1.04k
  sc_file_dup(&tmp_file, profile->df_info->file);
121
1.04k
  if (tmp_file == NULL)
122
1.04k
    LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot duplicate Application DF file");
123
1.04k
  r = sc_pkcs15init_fixup_file(profile, p15card, tmp_file);
124
1.04k
  if (r < 0)
125
2
    sc_file_free(tmp_file);
126
1.04k
  LOG_TEST_RET(ctx, r, "Application DF fixup failed");
127
128
  /* AC 'Create DF' and 'Create EF' */
129
1.04k
  *(data + 5) = 0x00; /* 'NONE' */
130
1.04k
  entry = sc_file_get_acl_entry(tmp_file, SC_AC_OP_CREATE);
131
1.04k
  if (entry->method == SC_AC_CHV)
132
103
    *(data + 5) = entry->key_ref | (entry->key_ref << 4); /* 'CHVx' */
133
940
  else if (entry->method == SC_AC_NEVER)
134
29
    *(data + 5) = 0xFF; /* 'NEVER'. */
135
136
  /* AC 'Self delete' */
137
1.04k
  *(data + 6) = 0x0F; /* 'NONE' */
138
1.04k
  entry = sc_file_get_acl_entry(tmp_file, SC_AC_OP_DELETE);
139
1.04k
  if (entry->method == SC_AC_CHV)
140
123
    *(data + 6) = (entry->key_ref << 4) | 0xF; /* 'CHVx' */
141
920
  else if (entry->method == SC_AC_NEVER)
142
4
    *(data + 6) = 0xFF; /* 'NEVER'. */
143
1.04k
  *(data + 7) = 0xFF;
144
145
1.04k
  sc_file_free(tmp_file);
146
1.04k
  LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
147
1.04k
}
148
149
/*
150
 * Erase the card.
151
 */
152
static int
153
1.06k
myeid_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card) {
154
1.06k
  struct sc_context *ctx = p15card->card->ctx;
155
1.06k
  struct sc_cardctl_myeid_data_obj data_obj;
156
1.06k
  struct sc_file *mf = NULL;
157
1.06k
  unsigned char data[8];
158
1.06k
  int r;
159
160
1.06k
  LOG_FUNC_CALLED(ctx);
161
162
1.06k
  r = myeid_get_init_applet_data(profile, p15card, data, sizeof (data));
163
1.06k
  LOG_TEST_RET(ctx, r, "Get init applet date error");
164
165
  /* Select parent DF and verify PINs/key as necessary */
166
1.04k
  r = sc_select_file(p15card->card, sc_get_mf_path(), &mf);
167
1.04k
  LOG_TEST_RET(ctx, r, "Cannot select MF");
168
169
  /* ACLs are not actives if file is not in the operational state */
170
30
  if (mf->status == SC_FILE_STATUS_ACTIVATED)
171
16
    r = sc_pkcs15init_authenticate(profile, p15card, mf, SC_AC_OP_DELETE);
172
30
  if (r < 0)
173
2
    sc_file_free(mf);
174
30
  LOG_TEST_RET(ctx, r, "'DELETE' authentication failed on MF");
175
176
28
  data_obj.P1 = 0x01;
177
28
  data_obj.P2 = 0xE0;
178
28
  data_obj.Data = data;
179
28
  data_obj.DataLen = sizeof (data);
180
181
28
  r = sc_card_ctl(p15card->card, SC_CARDCTL_MYEID_PUTDATA, &data_obj);
182
28
  sc_file_free(mf);
183
184
28
  LOG_FUNC_RETURN(p15card->card->ctx, r);
185
28
}
186
187
188
189
static int
190
myeid_init_card(sc_profile_t *profile,
191
509
    sc_pkcs15_card_t *p15card) {
192
509
  struct sc_path path;
193
509
  struct sc_file *file = NULL;
194
509
  u8 rbuf[256];
195
509
  int r;
196
197
509
  LOG_FUNC_CALLED(p15card->card->ctx);
198
199
509
  p15card->tokeninfo->flags = SC_PKCS15_TOKEN_PRN_GENERATION | SC_PKCS15_TOKEN_EID_COMPLIANT;
200
201
509
  _add_supported_algo(profile, p15card, NULL, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_ECB, &id_aes128_ecb);
202
509
  _add_supported_algo(profile, p15card, NULL, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_CBC, &id_aes128_cbc);
203
509
  _add_supported_algo(profile, p15card, NULL, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_ECB, &id_aes256_ecb);
204
509
  _add_supported_algo(profile, p15card, NULL, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_CBC, &id_aes256_cbc);
205
206
509
  r = sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &rbuf);
207
509
  LOG_TEST_RET(p15card->card->ctx, r,  "Get applet info failed");
208
209
332
  sc_format_path("3F00", &path);
210
332
  r = sc_select_file(p15card->card, &path, &file);
211
212
332
  sc_file_free(file);
213
214
332
  LOG_FUNC_RETURN(p15card->card->ctx, r);
215
332
}
216
217
/*
218
 * Create a DF
219
 */
220
static int
221
329
myeid_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df) {
222
329
  struct sc_context *ctx = NULL;
223
329
  struct sc_file *file = NULL;
224
329
  int r = 0, ii;
225
329
  static const char *create_dfs[] = {
226
329
    "PKCS15-PrKDF",
227
329
    "PKCS15-PuKDF",
228
329
    "PKCS15-SKDF",
229
329
    "PKCS15-CDF",
230
329
    "PKCS15-CDF-TRUSTED",
231
329
    "PKCS15-DODF",
232
329
    NULL
233
329
  };
234
235
329
  static const int create_dfs_val[] = {
236
329
    SC_PKCS15_PRKDF,
237
329
    SC_PKCS15_PUKDF,
238
329
    SC_PKCS15_SKDF,
239
329
    SC_PKCS15_CDF,
240
329
    SC_PKCS15_CDF_TRUSTED,
241
329
    SC_PKCS15_DODF
242
329
  };
243
244
329
  if (!profile || !p15card || !p15card->card || !df)
245
0
    return SC_ERROR_INVALID_ARGUMENTS;
246
247
329
  ctx = p15card->card->ctx;
248
329
  LOG_FUNC_CALLED(ctx);
249
329
  sc_log(ctx, "id (%x)", df->id);
250
251
329
  if (df->id == 0x5015) {
252
299
    sc_log(ctx, "Select (%x)", df->id);
253
299
    r = sc_select_file(p15card->card, &df->path, NULL);
254
255
1.32k
    for (ii = 0; create_dfs[ii]; ii++) {
256
1.18k
      sc_log(ctx, "Create '%s'", create_dfs[ii]);
257
258
1.18k
      file = NULL;
259
1.18k
      r = sc_profile_get_file(profile, create_dfs[ii], &file);
260
1.18k
      sc_file_free(file);
261
1.18k
      if (r) {
262
12
        sc_log(ctx, "Inconsistent profile: cannot find %s", create_dfs[ii]);
263
12
        LOG_FUNC_RETURN(ctx, SC_ERROR_INCONSISTENT_PROFILE);
264
12
      }
265
266
1.17k
      r = sc_pkcs15init_add_object(p15card, profile, create_dfs_val[ii], NULL);
267
268
1.17k
      if (r != SC_ERROR_FILE_ALREADY_EXISTS)
269
1.17k
        LOG_TEST_RET(ctx, r, "Failed to create MyEID xDF file");
270
1.17k
    }
271
299
  }
272
273
176
  LOG_FUNC_RETURN(p15card->card->ctx, r);
274
176
}
275
276
/*
277
 * Select the PIN reference
278
 */
279
static int
280
myeid_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
281
1.46k
    sc_pkcs15_auth_info_t *auth_info) {
282
1.46k
  SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
283
284
1.46k
  if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
285
0
    return SC_ERROR_OBJECT_NOT_VALID;
286
287
1.46k
  if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) {
288
297
    sc_log(p15card->card->ctx,
289
297
        "PIN_FLAG_SO_PIN, ref (%d), tries_left (%d)",
290
297
        auth_info->attrs.pin.reference, auth_info->tries_left);
291
1.16k
  } else {
292
1.16k
    sc_log(p15card->card->ctx,
293
1.16k
        "PIN_FLAG_PIN, ref (%d), tries_left (%d)",
294
1.16k
        auth_info->attrs.pin.reference, auth_info->tries_left);
295
296
1.16k
  }
297
298
1.46k
  if (auth_info->attrs.pin.reference <= 0 || auth_info->attrs.pin.reference > MYEID_MAX_PINS)
299
1.14k
    auth_info->attrs.pin.reference = 1;
300
301
1.46k
  LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
302
1.46k
}
303
304
/*
305
 * Create a new PIN
306
 */
307
static int
308
myeid_create_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
309
    struct sc_file *df, struct sc_pkcs15_object *pin_obj,
310
    const unsigned char *pin, size_t pin_len,
311
958
    const unsigned char *puk, size_t puk_len) {
312
958
  struct sc_context *ctx = p15card->card->ctx;
313
958
  unsigned char data[20];
314
958
  struct sc_cardctl_myeid_data_obj data_obj;
315
958
  struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *) pin_obj->data;
316
958
  struct sc_pkcs15_auth_info puk_ainfo = {0};
317
958
  int r;
318
319
958
  LOG_FUNC_CALLED(ctx);
320
958
  sc_log(ctx,
321
958
         "PIN('%s',ref:%i,flags:0x%X,pin_len:%"SC_FORMAT_LEN_SIZE_T"u,puk_len:%"SC_FORMAT_LEN_SIZE_T"u)\n",
322
958
         pin_obj->label, auth_info->attrs.pin.reference,
323
958
         auth_info->attrs.pin.flags, pin_len, puk_len);
324
325
958
  if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
326
0
    return SC_ERROR_OBJECT_NOT_VALID;
327
958
  if (auth_info->attrs.pin.reference >= MYEID_MAX_PINS)
328
1
    return SC_ERROR_INVALID_ARGUMENTS;
329
957
  if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4)
330
1
    return SC_ERROR_INVALID_PIN_LENGTH;
331
332
956
  sc_profile_get_pin_info(profile, (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN)
333
956
      ? SC_PKCS15INIT_SO_PUK : SC_PKCS15INIT_USER_PUK,
334
956
      &puk_ainfo);
335
336
956
  memset(data, 0, sizeof (data));
337
  /* Make command to add a pin-record */
338
956
  data_obj.P1 = 0x01;
339
956
  data_obj.P2 = auth_info->attrs.pin.reference; /* myeid pin number */
340
341
956
  memset(data, auth_info->attrs.pin.pad_char, 8);
342
956
  memcpy(&data[0], (u8 *) pin, pin_len); /* copy pin */
343
344
956
  memset(&data[8], puk_ainfo.attrs.pin.pad_char, 8);
345
956
  memcpy(&data[8], (u8 *) puk, puk_len); /* copy puk */
346
347
956
  if (auth_info->tries_left > 0 && auth_info->tries_left < 15)
348
913
    data[16] = auth_info->tries_left;
349
43
  else
350
43
    data[16] = 5; /* default value */
351
352
956
  if (puk_ainfo.tries_left > 0 && puk_ainfo.tries_left < 15)
353
947
    data[17] = puk_ainfo.tries_left;
354
9
  else
355
9
    data[17] = 5; /* default value */
356
357
956
  data[18] = 0x00;
358
359
956
  data_obj.Data = data;
360
956
  data_obj.DataLen = 19;
361
362
956
  r = sc_card_ctl(p15card->card, SC_CARDCTL_MYEID_PUTDATA, &data_obj);
363
956
  LOG_TEST_RET(ctx, r, "Initialize PIN failed");
364
365
379
  LOG_FUNC_RETURN(ctx, r);
366
379
}
367
368
/*
369
 * Setup file struct & path: get correct template from the profile, construct full path
370
 * num = number of objects of this type already on the card
371
 */
372
static int
373
myeid_new_file(sc_profile_t *profile, sc_card_t *card,
374
    unsigned int type, unsigned int num,
375
4.21k
    sc_file_t **out) {
376
4.21k
  sc_file_t *file;
377
4.21k
  sc_path_t *p;
378
4.21k
  char name[64];
379
4.21k
  const char *tag = NULL;
380
4.21k
  int r;
381
382
4.21k
  LOG_FUNC_CALLED(card->ctx);
383
4.21k
  switch (type) {
384
590
  case SC_PKCS15_TYPE_PRKEY_RSA:
385
1.14k
  case SC_PKCS15_TYPE_PRKEY_EC:
386
1.14k
    tag = "private-key";
387
1.14k
    break;
388
0
  case SC_PKCS15_TYPE_PUBKEY_RSA:
389
0
  case SC_PKCS15_TYPE_PUBKEY_EC:
390
0
    tag = "public-key";
391
0
    break;
392
1.02k
  case SC_PKCS15_TYPE_SKEY_GENERIC:
393
2.05k
  case SC_PKCS15_TYPE_SKEY_DES:
394
3.07k
  case SC_PKCS15_TYPE_SKEY_3DES:
395
3.07k
    tag = "secret-key";
396
3.07k
    break;
397
0
  default:
398
0
    if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_CERT)
399
0
      tag = "certificate";
400
0
    else if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_DATA_OBJECT)
401
0
      tag = "data";
402
0
    break;
403
4.21k
  }
404
405
4.21k
  if (!tag) {
406
0
    sc_log(card->ctx, "Unsupported file type");
407
0
    return SC_ERROR_INVALID_ARGUMENTS;
408
0
  }
409
410
  /* Get template from profile  */
411
4.21k
  snprintf(name, sizeof (name), "template-%s", tag);
412
4.21k
  if (sc_profile_get_file(profile, name, &file) < 0) {
413
3.05k
    sc_log(card->ctx, "Profile doesn't define %s", name);
414
3.05k
    return SC_ERROR_NOT_SUPPORTED;
415
3.05k
  }
416
417
  /* Auto-increment FID for next object */
418
1.16k
  file->id += num;
419
1.16k
  p = &file->path;
420
1.16k
  *p = profile->df_info->file->path;
421
1.16k
  if (p->len >= SC_MAX_PATH_SIZE - 2) {
422
12
    sc_log(card->ctx, "Wrong path length");
423
12
    sc_file_free(file);
424
12
    return SC_ERROR_INTERNAL;
425
12
  }
426
1.14k
  p->value[p->len++] = (u8) (file->id / 256);
427
1.14k
  p->value[p->len++] = (u8) (file->id % 256);
428
429
  /* Increment FID until there's no file with such path */
430
1.14k
  r = sc_select_file(card, p, NULL);
431
3.12k
  while (r == 0) {
432
1.97k
    file->id++;
433
1.97k
    p->value[p->len - 2] = (u8) (file->id / 256);
434
1.97k
    p->value[p->len - 1] = (u8) (file->id % 256);
435
1.97k
    r = sc_select_file(card, p, NULL);
436
1.97k
  }
437
438
1.14k
  *out = file;
439
1.14k
  LOG_FUNC_RETURN(card->ctx, 0);
440
1.14k
}
441
442
static int
443
myeid_encode_private_key(sc_profile_t *profile, sc_card_t *card,
444
    struct sc_pkcs15_prkey_rsa *rsa, u8 *key,
445
0
    size_t *keysize, int key_ref) {
446
0
  LOG_FUNC_CALLED(card->ctx);
447
0
  LOG_FUNC_RETURN(card->ctx, 0);
448
0
}
449
450
static int
451
myeid_encode_public_key(sc_profile_t *profile, sc_card_t *card,
452
    struct sc_pkcs15_prkey_rsa *rsa, u8 *key,
453
0
    size_t *keysize, int key_ref) {
454
0
  LOG_FUNC_CALLED(card->ctx);
455
0
  LOG_FUNC_RETURN(card->ctx, 0);
456
0
}
457
458
/*
459
 * Add AlgorithmInfo of a supported algorithm to supportedAlgorithms field in tokenInfo. If object != NULL,
460
 * add reference to the algorithmInfo to the passed object.
461
 */
462
static void
463
_add_supported_algo(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object,
464
        unsigned operations, unsigned mechanism, const struct sc_object_id *oid)
465
4.09k
{
466
4.09k
  struct sc_supported_algo_info *algo;
467
4.09k
  struct sc_context *ctx = p15card->card->ctx;
468
4.09k
  if (oid == NULL) {
469
0
    sc_log(ctx, "Failed to add algorithms refs - invalid arguments.");
470
0
    return;
471
0
  }
472
4.09k
  algo = sc_pkcs15_get_specific_supported_algo(p15card, operations, mechanism, oid);
473
4.09k
  int rv;
474
475
4.09k
  LOG_FUNC_CALLED(ctx);
476
4.09k
  if (!algo) {
477
4.02k
    unsigned ref = 1, ii;
478
479
8.43k
    for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference; ii++)
480
4.41k
      if (p15card->tokeninfo->supported_algos[ii].reference >= ref)
481
4.33k
        ref = p15card->tokeninfo->supported_algos[ii].reference + 1;
482
4.02k
    if (ii < SC_MAX_SUPPORTED_ALGORITHMS) {
483
4.02k
      algo = &p15card->tokeninfo->supported_algos[ii];
484
4.02k
      algo->reference = ref;
485
4.02k
      algo->mechanism = mechanism;
486
4.02k
      algo->operations = operations;
487
4.02k
      algo->algo_id = *oid;
488
4.02k
      profile->dirty = 1;
489
4.02k
      profile->pkcs15.do_last_update = 1;
490
4.02k
    }
491
492
4.02k
  }
493
4.09k
  if (object != NULL)
494
2.05k
    rv = sc_pkcs15_add_supported_algo_ref(object, algo);
495
2.03k
  else
496
2.03k
    rv = SC_SUCCESS;
497
498
4.09k
  if (rv != SC_SUCCESS) {
499
0
    sc_log(ctx, "Failed to add algorithms refs");
500
0
  }
501
4.09k
}
502
503
static void
504
myeid_fixup_supported_algos(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object)
505
4.21k
{
506
4.21k
  struct sc_context *ctx = p15card->card->ctx;
507
4.21k
  struct sc_pkcs15_skey_info *skey_info = (struct sc_pkcs15_skey_info *) object->data;
508
509
4.21k
  LOG_FUNC_CALLED(ctx);
510
4.21k
  switch (object->type) {
511
1.02k
  case SC_PKCS15_TYPE_SKEY_GENERIC:
512
1.02k
    switch (skey_info->key_type | (skey_info->value_len << 16)) {
513
1.02k
    case CKK_AES | (128 << 16):
514
1.02k
      _add_supported_algo(profile, p15card, object, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_ECB, &id_aes128_ecb);
515
1.02k
      _add_supported_algo(profile, p15card, object, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_CBC, &id_aes128_cbc);
516
1.02k
      break;
517
0
    case CKK_AES | (256 << 16):
518
0
      _add_supported_algo(profile, p15card, object, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_ECB, &id_aes256_ecb);
519
0
      _add_supported_algo(profile, p15card, object, SC_PKCS15_ALGO_OP_DECIPHER|SC_PKCS15_ALGO_OP_ENCIPHER, CKM_AES_CBC, &id_aes256_cbc);
520
0
      break;
521
1.02k
    }
522
1.02k
    break;
523
4.21k
  }
524
4.21k
}
525
526
527
/*
528
 * Create a private key file
529
 */
530
static int
531
myeid_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
532
4.21k
    struct sc_pkcs15_object *object) {
533
4.21k
  struct sc_context *ctx = p15card->card->ctx;
534
4.21k
  struct sc_card *card = p15card->card;
535
4.21k
  struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *) object->data;
536
4.21k
  struct sc_pkcs15_skey_info *skey_info = (struct sc_pkcs15_skey_info *) object->data;
537
4.21k
  struct sc_pkcs15_id *id;
538
4.21k
  struct sc_path *path;
539
4.21k
  int *key_reference;
540
4.21k
  struct sc_file *file = NULL;
541
4.21k
  struct sc_pkcs15_object *pin_object = NULL;
542
4.21k
  struct sc_pkcs15_auth_info *pkcs15_auth_info = NULL;
543
4.21k
  unsigned char sec_attrs[] = {0xFF, 0xFF, 0xFF};
544
4.21k
  int r, ef_structure = 0, pin_reference = -1;
545
4.21k
  size_t keybits = 0;
546
4.21k
  unsigned char prop_info[] = {0x00, 0x00};
547
4.21k
  int extractable = FALSE;
548
549
4.21k
  LOG_FUNC_CALLED(card->ctx);
550
551
4.21k
  switch (object->type) {
552
590
    case SC_PKCS15_TYPE_PRKEY_RSA:
553
590
      ef_structure = SC_CARDCTL_MYEID_KEY_RSA;
554
590
      keybits = prkey_info->modulus_length;
555
590
      break;
556
551
    case SC_PKCS15_TYPE_PRKEY_EC:
557
551
      ef_structure = SC_CARDCTL_MYEID_KEY_EC;
558
551
      keybits = prkey_info->field_length;
559
551
      break;
560
1.02k
    case SC_PKCS15_TYPE_SKEY_DES:
561
2.05k
    case SC_PKCS15_TYPE_SKEY_3DES:
562
2.05k
      ef_structure = SC_CARDCTL_MYEID_KEY_DES;
563
2.05k
      keybits = skey_info->value_len;
564
2.05k
      if ((skey_info->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) == SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE)
565
2.05k
        extractable = TRUE;
566
2.05k
      break;
567
1.02k
    case SC_PKCS15_TYPE_SKEY_GENERIC:
568
1.02k
      keybits = skey_info->value_len;
569
1.02k
      if ((skey_info->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE) == SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE)
570
1.02k
        extractable = TRUE;
571
1.02k
      switch (skey_info->key_type) {
572
1.02k
      case CKK_AES:
573
1.02k
        ef_structure = SC_CARDCTL_MYEID_KEY_AES;
574
1.02k
        break;
575
0
      case CKK_DES:
576
0
        ef_structure = SC_CARDCTL_MYEID_KEY_DES;
577
0
        break;
578
0
      default:
579
0
        if (object->type == SC_PKCS15_TYPE_SKEY_GENERIC)
580
0
          ef_structure = SC_CARDCTL_MYEID_KEY_GENERIC_SECRET;
581
0
        break;
582
1.02k
      }
583
1.02k
      break;
584
4.21k
  }
585
4.21k
  if (!ef_structure) {
586
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS,
587
0
        "Unsupported key type");
588
0
  }
589
590
4.21k
  myeid_fixup_supported_algos(profile, p15card, object);
591
592
4.21k
  if ((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY) {
593
1.14k
    id = &prkey_info->id;
594
1.14k
    path = &prkey_info->path;
595
1.14k
    key_reference = &prkey_info->key_reference;
596
3.07k
  } else {
597
3.07k
    id = &skey_info->id;
598
3.07k
    path = &skey_info->path;
599
3.07k
    key_reference = &skey_info->key_reference;
600
3.07k
  }
601
602
4.21k
  sc_log(ctx, "create MyEID key ID:%s", sc_pkcs15_print_id(id));
603
604
  /* Get the private key file */
605
4.21k
  r = myeid_new_file(profile, card, object->type, *key_reference, &file);
606
4.21k
  LOG_TEST_RET(ctx, r, "Cannot get new MyEID key file");
607
608
1.14k
  if (!file || !file->path.len || file->path.len > SC_MAX_PATH_SIZE) {
609
0
    sc_file_free(file);
610
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Cannot determine key file");
611
0
  }
612
613
1.14k
  sc_log(ctx, "Key file size %zu", keybits);
614
1.14k
  file->size = keybits;
615
1.14k
  file->ef_structure = ef_structure;
616
617
1.14k
  memcpy(path->value, &file->path.value, file->path.len);
618
1.14k
  *key_reference = file->path.value[file->path.len - 1] & 0xFF;
619
620
1.14k
  sc_log(ctx, "Path of MyEID key file to create %s",
621
1.14k
      sc_print_path(&file->path));
622
623
1.14k
  if (object->auth_id.len >= 1) {
624
1.14k
    r = sc_pkcs15_find_pin_by_auth_id(p15card, &object->auth_id, &pin_object);
625
626
1.14k
    if (r != SC_SUCCESS)
627
265
      sc_file_free(file);
628
1.14k
    LOG_TEST_RET(ctx, r, "Failed to get pin object by auth_id");
629
630
883
    if (pin_object->type != SC_PKCS15_TYPE_AUTH_PIN) {
631
0
      sc_file_free(file);
632
0
      LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_VALID, "Invalid object returned when locating pin object.");
633
0
    }
634
635
883
    pkcs15_auth_info =  (struct sc_pkcs15_auth_info*) pin_object->data;
636
637
883
    if (pkcs15_auth_info == NULL || pkcs15_auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) {
638
0
      sc_file_free(file);
639
0
      LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_VALID, "NULL or invalid sc_pkcs15_auth_info in pin object");
640
0
    }
641
642
883
    pin_reference = pkcs15_auth_info->attrs.pin.reference;
643
644
883
    if (pin_reference >= 1 && pin_reference < MYEID_MAX_PINS) {
645
295
      sec_attrs[0] = (pin_reference << 4 | (pin_reference & 0x0F));
646
295
      sec_attrs[1] = (pin_reference << 4 | (pin_reference & 0x0F));
647
295
      sc_file_set_sec_attr(file, sec_attrs, sizeof(sec_attrs));
648
295
    }
649
883
  }
650
0
  else {
651
0
    sc_file_free(file);
652
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid AuthID value for a private key.");
653
0
  }
654
655
  /* TODO: fill all proprietary attributes here based on the object */
656
657
883
  if (object->user_consent != 0 && pin_reference >= 1)
658
0
      prop_info[0] |= (pin_reference << 4);
659
660
883
  if (extractable)
661
591
      prop_info[1] |= MYEID_PROP_INFO_2_EXCTRACTABLE;
662
663
883
  if (object->session_object != 0) /* Object will be removed during next reset. */
664
0
    prop_info[1] |= MYEID_PROP_INFO_2_SESSION_OBJECT;
665
666
  /* TODO: add other flags, like CKA_TRUSTED and CKA_WRAP_WITH_TRUSTED */
667
668
883
  r = sc_file_set_prop_attr(file, prop_info, 2);
669
883
  LOG_TEST_RET(ctx, r, "Cannot create MyEID key file");
670
671
  /* Now create the key file */
672
883
  r = sc_pkcs15init_create_file(profile, p15card, file);
673
883
  sc_file_free(file);
674
883
  LOG_TEST_RET(ctx, r, "Cannot create MyEID key file");
675
676
328
  LOG_FUNC_RETURN(ctx, r);
677
328
}
678
679
/*
680
 * Store a private key
681
 */
682
static int
683
myeid_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
684
    struct sc_pkcs15_object *object,
685
177
    struct sc_pkcs15_prkey *prkey) {
686
177
  struct sc_context *ctx = p15card->card->ctx;
687
177
  struct sc_card *card = p15card->card;
688
177
  struct sc_cardctl_myeid_gen_store_key_info args;
689
177
  struct sc_file *file = NULL;
690
177
  struct sc_pkcs15_id *id;
691
177
  struct sc_path *path;
692
177
  int r;
693
694
177
  LOG_FUNC_CALLED(ctx);
695
696
177
  if ((object->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY) {
697
0
    struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *) object->data;
698
0
    id = &prkey_info->id;
699
0
    path = &prkey_info->path;
700
177
  } else {
701
177
    struct sc_pkcs15_skey_info *skey_info = (struct sc_pkcs15_skey_info *) object->data;
702
177
    id = &skey_info->id;
703
177
    path = &skey_info->path;
704
177
  }
705
706
177
  sc_log(ctx, "store MyEID key with ID:%s and path:%s",
707
177
      sc_pkcs15_print_id(id), sc_print_path(path));
708
709
177
  r = sc_select_file(card, path, &file);
710
177
  LOG_TEST_RET(ctx, r, "Cannot store MyEID key: select key file failed");
711
712
111
  r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
713
111
  sc_file_free(file);
714
111
  LOG_TEST_RET(ctx, r, "No authorisation to store MyEID private key");
715
716
  /* Fill in data structure */
717
95
  memset(&args, 0, sizeof (args));
718
719
95
  args.op_type = OP_TYPE_STORE;
720
721
95
  switch (object->type) {
722
0
  case SC_PKCS15_TYPE_PRKEY_RSA:
723
0
    args.key_type = SC_CARDCTL_MYEID_KEY_RSA;
724
0
    args.pubexp_len = prkey->u.rsa.exponent.len;
725
0
    args.pubexp = prkey->u.rsa.exponent.data;
726
0
    args.primep_len = prkey->u.rsa.p.len;
727
0
    args.primep = prkey->u.rsa.p.data;
728
0
    args.primeq_len = prkey->u.rsa.q.len;
729
0
    args.primeq = prkey->u.rsa.q.data;
730
731
0
    args.dp1_len = prkey->u.rsa.dmp1.len;
732
0
    args.dp1 = prkey->u.rsa.dmp1.data;
733
0
    args.dq1_len = prkey->u.rsa.dmq1.len;
734
0
    args.dq1 = prkey->u.rsa.dmq1.data;
735
0
    args.invq_len = prkey->u.rsa.iqmp.len;
736
0
    args.invq = prkey->u.rsa.iqmp.data;
737
738
    //args.key_len_bits = keybits;
739
0
    args.key_len_bits = prkey->u.rsa.modulus.len;
740
0
    args.mod = prkey->u.rsa.modulus.data;
741
0
    break;
742
0
  case SC_PKCS15_TYPE_PRKEY_EC:
743
0
    args.key_type = SC_CARDCTL_MYEID_KEY_EC;
744
0
    args.d = prkey->u.ec.privateD.data;
745
0
    args.d_len = prkey->u.ec.privateD.len;
746
0
    args.ecpublic_point = prkey->u.ec.ecpointQ.value;
747
0
    args.ecpublic_point_len = prkey->u.ec.ecpointQ.len;
748
0
    args.key_len_bits = prkey->u.ec.params.field_length;
749
0
    break;
750
38
  case SC_PKCS15_TYPE_SKEY_GENERIC:
751
76
  case SC_PKCS15_TYPE_SKEY_DES:
752
76
  case SC_PKCS15_TYPE_SKEY_2DES:
753
95
  case SC_PKCS15_TYPE_SKEY_3DES:
754
95
    switch (prkey->algorithm) {
755
38
    case SC_ALGORITHM_AES:
756
38
      args.key_type = SC_CARDCTL_MYEID_KEY_AES;
757
38
      break;
758
38
    case SC_ALGORITHM_DES:
759
38
      args.key_type = SC_CARDCTL_MYEID_KEY_DES;
760
38
      break;
761
95
    }
762
95
    args.d = prkey->u.secret.data;
763
95
    args.d_len = prkey->u.secret.data_len;
764
95
    break;
765
95
  }
766
  /* Store RSA key  */
767
95
  r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_STORE_KEY, &args);
768
95
  LOG_TEST_RET(ctx, r, "Card control 'MYEID_GENERATE_STORE_KEY' failed");
769
770
81
  LOG_FUNC_RETURN(ctx, r);
771
81
}
772
773
static int
774
myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
775
    struct sc_pkcs15_object *object,
776
151
    struct sc_pkcs15_pubkey *pubkey) {
777
151
  struct sc_context *ctx = p15card->card->ctx;
778
151
  struct sc_card *card = p15card->card;
779
151
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data;
780
151
  struct sc_cardctl_myeid_gen_store_key_info args;
781
151
  struct sc_file *file = NULL;
782
151
  int r;
783
151
  unsigned int cla,tag;
784
151
  size_t taglen;
785
151
  unsigned int keybits = (unsigned int)key_info->modulus_length;
786
151
  u8 raw_pubkey[MYEID_MAX_RSA_KEY_LEN / 8];
787
151
  u8* dataptr;
788
789
151
  LOG_FUNC_CALLED(ctx);
790
151
  if (object->type != SC_PKCS15_TYPE_PRKEY_RSA && object->type != SC_PKCS15_TYPE_PRKEY_EC)
791
151
    LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Generate key failed: only RSA and EC supported");
792
793
  /* Check that the card supports the requested modulus length */
794
151
  switch (object->type) {
795
80
    case SC_PKCS15_TYPE_PRKEY_RSA:
796
80
      if (sc_card_find_rsa_alg(p15card->card, keybits) == NULL)
797
80
        LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported RSA key size");
798
80
      break;
799
80
    case SC_PKCS15_TYPE_PRKEY_EC:
800
      /* EC is supported in MyEID v > 3.5. TODO: set correct return value if older MyEID version. */
801
      /* Here the information about curve is not available, that's why supported algorithm is checked
802
         without curve OID. */
803
804
71
      if(key_info->field_length != 0)
805
71
        keybits = (unsigned int)key_info->field_length;
806
0
      else
807
0
        key_info->field_length = keybits;
808
809
71
      if (sc_card_find_ec_alg(p15card->card, keybits, NULL) == NULL)
810
71
        LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported EC key size");
811
812
71
      break;
813
71
    default:
814
0
      LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported key type");
815
151
  }
816
817
151
  sc_log(ctx, "Generate key with ID:%s and path:%s",
818
151
      sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path));
819
820
151
  r = sc_select_file(card, &key_info->path, &file);
821
151
  LOG_TEST_RET(ctx, r, "Cannot generate key: failed to select key file");
822
823
116
  r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_GENERATE);
824
116
  if (r < 0)
825
5
    sc_file_free(file);
826
116
  LOG_TEST_RET(ctx, r, "No authorisation to generate private key");
827
828
  /* Fill in data structure */
829
111
  memset(&args, 0, sizeof (args));
830
111
  args.key_len_bits = keybits;
831
111
  args.op_type = OP_TYPE_GENERATE;
832
111
  if (object->type == SC_PKCS15_TYPE_PRKEY_RSA) {
833
57
    args.key_type = SC_CARDCTL_MYEID_KEY_RSA;
834
57
    args.pubexp_len = MYEID_DEFAULT_PUBKEY_LEN;
835
57
    args.pubexp = MYEID_DEFAULT_PUBKEY;
836
57
  } else if (object->type == SC_PKCS15_TYPE_PRKEY_EC) {
837
54
    args.key_type = SC_CARDCTL_MYEID_KEY_EC;
838
54
  }
839
840
  /* Generate the key  */
841
111
  r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_STORE_KEY, &args);
842
111
  if (r < 0)
843
11
    sc_file_free(file);
844
111
  LOG_TEST_RET(ctx, r, "Card control 'MYEID_GENERATE_STORE_KEY' failed");
845
846
  /* Key pair generation -> collect public key info */
847
100
  if (pubkey != NULL) {
848
100
    struct sc_cardctl_myeid_data_obj data_obj;
849
850
100
    if (object->type == SC_PKCS15_TYPE_PRKEY_RSA) {
851
49
      pubkey->algorithm = SC_ALGORITHM_RSA;
852
49
      pubkey->u.rsa.modulus.len = BYTES4BITS(keybits);
853
49
      pubkey->u.rsa.modulus.data = malloc(pubkey->u.rsa.modulus.len);
854
49
      pubkey->u.rsa.exponent.len = MYEID_DEFAULT_PUBKEY_LEN;
855
49
      pubkey->u.rsa.exponent.data = malloc(MYEID_DEFAULT_PUBKEY_LEN);
856
49
      memcpy(pubkey->u.rsa.exponent.data, MYEID_DEFAULT_PUBKEY, MYEID_DEFAULT_PUBKEY_LEN);
857
858
      /* Get public key modulus */
859
49
      r = sc_select_file(card, &file->path, NULL);
860
49
      sc_file_free(file);
861
49
      file = NULL;
862
49
      LOG_TEST_RET(ctx, r, "Cannot get key modulus: select key file failed");
863
864
44
      data_obj.P1 = 0x01;
865
44
      data_obj.P2 = 0x01;
866
44
      data_obj.Data = raw_pubkey;
867
44
      data_obj.DataLen = sizeof (raw_pubkey);
868
869
44
      r = sc_card_ctl(card, SC_CARDCTL_MYEID_GETDATA, &data_obj);
870
44
      LOG_TEST_RET(ctx, r, "Cannot get RSA key modulus: 'MYEID_GETDATA' failed");
871
872
36
      if ((data_obj.DataLen * 8) != key_info->modulus_length)
873
36
        LOG_TEST_RET(ctx, SC_ERROR_PKCS15INIT, "Cannot get RSA key modulus: invalid key-size");
874
875
13
      memcpy(pubkey->u.rsa.modulus.data, raw_pubkey, pubkey->u.rsa.modulus.len);
876
13
    }
877
51
    else if (object->type == SC_PKCS15_TYPE_PRKEY_EC) {
878
51
      struct sc_ec_parameters *ecparams = (struct sc_ec_parameters *)key_info->params.data;
879
880
51
      sc_log(ctx,
881
51
             "curve '%s', len %"SC_FORMAT_LEN_SIZE_T"u, oid '%s'",
882
51
             ecparams->named_curve, ecparams->field_length,
883
51
             sc_dump_oid(&(ecparams->id)));
884
51
      pubkey->algorithm = SC_ALGORITHM_EC;
885
886
51
      r = sc_select_file(card, &file->path, NULL);
887
51
      sc_file_free(file);
888
51
      file = NULL;
889
51
      LOG_TEST_RET(ctx, r, "Cannot get public key: select key file failed");
890
891
49
      data_obj.P1 = 0x01;
892
49
      data_obj.P2 = 0x86; /* Get public EC key (Q) */
893
49
      data_obj.Data = raw_pubkey;
894
49
      data_obj.DataLen = sizeof (raw_pubkey);
895
896
49
      r = sc_card_ctl(card, SC_CARDCTL_MYEID_GETDATA, &data_obj);
897
49
      LOG_TEST_RET(ctx, r, "Cannot get EC public key: 'MYEID_GETDATA' failed");
898
899
42
      dataptr = data_obj.Data;
900
42
      r = sc_asn1_read_tag((const u8 **)&dataptr, data_obj.DataLen, &cla, &tag, &taglen);
901
42
      if (dataptr == NULL)
902
11
        r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
903
42
      LOG_TEST_RET(ctx, r, "Invalid EC public key data. Cannot parse DER structure.");
904
905
31
      if (taglen == 0)
906
31
          LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
907
908
30
      if (pubkey->u.ec.ecpointQ.value)
909
0
        free(pubkey->u.ec.ecpointQ.value);
910
911
30
      pubkey->u.ec.ecpointQ.value = malloc(taglen);
912
913
30
      if (pubkey->u.ec.ecpointQ.value == NULL)
914
30
        LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
915
916
30
      memcpy(pubkey->u.ec.ecpointQ.value, dataptr, taglen);
917
30
      pubkey->u.ec.ecpointQ.len = taglen;
918
919
30
      if (pubkey->u.ec.params.named_curve)
920
30
        free(pubkey->u.ec.params.named_curve);
921
30
      pubkey->u.ec.params.named_curve = NULL;
922
30
      if (pubkey->u.ec.params.der.value)
923
30
        free(pubkey->u.ec.params.der.value);
924
30
      pubkey->u.ec.params.der.value = NULL;
925
30
      pubkey->u.ec.params.der.len = 0;
926
927
30
      pubkey->u.ec.params.named_curve = strdup(ecparams->named_curve);
928
30
      if (!pubkey->u.ec.params.named_curve) {
929
0
        free(pubkey->u.ec.ecpointQ.value);
930
0
        LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
931
0
      }
932
933
30
      r = sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params);
934
30
      if (r < 0)
935
0
        free(pubkey->u.ec.ecpointQ.value);
936
30
      LOG_TEST_RET(ctx, r, "Cannot fix EC parameters");
937
30
    }
938
100
  }
939
940
43
  sc_file_free(file);
941
942
43
  LOG_FUNC_RETURN(ctx, r);
943
43
}
944
945
/* Finish initialization. After this ACL is in affect */
946
1.06k
static int myeid_finalize_card(sc_card_t *card) {
947
1.06k
  LOG_FUNC_CALLED(card->ctx);
948
1.06k
  LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_MYEID_ACTIVATE_CARD, NULL));
949
1.06k
}
950
951
952
/*
953
 * Create a new PIN
954
 */
955
static struct sc_pkcs15init_operations sc_pkcs15init_myeid_operations = {
956
  myeid_erase_card,
957
  myeid_init_card, /* init_card */
958
  myeid_create_dir, /* create_dir */
959
  NULL, /* create_domain */
960
  myeid_select_pin_reference,
961
  myeid_create_pin,
962
  NULL, /* select_key_reference */
963
  myeid_create_key,
964
  myeid_store_key,
965
  myeid_generate_key,
966
  myeid_encode_private_key,
967
  myeid_encode_public_key,
968
  myeid_finalize_card,
969
  myeid_delete_object, /* delete_object */
970
  NULL, NULL, NULL, NULL, NULL, /* pkcs15init emulation */
971
  NULL /* sanity_check */
972
};
973
974
1.45k
struct sc_pkcs15init_operations *sc_pkcs15init_get_myeid_ops(void) {
975
1.45k
  return &sc_pkcs15init_myeid_operations;
976
1.45k
}