Coverage Report

Created: 2026-07-24 06:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/pkcs15-coolkey.c
Line
Count
Source
1
/*
2
 * partial PKCS15 emulation for Coolkey cards
3
 *
4
 * Copyright (C) 2005,2006,2007,2008,2009,2010
5
 *               Douglas E. Engert <deengert@anl.gov>
6
 *               2004, Nils Larsch <larsch@trustcenter.de>
7
 * Copyright (C) 2006, Identity Alliance,
8
 *               Thomas Harning <thomas.harning@identityalliance.com>
9
 * Copyright (C) 2007, EMC, Russell Larner <rlarner@rsa.com>
10
 * Copyright (C) 2016, Red Hat, Inc.
11
 *
12
 * Coolkey driver author: Robert Relyea <rrelyea@redhat.com>
13
 *
14
 * This library is free software; you can redistribute it and/or
15
 * modify it under the terms of the GNU Lesser General Public
16
 * License as published by the Free Software Foundation; either
17
 * version 2.1 of the License, or (at your option) any later version.
18
 *
19
 * This library is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22
 * Lesser General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Lesser General Public
25
 * License along with this library; if not, write to the Free Software
26
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27
 */
28
29
#ifdef HAVE_CONFIG_H
30
#include "config.h"
31
#endif
32
33
#include <stdlib.h>
34
#include <string.h>
35
#include <stdio.h>
36
#include <ctype.h>
37
38
#include "internal.h"
39
#include "cardctl.h"
40
#include "asn1.h"
41
#include "pkcs15.h"
42
#include "../pkcs11/pkcs11.h"
43
44
typedef struct pdata_st {
45
  const char *id;
46
  const char *label;
47
  const char *path;
48
  int         ref;
49
  int         type;
50
  unsigned int maxlen;
51
  unsigned int minlen;
52
  unsigned int storedlen;
53
  int         flags;
54
  int         tries_left;
55
  const unsigned char  pad_char;
56
  int         obj_flags;
57
} pindata;
58
59
static int coolkey_detect_card(sc_pkcs15_card_t *p15card)
60
8.75k
{
61
8.75k
  sc_card_t *card = p15card->card;
62
63
8.75k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
64
8.75k
  if (card->type < SC_CARD_TYPE_COOLKEY_GENERIC
65
1.14k
    || card->type >= SC_CARD_TYPE_COOLKEY_GENERIC+1000)
66
8.11k
    return SC_ERROR_INVALID_CARD;
67
632
  return SC_SUCCESS;
68
8.75k
}
69
70
static int
71
248
coolkey_get_object(sc_card_t *card, unsigned long object_id, sc_cardctl_coolkey_object_t **obj) {
72
248
  sc_cardctl_coolkey_find_object_t fobj;
73
248
  int r;
74
75
248
  fobj.type = SC_CARDCTL_COOLKEY_FIND_BY_ID;
76
248
  fobj.find_id = object_id;
77
248
  fobj.obj = NULL;
78
248
  r = sc_card_ctl(card, SC_CARDCTL_COOLKEY_FIND_OBJECT, &fobj);
79
248
  if (r < 0) {
80
139
    return r;
81
139
  }
82
109
  *obj = fobj.obj;
83
109
  return SC_SUCCESS;
84
248
}
85
86
87
/*
88
 * fetch attributes from an object
89
 */
