Coverage Report

Created: 2025-07-01 06:08

/src/opensc/src/pkcs15init/pkcs15-setcos.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * SetOCS 4.4 specific operations for PKCS15 initialization
3
 *
4
 * Copyright (C) 2003, 2005 Zetes
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 <stdlib.h>
24
#include <string.h>
25
#include <sys/types.h>
26
27
#include "libopensc/opensc.h"
28
#include "libopensc/cardctl.h"
29
#include "libopensc/internal.h"
30
#include "libopensc/log.h"
31
#include "pkcs15-init.h"
32
#include "profile.h"
33
34
0
#define SETCOS_MAX_PINS   7
35
36
static unsigned char SETCOS_DEFAULT_PUBKEY[] = {0x01, 0x00, 0x01};
37
0
#define SETCOS_DEFAULT_PUBKEY_LEN       sizeof(SETCOS_DEFAULT_PUBKEY)
38
39
static int setcos_create_pin_internal(sc_profile_t *, sc_pkcs15_card_t *,
40
  int, sc_pkcs15_auth_info_t *, const u8 *, size_t, const u8 *, size_t);
41
42
43
static int
44
setcos_puk_retries(sc_profile_t *profile, int pin_ref)
45
0
{
46
0
  sc_pkcs15_auth_info_t auth_info = {0};
47
48
0
  auth_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
49
0
  auth_info.attrs.pin.reference = 1; /* Default SO PIN ref. */
50
0
  sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &auth_info);
51
52
  /* If pin_ref is the SO PIN, get the SO PUK info, otherwise the User PUK info */
53
0
  sc_profile_get_pin_info(profile,
54
0
    pin_ref == auth_info.attrs.pin.reference ? SC_PKCS15INIT_SO_PUK : SC_PKCS15INIT_USER_PUK,
55
0
    &auth_info);
56
57
0
  if ((auth_info.tries_left < 0) || (auth_info.tries_left > 15))
58
0
    return 3; /* Little extra safety */
59
0
  return auth_info.tries_left;
60
0
}
61
62
63
/*
64
 * Erase the card.
65
 */
66
static int setcos_erase_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card)
67
0
{
68
0
  sc_path_t path;
69
0
  int r;
70
71
  /* Just delete the entire MF */
72
73
  /* Select parent DF and verify PINs/key as necessary */
74
0
  r = sc_pkcs15init_authenticate(profile, p15card, profile->mf_info->file, SC_AC_OP_DELETE);
75
0
  if (r < 0)
76
0
    return r == SC_ERROR_FILE_NOT_FOUND ? 0 : r;
77
78
  /* Empty path -> we have to to delete the current DF (= the MF) */
79
0
  memset(&path, 0, sizeof(sc_path_t));
80
0
  r = sc_delete_file(p15card->card, &path) ;
81
0
  if (r)
82
0
    return r;
83
84
0
  sc_free_apps(p15card->card);
85
0
  return 0;
86
0
}
87
88
89
/*
90
 * Create the MF and global pin file if they don't exist.
91
 */
92
static int
93
setcos_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card)
94
0
{
95
0
  struct sc_context *ctx = p15card->card->ctx;
96
0
  sc_file_t *mf = profile->mf_info->file;
97
0
  sc_file_t *pinfile;
98
0
  int r;
99
100
0
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
101
102
  /* Create the MF if it doesn't exist yet */
103
0
  r = sc_select_file(p15card->card, &mf->path, NULL);
104
0
  if (r == SC_ERROR_FILE_NOT_FOUND) {
105
0
    sc_log(ctx,  "MF doesn't exist, creating now");
106
107
    /* Fix up the file's ACLs */
108
0
    r = sc_pkcs15init_fixup_file(profile, p15card, mf);
109
0
    LOG_TEST_RET(ctx, r, "MF fixup failed");
110
111
0
    mf->status = SC_FILE_STATUS_CREATION;
112
0
    r = sc_create_file(p15card->card, mf);
113
0
    LOG_TEST_RET(ctx, r, "MF creation failed");
114
0
  }
115
0
  LOG_TEST_RET(ctx, r, "Cannot select MF");
116
117
  /* Create the global pin file if it doesn't exist yet */
118
0
  r = sc_profile_get_file(profile, "pinfile", &pinfile);
119
0
  LOG_TEST_RET(ctx, r, "Cannot get 'pinfile' from profile");
120
121
0
  r = sc_select_file(p15card->card, &pinfile->path, NULL);
122
0
  if (r == SC_ERROR_FILE_NOT_FOUND) {
123
0
    sc_log(ctx,  "Global pin file doesn't exist, creating now");
124
125
    /* Fix up the file's ACLs */
126
0
    r = sc_pkcs15init_fixup_file(profile, p15card, pinfile);
127
0
    if (r < 0)
128
0
      sc_file_free(pinfile);
129
0
    LOG_TEST_RET(ctx, r, "Pinfile fixup failed");
130
131
    /* Set life cycle state to SC_FILE_STATUS_CREATION,
132
     * which means that all ACs are ignored. */
133
0
    pinfile->status = SC_FILE_STATUS_CREATION;
134
0
    r = sc_create_file(p15card->card, pinfile);
135
0
    if (r < 0)
136
0
      sc_file_free(pinfile);
137
0
    LOG_TEST_RET(ctx, r, "Pinfile creation failed");
138
0
  }
139
0
  sc_file_free(pinfile);
140
0
  LOG_TEST_RET(ctx, r, "Select pinfile failed");
141
142
0
  LOG_FUNC_RETURN(ctx, r);
143
0
}
144
145
/*
146
 * Create a DF
147
 */