90
static int
91
35.3k
coolkey_get_attribute(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, CK_ATTRIBUTE_TYPE type, const u8 **val, size_t *val_len, u8 *data_type) {
92
35.3k
  sc_cardctl_coolkey_attribute_t attribute;
93
35.3k
  int r;
94
95
35.3k
  attribute.object = obj;
96
35.3k
  attribute.attribute_type = type;
97
98
35.3k
  r = sc_card_ctl(card, SC_CARDCTL_COOLKEY_GET_ATTRIBUTE, &attribute);
99
35.3k
  if (r < 0) {
100
18.8k
    return r;
101
18.8k
  }
102
16.5k
  *val = attribute.attribute_value;
103
16.5k
  *val_len = attribute.attribute_length;
104
16.5k
  if (data_type) {
105
1.58k
    *data_type = attribute.attribute_data_type;
106
1.58k
  }
107
16.5k
  return SC_SUCCESS;
108
35.3k
}
109
110
static int
111
1.32k
coolkey_find_matching_cert(sc_card_t *card, sc_cardctl_coolkey_object_t *in_obj, sc_cardctl_coolkey_object_t **cert_obj) {
112
1.32k
  sc_cardctl_coolkey_find_object_t fobj;
113
1.32k
  sc_cardctl_coolkey_attribute_t template[2];
114
1.32k
  u8 obj_class[4];
115
1.32k
  int r;
116
117
  /* we are searching for certs .. */
118
1.32k
  template[0].attribute_type = CKA_CLASS;
119
1.32k
  template[0].attribute_data_type = SC_CARDCTL_COOLKEY_ATTR_TYPE_ULONG;
120
1.32k
  template[0].attribute_length = sizeof(obj_class);
121
1.32k
  template[0].attribute_value = obj_class;
122
1.32k
  ulong2bebytes(obj_class, CKO_CERTIFICATE);
123
124
  /* fetch the current object's CKA_ID */
125
1.32k
  template[1].attribute_type = CKA_ID;
126
1.32k
  template[1].object = in_obj;
127
1.32k
  r = sc_card_ctl(card, SC_CARDCTL_COOLKEY_GET_ATTRIBUTE, &template[1]);
128
1.32k
  if (r < 0) {
129
44
    return r;
130
44
  }
131
1.27k
  template[0].object = NULL; /*paranoia */
132
1.27k
  template[1].object = NULL; /*paranoia */
133
134
  /* now find the cert that has the ID */
135
1.27k
  fobj.type = SC_CARDCTL_COOLKEY_FIND_BY_TEMPLATE;
136
1.27k
  fobj.obj = NULL;
137
1.27k
  fobj.coolkey_template = &template[0];
138
1.27k
  fobj.template_count=2;
139
1.27k
  r = sc_card_ctl(card, SC_CARDCTL_COOLKEY_FIND_OBJECT, &fobj);
140
1.27k
  if (r < 0) {
141
938
    return r;
142
938
  }
143
341
  *cert_obj = fobj.obj;
144
341
  return SC_SUCCESS;
145
1.27k
}
146
147
static int
148
coolkey_get_attribute_ulong(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, CK_ATTRIBUTE_TYPE type, CK_ULONG *value)
149
5.26k
{
150
5.26k
  const u8 *val = NULL;
151
5.26k
  size_t val_len = 0;
152
5.26k
  u8 data_type = 0;
153
5.26k
  int r;
154
155
5.26k
  r  = coolkey_get_attribute(card, obj, type, &val, &val_len, &data_type);
156
5.26k
  if (r < 0) {
157
3.68k
    return r;
158
3.68k
  }
159
1.58k
  if ((data_type != SC_CARDCTL_COOLKEY_ATTR_TYPE_ULONG) &&
160
99
      (val_len != sizeof(CK_ULONG))) {
161
64
    return SC_ERROR_CORRUPTED_DATA;
162
64
  }
163
1.51k
  *value = bebytes2ulong(val);
164
1.51k
  return SC_SUCCESS;
165
1.58k
}
166
167
static int
168
coolkey_get_attribute_boolean(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, CK_ATTRIBUTE_TYPE attr_type)
169
23.1k
{
170
23.1k
  int r;
171
23.1k
  const u8 *val = NULL;
172
23.1k
  size_t val_len = 0;
173
174
23.1k
  r = coolkey_get_attribute(card, obj, attr_type, &val, &val_len, NULL);
175
23.1k
  if (r < 0) {
176
    /* attribute not valid for this object, set boolean to false */
177
9.67k
    return 0;
178
9.67k
  }
179
13.5k
  if ((val_len == 1) && (*val == 1)) {
180
5.61k
    return 1;
181
5.61k
  }
182
7.89k
  return 0;
183
13.5k
}
184
185
static int
186
coolkey_get_attribute_bytes(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, CK_ATTRIBUTE_TYPE type, u8 *data, size_t *data_len, size_t max_data_len)
187
5.44k
{
188
5.44k
  const u8 *val;
189
5.44k
  size_t val_len = 0;
190
5.44k
  int r;
191
192
5.44k
  r = coolkey_get_attribute(card, obj, type, &val, &val_len, NULL);
193
5.44k
  if (r < 0) {
194
4.15k
    return r;
195
4.15k
  }
196
1.29k
  if (val_len > max_data_len) {
197
6
    val_len = max_data_len;
198
6
  }
199
1.29k
  memcpy(data, val, val_len);
200
1.29k
  *data_len = val_len;
201
1.29k
  return SC_SUCCESS;
202
5.44k
}
203
204
static int
205
coolkey_get_attribute_bytes_alloc(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, CK_ATTRIBUTE_TYPE type, u8 **data, size_t *data_len)
206
1.44k
{
207
1.44k
  const u8 *val;
208
1.44k
  size_t val_len;
209
1.44k
  int r;
210
211
1.44k
  r = coolkey_get_attribute(card, obj, type, &val, &val_len, NULL);
212
1.44k
  if (r < 0 || val_len < 1) {
213
1.33k
    return r;
214
1.33k
  }
215
105
  *data = malloc(val_len);
216
105
  if (*data == NULL) {
217
0
    return SC_ERROR_OUT_OF_MEMORY;
218
0
  }
219
105
  memcpy(*data, val, val_len);
220
105
  *data_len = val_len;
221
105
  return SC_SUCCESS;
222
105
}
223
224
static int
225
coolkey_get_id(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, struct sc_pkcs15_id *id)
226
1.32k
{
227
1.32k
  return coolkey_get_attribute_bytes(card, obj, CKA_ID, id->value , &id->len, sizeof(id->value));
228
1.32k
}
229
230
/*
231
 * A number of opensc structure have the same layout, use a common function to fill them
232
 * int:
233
 *     structure name      first parameter                 second parameter
234
 *     sc_lv_data          unsigned char * value           size_t len
235
 *     sc_pkcs15_data         u8 *data                     size_t data_len
236
 *     sc_pkcs15_bignum       u8 *data                     size_t len
237
 *     sc_pkcs15_der          u8 *value                    size_t len
238
 *     sc_pkcs15_u8           u8 *value                    size_t len
239
 *
240
 * The following can properly assign all of them
241
 */