148
static int
149
setcos_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df)
150
0
{
151
0
  struct sc_context *ctx = p15card->card->ctx;
152
0
  int r;
153
154
0
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
155
156
0
        r = sc_pkcs15init_fixup_file(profile, p15card, df);
157
0
  LOG_TEST_RET(ctx, r, "SetCOS file ACL fixup failed");
158
159
0
  r = sc_create_file(p15card->card, df);
160
0
  LOG_TEST_RET(ctx, r, "SetCOS create file failed");
161
162
0
  LOG_FUNC_RETURN(ctx, r);
163
0
}
164
165
166
/*
167
 * Select the PIN reference
168
 */
169
static int
170
setcos_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
171
  sc_pkcs15_auth_info_t *auth_info)
172
0
{
173
0
  sc_pkcs15_auth_info_t auth_info_prof = {0};
174
175
0
  auth_info_prof.attrs.pin.reference = 1; /* Default SO PIN ref. */
176
0
  auth_info_prof.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
177
0
  sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &auth_info_prof);
178
179
  /* For the SO pin, we take the first available pin reference = 1 */
180
0
  if (auth_info != NULL && auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN)
181
0
    auth_info->attrs.pin.reference = auth_info_prof.attrs.pin.reference;
182
  /* sc_pkcs15init_create_pin() starts checking if -1 is an acceptable
183
   * pin reference, which isn't for the SetCOS cards. And since the
184
   * value 1 has been assigned to the SO pin, we'll jump to 2. */
185
0
  else if (auth_info != NULL && auth_info->attrs.pin.reference <= 0) {
186
0
    if (auth_info_prof.attrs.pin.reference != 1)
187
0
      return SC_ERROR_INVALID_PIN_REFERENCE;
188
0
    auth_info->attrs.pin.reference = auth_info_prof.attrs.pin.reference + 1;
189
0
  }
190
191
0
  return SC_SUCCESS;
192
0
}
193
194
/*
195
 * Create a new PIN
196
 */
197
static int
198
setcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
199
  sc_file_t *df,
200
  sc_pkcs15_object_t *pin_obj,
201
  const u8 *pin, size_t pin_len,
202
  const u8 *puk, size_t puk_len)
203
0
{
204
0
  struct sc_context *ctx = p15card->card->ctx;
205
0
  sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data;
206
0
  sc_file_t *pinfile = NULL, *tmp_pinfile = NULL;
207
0
  int r, ignore_ac = 0;
208
209
0
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
210
211
0
  if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
212
0
    return SC_ERROR_OBJECT_NOT_VALID;
213
214
  /* Create the global pin file if it doesn't exist yet */
215
0
  r = sc_profile_get_file(profile, "pinfile", &tmp_pinfile);
216
0
  LOG_TEST_RET(ctx, r, "No 'pinfile' template in profile");
217
218
0
  r = sc_select_file(p15card->card, &tmp_pinfile->path, &pinfile);
219
0
  sc_file_free(tmp_pinfile);
220
0
  LOG_TEST_RET(ctx, r, "Cannot select 'pinfile'");
221
222
0
  sc_log(ctx,  "pinfile->status:%X", pinfile->status);
223
0
  sc_log(ctx,  "create PIN with reference:%X, flags:%X, path:%s",
224
0
      auth_info->attrs.pin.reference, auth_info->attrs.pin.flags, sc_print_path(&auth_info->path));
225
226
0
  if (pinfile->status == SC_FILE_STATUS_CREATION)
227
0
    ignore_ac = 1;
228
229
0
  r = setcos_create_pin_internal(profile, p15card, ignore_ac, auth_info,
230
0
      pin, pin_len, puk, puk_len);
231
232
  /* If pinfile is in 'Creation' state and SOPIN has been created,
233
   * change status of MF and 'pinfile' to 'Operational:Activated'
234
   */
235
0
  sc_file_free(pinfile);
236
0
  if (ignore_ac && (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN))   {
237
0
    sc_file_t *mf = profile->mf_info->file;
238
239
0
    r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_ACTIVATE_FILE, NULL);
240
0
    LOG_TEST_RET(ctx, r, "Cannot set 'pinfile' into the activated state");
241
242
0
    r = sc_select_file(p15card->card, &mf->path, NULL);
243
0
    LOG_TEST_RET(ctx, r, "Cannot select MF");
244
245
0
    r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_ACTIVATE_FILE, NULL);