242
int
243
coolkey_get_attribute_lv(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, CK_ATTRIBUTE_TYPE type, void *ptr)
244
1.43k
{
245
1.43k
  struct sc_pkcs15_data *item = (struct sc_pkcs15_data *)ptr;
246
1.43k
  return coolkey_get_attribute_bytes_alloc(card, obj, type, &item->data, &item->data_len);
247
1.43k
}
248
249
1.33k
#define COOLKEY_ID_CERT ((unsigned long)'c')
250
#define COOLKEY_ID_KEY ((unsigned long)'k')
251
248
#define COOLKEY_ID_CERT_DATA ((unsigned long)'C')
252
253
static unsigned long
254
1.33k
coolkey_get_object_type(unsigned long object_id) { return ((object_id >> 24 ) & 0xff); }
255
256
static unsigned long
257
coolkey_make_new_id(unsigned long object_id, unsigned long id_type)
258
248
{ return ((object_id  & 0x00ffffffUL)|(id_type << 24)); }
259
260
261
/*
262
 * We need cert data to fill in some of our keys. Also, some older tokens store the cert data in a separate
263
 * object from the rest of the cert attributes. This function handles both of these complications
264
 */
265
static int
266
coolkey_get_certificate(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, struct sc_pkcs15_der *cert)
267
1.33k
{
268
1.33k
  sc_cardctl_coolkey_object_t *cert_obj;
269
1.33k
  unsigned long object_id;
270
1.33k
  int r;
271
272
1.33k
  cert_obj = obj;
273
1.33k
  if (coolkey_get_object_type(obj->id) != COOLKEY_ID_CERT) {
274
1.32k
    r = coolkey_find_matching_cert(card, obj, &cert_obj);
275
1.32k
    if (r < 0) {
276
982
      return r;
277
982
    }
278
1.32k
  }
279
350
  r = coolkey_get_attribute_lv(card, cert_obj, CKA_VALUE, cert);
280
350
  if (r == SC_ERROR_DATA_OBJECT_NOT_FOUND) {
281
248
    object_id = coolkey_make_new_id(cert_obj->id, COOLKEY_ID_CERT_DATA);
282
248
    r = coolkey_get_object(card, object_id, &cert_obj);
283
248
    if (r < 0) {
284
139
      return r;
285
139
    }
286
    /* fill in cert data */
287
109
    cert->value = malloc(cert_obj->length);
288
109
    if (cert->value == NULL) {
289
0
      return SC_ERROR_OUT_OF_MEMORY;
290
0
    }
291
109
    memcpy(cert->value, cert_obj->data, cert_obj->length);
292
109
    cert->len = cert_obj->length;
293
109
    return SC_SUCCESS;
294
109
  }
295
102
  return r;
296
350
}
297
298
299
300
struct coolkey_attr_flags {
301
  CK_ATTRIBUTE_TYPE attribute_type;
302
  unsigned int pkcs15_flags;
303
};
304
305
static struct coolkey_attr_flags usage_table[] = {
306
  { CKA_ENCRYPT,          SC_PKCS15_PRKEY_USAGE_ENCRYPT       },
307
  { CKA_DECRYPT,          SC_PKCS15_PRKEY_USAGE_DECRYPT       },
308
  { CKA_SIGN,             SC_PKCS15_PRKEY_USAGE_SIGN          },
309
  { CKA_SIGN_RECOVER,     SC_PKCS15_PRKEY_USAGE_SIGNRECOVER   },
310
  { CKA_WRAP,             SC_PKCS15_PRKEY_USAGE_WRAP          },
311
  { CKA_UNWRAP,           SC_PKCS15_PRKEY_USAGE_UNWRAP        },
312
  { CKA_VERIFY,           SC_PKCS15_PRKEY_USAGE_VERIFY        },
313
  { CKA_VERIFY_RECOVER,   SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER },
314
  { CKA_DERIVE,           SC_PKCS15_PRKEY_USAGE_DERIVE        }
315
};
316
317
static struct coolkey_attr_flags access_table[] = {
318
  { CKA_SENSITIVE,        SC_PKCS15_PRKEY_ACCESS_SENSITIVE       },
319
    { CKA_EXTRACTABLE,      SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE     },
320
    { CKA_ALWAYS_SENSITIVE, SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE },
321
    { CKA_NEVER_EXTRACTABLE,SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE},
322
    { CKA_LOCAL,            SC_PKCS15_PRKEY_ACCESS_LOCAL           }
323
};
324
325
static struct coolkey_attr_flags flag_table[] = {
326
  { CKA_PRIVATE,          SC_PKCS15_CO_FLAG_PRIVATE       },
327
  { CKA_MODIFIABLE,       SC_PKCS15_CO_FLAG_MODIFIABLE    }
328
};
329
330
static int usage_table_size = sizeof(usage_table)/sizeof(usage_table[0]);
331
static int access_table_size = sizeof(access_table)/sizeof(access_table[0]);
332
static int flag_table_size = sizeof(flag_table)/sizeof(flag_table[0]);
333
334
static int
335
coolkey_set_bool_flags(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, unsigned int *flags_ptr, struct coolkey_attr_flags *table, int table_size)
336
6.30k
{
337
6.30k
  unsigned int flags = 0;
338
6.30k
  int i;
339
340
29.4k
  for (i=0; i< table_size; i++) {
341
23.1k
    if (coolkey_get_attribute_boolean(card, obj, table[i].attribute_type)) {
342
5.61k
      flags |= table[i].pkcs15_flags;
343
5.61k
    }
344
23.1k
  }
345
6.30k
  *flags_ptr = flags;
346
6.30k
  return SC_SUCCESS;
347
6.30k
}
348
349
/* map a cert usage and algorithm to public and private key usages */
350
static int
351
coolkey_get_usage(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, unsigned int *usage_ptr)
352
1.05k
{
353
1.05k
  return coolkey_set_bool_flags(card, obj, usage_ptr, usage_table, usage_table_size);
354
1.05k
}
355
356
/* map a cert usage and algorithm to public and private key usages */
357
static int
358
coolkey_get_flags(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, unsigned int *flag_ptr)
359
4.18k
{
360
4.18k
  return coolkey_set_bool_flags(card, obj, flag_ptr, flag_table, flag_table_size);
361
4.18k
}
362
363
static int
364
coolkey_get_access(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, unsigned int *access_ptr)
365
1.05k
{
366
1.05k
  return coolkey_set_bool_flags(card, obj, access_ptr, access_table, access_table_size);
367
1.05k
}
368
369
370
/*
371
 * turn a coolkey object into a pkcss 15 pubkey. object should already be type
372
 * CKO_PUBLIC_KEY */