246
0
    LOG_TEST_RET(ctx, r, "Cannot set MF into the activated state");
247
0
  }
248
249
0
  LOG_FUNC_RETURN(ctx, r);
250
0
}
251
252
/*
253
 * Setup file struct & path: get correct template from the profile, construct full path
254
 */
255
static int
256
setcos_new_file(sc_profile_t *profile, sc_card_t *card,
257
  unsigned int type,
258
  unsigned int num, /* number of objects of this type already on the card */
259
  sc_file_t **out)
260
0
{
261
0
  sc_file_t *file = NULL;
262
0
  sc_path_t *p;
263
0
  char name[64];
264
0
  const char *tag;
265
0
  int r;
266
267
0
  if (type == SC_PKCS15_TYPE_PRKEY_RSA)
268
0
    tag = "private-key";
269
0
  else if (type  == SC_PKCS15_TYPE_PUBKEY_RSA)
270
0
    tag = "public-key";
271
0
  else if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_CERT)
272
0
    tag = "certificate";
273
0
  else if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_DATA_OBJECT)
274
0
    tag = "data";
275
0
  else {
276
0
    sc_log(card->ctx,  "Unsupported file type");
277
0
    return SC_ERROR_INVALID_ARGUMENTS;
278
0
  }
279
280
  /* Get template from profile  */
281
0
  snprintf(name, sizeof(name), "template-%s", tag);
282
0
  if (sc_profile_get_file(profile, name, &file) < 0) {
283
0
    sc_log(card->ctx,  "Profile doesn't define %s", name);
284
0
    return SC_ERROR_NOT_SUPPORTED;
285
0
  }
286
287
  /* Auto-increment FID for next object */
288
0
  file->id += num;
289
0
  p = &file->path;
290
0
  *p = profile->df_info->file->path;
291
0
  if (p->len + 2 > SC_MAX_PATH_SIZE) {
292
0
    sc_file_free(file);
293
0
    return SC_ERROR_INVALID_DATA;
294
0
  }
295
0
  p->value[p->len++] = (u8) (file->id / 256);
296
0
  p->value[p->len++] = (u8) (file->id % 256);
297
298
  /* Increment FID until there's no file with such path */
299
0
  r = sc_select_file(card, p, NULL);
300
0
  while(r == 0) {
301
0
    file->id++;
302
0
    p->value[p->len - 2] = (u8) (file->id / 256);
303
0
    p->value[p->len - 1] = (u8) (file->id % 256);
304
0
    r = sc_select_file(card, p, NULL);
305
0
  }
306
307
0
  *out = file;
308
0
  return 0;
309
0
}
310
311
static int
312
setcos_encode_private_key(sc_profile_t *profile, sc_card_t *card,
313
  struct sc_pkcs15_prkey_rsa *rsa,
314
  u8 *key, size_t *keysize, int key_ref)
315
0
{
316
0
  return 0;
317
0
}
318
319
static int
320
setcos_encode_public_key(sc_profile_t *profile, sc_card_t *card,
321
  struct sc_pkcs15_prkey_rsa *rsa,
322
  u8 *key, size_t *keysize, int key_ref)
323
0
{
324
0
  return 0;
325
0
}
326
327
328
static int
329
setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
330
    struct sc_pkcs15_object *object)