373
static sc_pkcs15_pubkey_t *
374
coolkey_make_public_key(sc_card_t *card, sc_cardctl_coolkey_object_t *obj, CK_KEY_TYPE key_type)
375
1.12k
{
376
1.12k
  sc_pkcs15_pubkey_t *key;
377
1.12k
  int r;
378
379
1.12k
  key = calloc(1, sizeof(struct sc_pkcs15_pubkey));
380
1.12k
  if (!key)
381
0
    return NULL;
382
1.12k
  switch (key_type) {
383
1.06k
  case CKK_RSA:
384
1.06k
    key->algorithm = SC_ALGORITHM_RSA;
385
1.06k
    r = coolkey_get_attribute_lv(card, obj, CKA_MODULUS, &key->u.rsa.modulus);
386
1.06k
    if (r != SC_SUCCESS) {
387
1.03k
      goto fail;
388
1.03k
    }
389
26
    r = coolkey_get_attribute_lv(card, obj, CKA_PUBLIC_EXPONENT, &key->u.rsa.exponent);
390
26
    if (r != SC_SUCCESS) {
391
26
      goto fail;
392
26
    }
393
0
    break;
394
2
  case CKK_EC:
395
2
    key->algorithm = SC_ALGORITHM_EC;
396
2
    r = coolkey_get_attribute_bytes_alloc(card, obj, CKA_EC_POINT, &key->u.ec.ecpointQ.value, &key->u.ec.ecpointQ.len);
397
2
      if(r < 0) {
398
1
      goto fail;
399
1
    }
400
1
    r = coolkey_get_attribute_bytes_alloc(card, obj, CKA_EC_PARAMS,
401
1
        &key->u.ec.params.der.value, &key->u.ec.params.der.len);
402
1
    if (r < 0) {
403
1
      goto fail;
404
1
    }
405
0
    r = sc_pkcs15_fix_ec_parameters(card->ctx, &key->u.ec.params);
406
0
    if (r < 0) {
407
0
      goto fail;
408
0
    }
409
0
    break;
410
1.12k
  }
411
58
  return key;
412
1.06k
fail:
413
1.06k
  sc_pkcs15_free_pubkey(key);
414
415
  /* now parse the DER cert */
416
1.06k
  return NULL;
417
1.12k
}
418
419
420
static sc_pkcs15_pubkey_t *
421
coolkey_get_public_key_from_certificate(sc_pkcs15_card_t *p15card, sc_cardctl_coolkey_object_t *obj)
422
1.06k
{
423
1.06k
  sc_pkcs15_cert_info_t cert_info;
424
1.06k
  sc_pkcs15_cert_t *cert_out = NULL;
425
1.06k
  sc_pkcs15_pubkey_t *key = NULL;
426
1.06k
  int r, private_obj;
427
1.06k
  unsigned int flags;
428
429
1.06k
  memset(&cert_info, 0, sizeof(cert_info));
430
431
1.06k
  r = coolkey_get_certificate(p15card->card, obj, &cert_info.value);
432
1.06k
  if (r < 0) {
433
1.00k
    goto fail;
434
1.00k
  }
435
436
62
  coolkey_get_flags(p15card->card, obj, &flags);
437
62
  private_obj = flags & SC_PKCS15_CO_FLAG_PRIVATE;
438
62
  r = sc_pkcs15_read_certificate(p15card, &cert_info, private_obj, &cert_out);
439
62
  if (r < 0) {
440
58
    goto fail;
441
58
  }
442
4
  key = cert_out->key;
443
4
  cert_out->key = NULL; /* adopt the key from the cert */
444
1.06k
fail:
445
1.06k
  if (cert_out) {
446
4
    sc_pkcs15_free_certificate(cert_out);
447
4
  }
448
1.06k
  if (cert_info.value.value) {
449
46
    free(cert_info.value.value);
450
46
  }
451
1.06k
  return key;
452
4
}
453
454
static sc_pkcs15_pubkey_t *
455
coolkey_get_public_key(sc_pkcs15_card_t *p15card, sc_cardctl_coolkey_object_t *obj, CK_KEY_TYPE key_type)
456
1.12k
{
457
1.12k
  sc_pkcs15_pubkey_t *key;
458
459
1.12k
  key = coolkey_make_public_key(p15card->card, obj, key_type);
460
1.12k
  if (key) {
461
58
    return key;
462
58
  }
463
1.06k
  return coolkey_get_public_key_from_certificate(p15card, obj);
464
1.12k
}
465
466
static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card)
467
632
{
468
632
  int use_pin_cache_backup = p15card->opts.use_pin_cache;
469
632
  static const pindata pins[] = {
470
632
    { "1", NULL, "", 0x00,
471
632
      SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
472
632
      32, 4, 32,
473
632
      SC_PKCS15_PIN_FLAG_INITIALIZED,
474
632
      -1, 0xFF,
475
632
      SC_PKCS15_CO_FLAG_PRIVATE },
476
632
    { NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0}
477
632
  };
478
479
  /*
480
   * The size of the key or the algid is not really known
481
   * but can be derived from the certificates.
482
   * the cert, pubkey and privkey are a set.
483
   * Key usages bits taken from certificate key usage extension.
484
   */
485
486
632
  int    r, i;
487
632
  sc_card_t *card = p15card->card;
488
632
  sc_serial_number_t serial;
489
632
  int count;
490
632
  struct sc_pkcs15_object *obj;
491
492
632
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
493
494
632
  memset(&serial, 0, sizeof(serial));
495
496
  /* coolkey caches a nonce once it logs in, don't keep the pin around. The card will
497
   * stay logged in until it's been pulled from the reader, in which case you want to reauthenticate
498
   * anyway */
499
632
  p15card->opts.use_pin_cache = 0;
500
501
  /* get the token info from the card */
502
632
  r = sc_card_ctl(card, SC_CARDCTL_COOLKEY_GET_TOKEN_INFO, p15card->tokeninfo);
503
632
  if (r < 0) {
504
    /* put some defaults in if we didn't succeed */
505
0
    set_string(&p15card->tokeninfo->label, "Coolkey");
506
0
    set_string(&p15card->tokeninfo->manufacturer_id, "Unknown");
507
0
    set_string(&p15card->tokeninfo->serial_number, "00000000");
508
0
  }
509
510
  /* set pins */
511
632
  sc_log(card->ctx,  "Coolkey adding pins...");
512
1.26k
  for (i = 0; pins[i].id; i++) {
513
632
    struct sc_pkcs15_auth_info pin_info;
514
632
    struct sc_pkcs15_object   pin_obj;
515
632
    const char * label;
516
517
632
    memset(&pin_info, 0, sizeof(pin_info));
518
632
    memset(&pin_obj,  0, sizeof(pin_obj));
519
520
632
    pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
521
632
    sc_pkcs15_format_id(pins[i].id, &pin_info.auth_id);
522
632
    pin_info.attrs.pin.reference     = pins[i].ref;
523
632
    pin_info.attrs.pin.flags         = pins[i].flags;
524
632
    pin_info.attrs.pin.type          = pins[i].type;
525
632
    pin_info.attrs.pin.min_length    = pins[i].minlen;
526
632
    pin_info.attrs.pin.stored_length = pins[i].storedlen;
527
632
    pin_info.attrs.pin.max_length    = pins[i].maxlen;
528
632
    pin_info.attrs.pin.pad_char      = pins[i].pad_char;
529
632
    sc_format_path(pins[i].path, &pin_info.path);
530
632
    pin_info.tries_left    = -1;
531
532
632
    label = pins[i].label? pins[i].label : p15card->tokeninfo->label;
533
632
    sc_log(card->ctx,  "Coolkey Adding pin %d label=%s",i, label);
534
632
    strncpy(pin_obj.label, label, SC_PKCS15_MAX_LABEL_SIZE - 1);
535
632
    pin_obj.flags = pins[i].obj_flags;
536
537
632
    r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
538
632
    LOG_TEST_GOTO_ERR(card->ctx, r, "Can not add pin object.");
539
632
  }
540
541
  /* set other objects */
542
632
  r = (card->ops->card_ctl)(card, SC_CARDCTL_COOLKEY_INIT_GET_OBJECTS, &count);
543
632
  LOG_TEST_GOTO_ERR(card->ctx, r, "Can not initiate objects.");
544
545
632
  sc_log(card->ctx,  "Iterating over %d objects", count);
546
4.75k
  for (i = 0; i < count; i++) {
547
4.12k
    struct sc_cardctl_coolkey_object     coolkey_obj;
548
4.12k
    struct sc_pkcs15_object    obj_obj;
549
4.12k
    struct sc_pkcs15_cert_info cert_info = {0};
550
4.12k
    struct sc_pkcs15_pubkey_info pubkey_info;
551
4.12k
    struct sc_pkcs15_prkey_info prkey_info;
552
4.12k
    sc_pkcs15_pubkey_t *key = NULL;
553
4.12k
    void *obj_info = NULL;
554
4.12k
    int obj_type = 0;
555
4.12k
    CK_KEY_TYPE key_type;
556
4.12k
    CK_OBJECT_CLASS obj_class;
557
4.12k
    size_t len;
558
559
4.12k
    r = (card->ops->card_ctl)(card, SC_CARDCTL_COOLKEY_GET_NEXT_OBJECT, &coolkey_obj);
560
4.12k
    LOG_TEST_GOTO_ERR(card->ctx, r, "Can not get next object from card.");
561
4.12k
    sc_log(card->ctx, "Loading object %d", i);
562
4.12k
    memset(&obj_obj, 0, sizeof(obj_obj));
563
    /* coolkey applets have label only on the certificates,
564
     * but we should copy it also to the keys matching the same ID */
565
4.12k
    coolkey_get_attribute_bytes(card, &coolkey_obj, CKA_LABEL, (u8 *)obj_obj.label, &len, sizeof(obj_obj.label));
566
4.12k
    coolkey_get_flags(card, &coolkey_obj, &obj_obj.flags);
567
4.12k
    if (obj_obj.flags & SC_PKCS15_CO_FLAG_PRIVATE) {
568
596
      sc_pkcs15_format_id(pins[0].id, &obj_obj.auth_id);
569
596
    }
570
571
4.12k
    r = coolkey_get_attribute_ulong(card, &coolkey_obj, CKA_CLASS, &obj_class);
572
4.12k
    if (r < 0) {
573
2.66k
      goto fail;
574
2.66k
    }
575
1.45k
    switch (obj_class) {
576
1.06k
    case CKO_PRIVATE_KEY:
577
1.06k
      sc_log(card->ctx, "Processing private key object %d", i);
578
1.06k
      r = coolkey_get_attribute_ulong(card, &coolkey_obj, CKA_KEY_TYPE, &key_type);
579
      /* default to CKK_RSA */
580
1.06k
      if (r == SC_ERROR_DATA_OBJECT_NOT_FOUND) {
581
1.00k
        key_type = CKK_RSA;
582
1.00k
        r = SC_SUCCESS;
583
1.00k
      }
584
1.06k
      if (r < 0) {
585
10
        goto fail;
586
10
      }
587
      /* set the info values */
588
1.05k
      obj_info = &prkey_info;
589
1.05k
      memset(&prkey_info, 0, sizeof(prkey_info));
590
1.05k
      coolkey_get_id(card, &coolkey_obj, &prkey_info.id);
591
1.05k
      prkey_info.path = coolkey_obj.path;
592
1.05k
      prkey_info.key_reference = (int)coolkey_obj.id;
593
1.05k
      prkey_info.native = 1;
594
1.05k
      coolkey_get_usage(card, &coolkey_obj, &prkey_info.usage);
595
1.05k
      coolkey_get_access(card, &coolkey_obj, &prkey_info.access_flags);
596
1.05k
      key = coolkey_get_public_key(p15card, &coolkey_obj, key_type);
597
1.05k
      if (key_type == CKK_RSA) {
598
1.00k
        obj_type = SC_PKCS15_TYPE_PRKEY_RSA;
599
1.00k
        if (key) {
600
2
          prkey_info.modulus_length = key->u.rsa.modulus.len*8;
601
2
        }
602
1.00k
      } else if (key_type == CKK_EC) {
603
2
        obj_type = SC_PKCS15_TYPE_PRKEY_EC;
604
2
        if (key) {
605
0
          prkey_info.field_length = key->u.ec.params.field_length;
606
0
        }
607
45
      } else {
608
45
        goto fail;
609
45
      }
610
1.01k
      break;
611
612
1.01k
    case CKO_PUBLIC_KEY:
613
72
      sc_log(card->ctx, "Processing public key object %d", i);
614
72
      r = coolkey_get_attribute_ulong(card, &coolkey_obj, CKA_KEY_TYPE, &key_type);
615
      /* default to CKK_RSA */
616
72
      if (r == SC_ERROR_DATA_OBJECT_NOT_FOUND) {
617
53
        key_type = CKK_RSA;
618
53
        r = SC_SUCCESS;
619
53
      }
620
72
      if (r < 0) {
621
5
        goto fail;
622
5
      }
623
67
      key = coolkey_get_public_key(p15card, &coolkey_obj, key_type);
624
67
      if (key == NULL) {
625
52
        goto fail;
626
52
      }
627
      /* set the info values */
628
15
      obj_info = &pubkey_info;
629
15
      memset(&pubkey_info, 0, sizeof(pubkey_info));
630
15
      r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, key, &pubkey_info.direct.spki.value,
631
15
        &pubkey_info.direct.spki.len);
632
15
      if (r < 0)
633
13
        goto fail;
634
2
      coolkey_get_id(card, &coolkey_obj, &pubkey_info.id);
635
2
      pubkey_info.path = coolkey_obj.path;
636
2
      pubkey_info.native = 1;
637
2
      pubkey_info.key_reference = (int)coolkey_obj.id;
638
2
      coolkey_get_usage(card, &coolkey_obj, &pubkey_info.usage);
639
2
      coolkey_get_access(card, &coolkey_obj, &pubkey_info.access_flags);
640
2
      if (key_type == CKK_RSA) {
641
2
        obj_type = SC_PKCS15_TYPE_PUBKEY_RSA;
642
2
        pubkey_info.modulus_length = key->u.rsa.modulus.len*8;
643
2
      } else if (key_type == CKK_EC) {
644
0
        obj_type = SC_PKCS15_TYPE_PUBKEY_EC;
645
0
        pubkey_info.field_length = key->u.ec.params.field_length;
646
0
      } else {
647
0
        free(pubkey_info.direct.spki.value);
648
0
        goto fail;
649
0
      }
650
      /* set the obj values */
651
2
      obj_obj.emulated = key;
652
2
      key = NULL;
653
2
      break;
654
655
267
    case CKO_CERTIFICATE:
656
267
      sc_log(card->ctx, "Processing certificate object %d", i);
657
267
      obj_info = &cert_info;
658
267
      memset(&cert_info, 0, sizeof(cert_info));
659
267
      coolkey_get_id(card, &coolkey_obj, &cert_info.id);
660
267
      cert_info.path = coolkey_obj.path;
661
267
      obj_type = SC_PKCS15_TYPE_CERT_X509;
662
663
      /* following will find the cached cert in cert_info */
664
267
      r = coolkey_get_certificate(card, &coolkey_obj, &cert_info.value);
665
267
      if (r < 0) {
666
118
        goto fail;
667
118
      }
668
149
      break;
669
670
671
149
    default:
672
      /* no other recognized types which are stored 'on card' */
673
50
      sc_log(card->ctx, "Unknown object type %lu, skipping", obj_class);
674
50
      continue;
675
1.45k
    }
676
677
1.16k
    r = sc_pkcs15emu_object_add(p15card, obj_type, &obj_obj, obj_info);
678
1.16k
    if (r != SC_SUCCESS)
679
0
      sc_log(card->ctx, "sc_pkcs15emu_object_add() returned %d", r);
680
4.07k
fail:
681
4.07k
    if (key) {
682
60
      sc_pkcs15_free_pubkey(key);
683
60
    }
684
4.07k
    if (r != SC_SUCCESS) {
685
2.81k
      free(cert_info.value.value);
686
2.81k
    }
687
4.07k
  }