331
0
{
332
0
  struct sc_context *ctx = p15card->card->ctx;
333
0
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
334
0
  struct sc_file *file = NULL;
335
0
  size_t keybits = key_info->modulus_length;
336
0
  int r;
337
338
0
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
339
0
  if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
340
0
    LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Create key failed: RSA only supported");
341
342
  /* Parameter check */
343
0
  if ((keybits < 512) || (keybits > 1024) || (keybits & 0x7))
344
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length");
345
346
0
  sc_log(ctx,  "create private key ID:%s\n",  sc_pkcs15_print_id(&key_info->id));
347
348
  /* Get the private key file */
349
0
  r = setcos_new_file(profile, p15card->card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file);
350
0
  LOG_TEST_RET(ctx, r, "Cannot get new private key file");
351
352
  /* Take enough room for a 1024 bit key */
353
0
  if (file->size < 512)
354
0
    file->size = 512;
355
356
  /* Replace the path of instantiated key template by the path from the object data. */
357
0
  memcpy(&file->path, &key_info->path, sizeof(file->path));
358
0
  if (file->path.len < 2) {
359
0
    sc_file_free(file);
360
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid path");
361
0
  }
362
0
  file->id = file->path.value[file->path.len - 2] * 0x100
363
0
      + file->path.value[file->path.len - 1];
364
365
0
  key_info->key_reference = file->path.value[file->path.len - 1] & 0xFF;
366
367
0
  sc_log(ctx,  "Path of private key file to create %s\n", sc_print_path(&file->path));
368
369
0
  r = sc_select_file(p15card->card, &file->path, NULL);
370
0
  if (!r) {
371
0
    r = sc_pkcs15init_delete_by_path(profile, p15card, &file->path);
372
0
    if (r != SC_SUCCESS)
373
0
      sc_file_free(file);
374
0
    LOG_TEST_RET(ctx, r, "Failed to delete private key file");
375
0
  } else if (r != SC_ERROR_FILE_NOT_FOUND) {
376
0
    sc_file_free(file);
377
0
    file = NULL;
378
0
    LOG_TEST_RET(ctx, r, "Select private key file error");
379
0
  }
380
381
  /* Now create the key file */
382
0
  r = sc_pkcs15init_create_file(profile, p15card, file);
383
0
  sc_file_free(file);
384
0
  LOG_TEST_RET(ctx, r, "Cannot create private key file");
385
386
0
  LOG_FUNC_RETURN(ctx, r);
387
0
}
388
389
390
/*
391
 * Store a private key
392
 */
393
static int
394
setcos_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
395
    struct sc_pkcs15_object *object,
396
    struct sc_pkcs15_prkey *prkey)
397
0
{
398
0
  struct sc_context *ctx = p15card->card->ctx;
399
0
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
400
0
  struct sc_cardctl_setcos_gen_store_key_info args;
401
0
  struct sc_file *file = NULL;
402
0
  int r;
403
0
  size_t keybits = key_info->modulus_length;
404
405
0
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
406
0
  if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
407
0
    LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported");
408
409
  /* Parameter check */
410
0
  if ( (keybits < 512) || (keybits > 1024) || (keybits & 0x7))
411
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length");
412
413
0
  sc_log(ctx,  "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id),
414
0
            sc_print_path(&key_info->path));
415
416
0
  r = sc_select_file(p15card->card, &key_info->path, &file);
417
0
  LOG_TEST_RET(ctx, r, "Cannot store key: select key file failed");
418
419
0
  r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
420
0
  LOG_TEST_RET(ctx, r, "No authorisation to store private key");
421
422
  /* Fill in data structure */
423
0
  memset(&args, 0, sizeof(args));
424
0
  args.mod_len = keybits;
425
0
  args.op_type = OP_TYPE_STORE;
426
0
  args.pubexp_len = prkey->u.rsa.exponent.len * 8;
427
0
  args.pubexp = prkey->u.rsa.exponent.data;
428
0
  args.primep_len = prkey->u.rsa.p.len * 8;
429
0
  args.primep = prkey->u.rsa.p.data;
430
0
  args.primeq_len = prkey->u.rsa.q.len * 8;
431
0
  args.primeq = prkey->u.rsa.q.data;
432
433
  /* Generate/store rsa key  */
434
0
  r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_GENERATE_STORE_KEY, &args);
435
0
  LOG_TEST_RET(ctx, r, "Card control 'GENERATE_STORE_KEY' failed");
436
437
0
  sc_file_free(file);
438
439
0
  LOG_FUNC_RETURN(ctx, r);
440
0
}
441
442
443
static int
444
setcos_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
445
    struct sc_pkcs15_object *object,