688
632
  r = (card->ops->card_ctl)(card, SC_CARDCTL_COOLKEY_FINAL_GET_OBJECTS, &count);
689
632
  LOG_TEST_GOTO_ERR(card->ctx, r, "Can not finalize objects.");
690
691
  /* Iterate over all the created objects and fill missing labels */
692
2.42k
  for (obj = p15card->obj_list; obj != NULL; obj = obj->next) {
693
1.79k
    struct sc_pkcs15_id *id = NULL;
694
1.79k
    struct sc_pkcs15_object *cert_object;
695
696
    /* label non-empty -- do not overwrite */
697
1.79k
    if (obj->label[0] != '\0')
698
638
      continue;
699
700
1.15k
    switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
701
2
    case SC_PKCS15_TYPE_PUBKEY:
702
2
      id = &((struct sc_pkcs15_pubkey_info *)obj->data)->id;
703
2
      break;
704
1.00k
    case SC_PKCS15_TYPE_PRKEY:
705
1.00k
      id = &((struct sc_pkcs15_prkey_info *)obj->data)->id;
706
1.00k
      break;
707
147
    default:
708
      /* We do not care about other objects */
709
147
      continue;
710
1.15k
    }
711
1.00k
    r = sc_pkcs15_find_cert_by_id(p15card, id, &cert_object);
712
1.00k
    if (r != 0)
713
942
      continue;
714
715
67
    sc_log(card->ctx, "Copy label \"%s\" from cert to key object",
716
67
      cert_object->label);
717
67
    memcpy(obj->label, cert_object->label, SC_PKCS15_MAX_LABEL_SIZE);
718
67
  }
719
720
632
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
721
722
0
err:
723
0
  sc_pkcs15_card_clear(p15card);
724
0
  p15card->opts.use_pin_cache = use_pin_cache_backup;
725
726
0
  LOG_FUNC_RETURN(card->ctx, r);
727
0
}
728
729
int
730
sc_pkcs15emu_coolkey_init_ex(sc_pkcs15_card_t *p15card,
731
    struct sc_aid *aid)
732
8.75k
{
733
8.75k
  sc_card_t      *card = p15card->card;
734
8.75k
  sc_context_t    *ctx = card->ctx;
735
8.75k
  int rv;
736
737
8.75k
  LOG_FUNC_CALLED(ctx);
738
739
8.75k
  rv = coolkey_detect_card(p15card);
740
8.75k
  if (rv)
741
8.75k
    LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_CARD);
742
632
  rv = sc_pkcs15emu_coolkey_init(p15card);
743
744
632
  LOG_FUNC_RETURN(ctx, rv);
745
632
}