446
    struct sc_pkcs15_pubkey *pubkey)
447
0
{
448
0
  struct sc_context *ctx = p15card->card->ctx;
449
0
  struct sc_cardctl_setcos_gen_store_key_info args;
450
0
  struct sc_cardctl_setcos_data_obj data_obj;
451
0
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
452
0
  int r;
453
0
  size_t keybits = key_info->modulus_length;
454
0
  unsigned char raw_pubkey[256];
455
0
  struct sc_file *file = NULL;
456
457
0
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
458
0
  if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
459
0
    LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Generate key failed: RSA only supported");
460
461
  /* Parameter check */
462
0
  if ( (keybits < 512) || (keybits > 1024) || (keybits & 0x7))
463
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length");
464
465
0
  r = sc_select_file(p15card->card, &key_info->path, &file);
466
0
  LOG_TEST_RET(ctx, r, "Cannot store key: select key file failed");
467
468
  /* Authenticate */
469
0
  r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
470
0
  if (r != SC_SUCCESS) {
471
0
    sc_file_free(file);
472
0
    LOG_TEST_RET(ctx, r, "No authorisation to store private key");
473
0
  }
474
475
  /* Fill in data structure */
476
0
  memset(&args, 0, sizeof(args));
477
0
  args.mod_len = keybits;
478
0
  args.op_type = OP_TYPE_GENERATE;
479
0
  args.pubexp_len = SETCOS_DEFAULT_PUBKEY_LEN * 8;
480
0
  args.pubexp = SETCOS_DEFAULT_PUBKEY;
481
482
  /* Generate/store rsa key  */
483
0
  r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_GENERATE_STORE_KEY, &args);
484
0
  if (r != SC_SUCCESS) {
485
0
    sc_file_free(file);
486
0
    LOG_TEST_RET(ctx, r, "Card control 'GENERATE_STORE_KEY' failed");
487
0
  }
488
489
  /* Key pair generation -> collect public key info */
490
0
  if (pubkey != NULL) {
491
0
    pubkey->algorithm   = SC_ALGORITHM_RSA;
492
0
    pubkey->u.rsa.modulus.len = BYTES4BITS(keybits);
493
0
    pubkey->u.rsa.modulus.data  = malloc(pubkey->u.rsa.modulus.len);
494
0
    pubkey->u.rsa.exponent.len  = SETCOS_DEFAULT_PUBKEY_LEN;
495
0
    pubkey->u.rsa.exponent.data = malloc(SETCOS_DEFAULT_PUBKEY_LEN);
496
0
    memcpy(pubkey->u.rsa.exponent.data, SETCOS_DEFAULT_PUBKEY, SETCOS_DEFAULT_PUBKEY_LEN);
497
498
    /* Get public key modulus */
499
0
    r = sc_select_file(p15card->card, &file->path, NULL);
500
0
    sc_file_free(file);
501
0
    LOG_TEST_RET(ctx, r, "Cannot get key modulus: select key file failed");
502
503
0
    data_obj.P1 = 0x01;
504
0
    data_obj.P2 = 0x01;
505
0
    data_obj.Data = raw_pubkey;
506
0
    data_obj.DataLen = sizeof(raw_pubkey);
507
508
0
    r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_GETDATA, &data_obj);
509
0
    LOG_TEST_RET(ctx, r, "Cannot get key modulus: 'SETCOS_GETDATA' failed");
510
511
0
    if (data_obj.DataLen < 3 || data_obj.DataLen < pubkey->u.rsa.modulus.len)
512
0
      LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Cannot get key modulus: wrong length of raw key");
513
514
0
    keybits = ((raw_pubkey[0] * 256) + raw_pubkey[1]);  /* modulus bit length */
515
0
    if (keybits != key_info->modulus_length)  {
516
0
      sc_log(ctx,
517
0
         "key-size from card[%"SC_FORMAT_LEN_SIZE_T"u] does not match[%"SC_FORMAT_LEN_SIZE_T"u]\n",
518
0
         keybits, key_info->modulus_length);
519
0
      LOG_TEST_RET(ctx, SC_ERROR_PKCS15INIT, "Failed to generate key");
520
0
    }
521
0
    memcpy(pubkey->u.rsa.modulus.data, &raw_pubkey[2], pubkey->u.rsa.modulus.len);
522
0
  } else {
523
0
    sc_file_free(file);
524
0
  }
525
526
0
  return r;
527
0
}
528
529
530
/*
531
 * Create a new PIN
532
 */
533
static int
534
setcos_create_pin_internal(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
535
  int ignore_ac, sc_pkcs15_auth_info_t *auth_info,
536
  const u8 *pin, size_t pin_len,
537
  const u8 *puk, size_t puk_len)
538
0
{
539
0
  struct sc_context *ctx = p15card->card->ctx;
540
0
  u8  data[32];
541
0
  int r;
542
0
  struct sc_cardctl_setcos_data_obj data_obj;
543
0
  sc_file_t *pinfile = NULL;
544
545
0
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
546
0
  if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
547
0
    return SC_ERROR_OBJECT_NOT_VALID;
548
549
0
  if (auth_info->attrs.pin.reference >= SETCOS_MAX_PINS)
550
0
    return SC_ERROR_INVALID_ARGUMENTS;
551
0
  if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4)
552
0
    return SC_ERROR_INVALID_PIN_LENGTH;
553
554
  /* Verify required access rights if needed (i.e. if the
555
   * pin file isn't in the CREATE life cycle state). */
556
0
  if (!ignore_ac) {
557
0
    r = sc_profile_get_file(profile, "pinfile", &pinfile);
558
0
    if (r >= 0)
559
0
      r = sc_pkcs15init_authenticate(profile, p15card, pinfile, SC_AC_OP_UPDATE);
560
0
    sc_file_free(pinfile);
561
0
    if (r < 0)
562
0
      return r;
563
0
  }
564
565
  /* Make command to add a pin-record */
566
567
0
  data_obj.P1 = 01;
568
0
  data_obj.P2 = 01;
569
570
  /* setcos pin number */
571
0
  data[0] = auth_info->attrs.pin.reference;
572
573
0
  memset(&data[1], auth_info->attrs.pin.pad_char, 16); /* padding */
574
0
  memcpy(&data[1], (u8 *)pin, pin_len);     /* copy pin*/
575
0
  memcpy(&data[9], (u8 *)puk, puk_len);     /* copy puk */
576
577
0
  data[17] = auth_info->tries_left & 0x0F;
578
0
  data[18] = auth_info->tries_left & 0x0F;
579
  /* 0xF0: unlimited unblock tries */
580
0
  data[19] = 0xF0 | setcos_puk_retries(profile, auth_info->attrs.pin.reference);
581
582
  /* Allow an unlimited number of signatures after a pin verification.
583
   * If set to 1 or so, we would have a UserConsent PIN. */
584
0
  data[20] = 0x00;
585
586
0
  if (auth_info->attrs.pin.type == 0)
587
0
    data[21] = 0x01; /* BCD */
588
0
  else
589
0
    data[21] = 0x00; /* ASCII */
590
0
  if ((auth_info->attrs.pin.flags & 0x010) == 0) /* test for initial pin */
591
0
    data[21] |= 0x80;
592
593
0
  data[22]        = 0x00;     /* not used */
594
0
  data[23]        = 0x00;     /* not used */
595
596
0
  data_obj.Data    = data;
597
0
  data_obj.DataLen = 24;
598
599
0
  r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_PUTDATA, &data_obj);
600
601
0
  SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r);
602
0
}
603
604
605
static struct sc_pkcs15init_operations sc_pkcs15init_setcos_operations = {
606
  setcos_erase_card,    /* erase_card */
607
  setcos_init_card,   /* init_card     */
608
  setcos_create_dir,    /* create_dir    */
609
  NULL,       /* create_domain */
610
  setcos_select_pin_reference,  /* select_pin_reference */
611
  setcos_create_pin,    /* create_pin */
612
  NULL,         /* select_key_reference */
613
  setcos_create_key,    /* create_key */
614
  setcos_store_key,   /* store_key  */
615
  setcos_generate_key,    /* generate_key */
616
  setcos_encode_private_key,  /* encode_private_key  */
617
  setcos_encode_public_key,   /* encode_public_key */
618
  NULL,       /* finalize_card */
619
  NULL,         /* delete_object */
620
  NULL,       /* emu_update_dir */
621
  NULL,         /* emu_update_any_df */
622
  NULL,         /* emu_update_tokeninfo */
623
  NULL,         /* emu_write_info */
624
  NULL,         /* emu_store_data */
625
  NULL        /* sanity_check */
626
};
627
628
struct sc_pkcs15init_operations *
629
sc_pkcs15init_get_setcos_ops(void)
630
0
{
631
0
  return &sc_pkcs15init_setcos_operations;
632
0
}