Coverage Report

Created: 2025-08-26 06:43

/src/opensc/src/libopensc/card-coolkey.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * card-coolkey.c: Support for Coolkey
3
 *
4
 * Copyright (C) 2001, 2002  Juha Yrjölä <juha.yrjola@iki.fi>
5
 * Copyright (C) 2005,2006,2007,2008,2009,2010 Douglas E. Engert <deengert@anl.gov>
6
 * Copyright (C) 2006, Identity Alliance, Thomas Harning <thomas.harning@identityalliance.com>
7
 * Copyright (C) 2007, EMC, Russell Larner <rlarner@rsa.com>
8
 * Copyright (C) 2016, Red Hat, Inc.
9
 *
10
 * Coolkey driver author: Robert Relyea <rrelyea@redhat.com>
11
 *
12
 * This library is free software; you can redistribute it and/or
13
 * modify it under the terms of the GNU Lesser General Public
14
 * License as published by the Free Software Foundation; either
15
 * version 2.1 of the License, or (at your option) any later version.
16
 *
17
 * This library is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20
 * Lesser General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Lesser General Public
23
 * License along with this library; if not, write to the Free Software
24
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25
 */
26
27
#ifdef HAVE_CONFIG_H
28
#include "config.h"
29
#endif
30
31
#include <ctype.h>
32
#include <fcntl.h>
33
#include <limits.h>
34
#include <stdlib.h>
35
#include <string.h>
36
37
#ifdef _WIN32
38
#include <io.h>
39
#else
40
#include <unistd.h>
41
#endif
42
43
#include <sys/types.h>
44
45
#include "internal.h"
46
#include "asn1.h"
47
#include "cardctl.h"
48
#ifdef ENABLE_ZLIB
49
#include "compression.h"
50
#endif
51
#include "iso7816.h"
52
#include "gp.h"
53
#include "../pkcs11/pkcs11.h"
54
55
#ifdef _MSC_VER
56
#define PACKED
57
#pragma pack(push,1)
58
#elif defined(__GNUC__)
59
#define PACKED __attribute__ ((__packed__))
60
#endif
61
62
#define COOLKEY_MAX_SIZE 4096   /* arbitrary, just needs to be 'large enough' */
63
64
/*
65
 *  COOLKEY hardware and APDU constants
66
 */
67
461
#define COOLKEY_MAX_CHUNK_SIZE 240 /* must be less than 255-8 */
68
69
/* ISO 7816 CLA values used by COOLKEY */
70
6.61k
#define ISO7816_CLASS           0x00
71
6.78k
#define COOLKEY_CLASS           0xb0
72
73
/* ISO 71816 INS values used by COOLKEY */
74
6.61k
#define ISO7816_INS_SELECT_FILE 0xa4
75
76
/* COOLKEY specific INS values (public) */
77
691
#define COOLKEY_INS_GET_LIFE_CYCLE             0xf2
78
680
#define COOLKEY_INS_GET_STATUS                 0x3c
79
0
#define COOLKEY_INS_VERIFY_PIN                 0x42
80
3.60k
#define COOLKEY_INS_LIST_OBJECTS               0x58
81
82
/* COOLKEY specific INS values (require nonce) */
83
0
#define COOLKEY_INS_COMPUTE_CRYPT              0x36
84
0
#define COOLKEY_INS_COMPUTE_ECC_KEY_AGREEMENT  0x37
85
0
#define COOLKEY_INS_COMPUTE_ECC_SIGNATURE      0x38
86
#define COOLKEY_INS_GET_RANDOM                 0x72
87
1.80k
#define COOLKEY_INS_READ_OBJECT                0x56
88
0
#define COOLKEY_INS_WRITE_OBJECT               0x54
89
0
#define COOLKEY_INS_LOGOUT                     0x61
90
91
/* COMPUTE_CRYPT and COMPUT_ECC parameters */
92
#define COOLKEY_CRYPT_INIT     1
93
#define COOLKEY_CRYPT_PROCESS  2
94
#define COOLKEY_CRYPT_FINAL    3
95
0
#define COOLKEY_CRYPT_ONE_STEP 4
96
97
0
#define COOLKEY_CRYPT_MODE_RSA_NO_PAD    0x00
98
0
#define COOLKEY_CRYPT_LOCATION_APDU      0x01
99
0
#define COOLKEY_CRYPT_LOCATION_DL_OBJECT 0x02
100
0
#define COOLKEY_CRYPT_DIRECTION_ENCRYPT  0x03
101
102
/* List Objects parameters */
103
531
#define COOLKEY_LIST_RESET 0x00
104
3.07k
#define COOLKEY_LIST_NEXT  0x01
105
106
/* Special object identifiers */
107
0
#define COOLKEY_DL_OBJECT_ID       0xffffffff
108
3.68k
#define COOLKEY_COMBINED_OBJECT_ID 0x7a300000 /* 'z0\0\0' */
109
614
#define COOLKEY_INVALID_KEY        0xff00
110
0
#define COOLKEY_KEY_CLASS     'k'
111
#define COOLKEY_NONCE_SIZE  8
112
113
/* returned from the coolkey extended life cycle apdu */
114
typedef struct coolkey_life_cycle {
115
  u8 life_cycle;
116
  u8 pin_count;
117
  u8 protocol_version_major;
118
  u8 protocol_version_minor;
119
} coolkey_life_cycle_t;
120
121
/* return by the coolkey status apdu */
122
typedef struct coolkey_status {
123
  u8 protocol_version_major;
124
  u8 protocol_version_minor;
125
  u8 applet_major_version;
126
  u8 applet_minor_version;
127
  u8 total_object_memory[4];
128
  u8 free_object_memory[4];
129
  u8 pin_count;
130
  u8 key_count;
131
  u8 logged_in_identities[2];
132
} coolkey_status_t;
133
134
/* format of the coolkey_cuid, either constructed from cplc data or read from the combined object */
135
typedef struct coolkey_cuid {
136
  u8 ic_fabricator[2];
137
  u8 ic_type[2];
138
  u8 ic_batch[2];
139
  u8 ic_serial_number[4];
140
} coolkey_cuid_t;
141
142
/* parameter for list objects apdu */
143
typedef struct coolkey_object_info {
144
  u8 object_id[4];
145
  u8 object_length[4];
146
  u8 read_acl[2];
147
  u8 write_acl[2];
148
  u8 delete_acl[2];
149
} coolkey_object_info_t;
150
151
/* parameter for the read object apdu */
152
typedef struct coolkey_read_object_param {
153
  u8 object_id[4];
154
  u8 offset[4];
155
  u8 length;
156
} coolkey_read_object_param_t;
157
158
/* parameter for the write object apdu */
159
typedef struct coolkey_write_object_param {
160
  coolkey_read_object_param_t head;
161
  u8 buf[COOLKEY_MAX_CHUNK_SIZE];
162
} coolkey_write_object_param_t;
163
164
/* coolkey uses muscle like objects, but when coolkey is managed by the TPS system
165
 * it creates a single object and encodes the individual objects inside the
166
 * common single object. This allows more efficient reading of all the objects
167
 * (because we can use a single apdu call and we can compress all the objects
168
 * together and take advantage of the fact that many of the certs share the same subject and issue). */
169
typedef struct coolkey_combined_header {
170
  u8  format_version[2];
171
  u8  object_version[2];
172
  coolkey_cuid_t cuid;
173
  u8  compression_type[2];
174
  u8  compression_length[2];
175
  u8  compression_offset[2];
176
} coolkey_combined_header_t;
177
178
#define COOLKEY_COMPRESSION_NONE 0
179
194
#define COOLKEY_COMPRESSION_ZLIB 1
180
181
/*
182
 * This is the header of the decompressed portion of the combined object
183
 */
184
typedef struct coolkey_decompressed_header {
185
  u8 object_offset[2];
186
  u8 object_count[2];
187
  u8 token_name_length;
188
  u8 token_name[255];      /* arbitrary size up to token_name_length */
189
} PACKED coolkey_decompressed_header_t;
190
191
/*
192
 * header for an object. There are 2 types of object headers, v1 and v0.
193
 * v1 is the most common, and is always found in a combined object, so
194
 * we only specify the v0 in the name of the structure.
195
 */
196
197
typedef struct coolkey_v0_object_header {
198
  u8 record_type;        /* version 0 or version 1 */
199
  u8 object_id[4];       /*  coolkey object id  */
200
  u8 attribute_data_len[2];    /* the length in bytes of the next block of
201
                  * attribute records */
202
  /* followed by the first attribute record */
203
} coolkey_v0_object_header_t;
204
205
typedef struct coolkey_v0_attribute_header {
206
  u8 attribute_attr_type[4];  /* CKA_ATTRIBUTE_TYPE */
207
  u8 attribute_data_len[2]; /* Length of the attribute */
208
  /* followed by the actual attribute data */
209
} coolkey_v0_attribute_header_t;
210
211
/* combined objects are v1 objects without the record_type indicator */
212
typedef struct coolkey_combined_object_header {
213
  u8 object_id[4];       /*  coolkey object id  */
214
  u8 fixed_attributes_values[4]; /* compressed fixed attributes */
215
  u8 attribute_count[2];    /* the number of attribute records that follow */
216
  /* followed by the first attribute */
217
} coolkey_combined_object_header_t;
218
219
typedef struct coolkey_object_header {
220
  u8 record_type;       /* version 0 or version 1 */
221
  u8 object_id[4];       /*  coolkey object id  */
222
  u8 fixed_attributes_values[4]; /* compressed fixed attributes */
223
  u8 attribute_count[2];    /* the number of attribute records that follow */
224
  /* followed by the first attribute */
225
} coolkey_object_header_t;
226
227
0
#define COOLKEY_V0_OBJECT 0
228
191
#define COOLKEY_V1_OBJECT 1
229
230
/* vi attribute header */
231
typedef struct coolkey_attribute_header {
232
  u8 attribute_attr_type[4]; /* CKA_ATTRIBUTE_TYPE */
233
  u8 attribute_data_type;    /* the Type of data stored */
234
  /* optional attribute data, or attribute len+data, depending on the value of data_type */
235
} coolkey_attribute_header_t;
236
237
#ifdef _MSC_VER
238
#undef PACKED
239
#pragma pack(pop)
240
#elif defined(__GNUC__)
241
#undef PACKED
242
#endif
243
244
/* values for attribute_data_type */
245
391
#define COOLKEY_ATTR_TYPE_STRING      0
246
285
#define COOLKEY_ATTR_TYPE_INTEGER     1
247
336
#define COOLKEY_ATTR_TYPE_BOOL_FALSE  2
248
556
#define COOLKEY_ATTR_TYPE_BOOL_TRUE   3
249
250
/*
251
 * format of the fix_attribute values. These are stored as a big endian uint32_t with the below bit field
252
 * Definitions:
253
 *
254
struct coolkey_fixed_attributes_values {
255
  uint32_t  cka_id:4;
256
  uint32_t  cka_class:3;
257
  uint32_t  cka_token:1;
258
  uint32_t  cka_private:1;
259
  uint32_t  cka_modifiable:1;
260
  uint32_t  cka_derive:1;
261
  uint32_t  cka_local:1;
262
  uint32_t  cka_encrypt:1;
263
  uint32_t  cka_decrypt:1;
264
  uint32_t  cka_wrap:1;
265
  uint32_t  cka_unwrap:1;
266
  uint32_t  cka_sign:1;
267
  uint32_t  cka_sign_recover:1;
268
  uint32_t  cka_verify:1;
269
  uint32_t  cka_verify_recover:1;
270
  uint32_t  cka_sensitive:1;
271
  uint32_t  cka_always_sensitive:1;
272
  uint32_t  cka_extractable:1;
273
  uint32_t  cka_never_extractable:1;
274
  uint32_t  reserved:8;
275
};
276
277
 *  cka_class is used to determine which booleans are valid. Any attributes in the full attribute list
278
 *  takes precedence over the fixed attributes. That is if there is a CKA_ID in the full attribute list,
279
 *  The cka_id in the fixed_attributes is ignored. When determining which boolean attribute is valid, the
280
 *  cka_class in the fixed attributes are used, even if it is overridden by the  full attribute list.
281
 * valid cka_class values and their corresponding valid bools are as follows:
282
 *
283
 *     0 CKO_DATA                          cka_private, cka_modifiable, cka_token
284
 *     1 CKO_CERTIFICATE                   cka_private, cka_modifiable, cka_token
285
 *     2 CKO_PUBLIC_KEY                    cka_private, cka_modifiable, cka_token
286
 *                                         cka_derive, cka_local, cka_encrypt, cka_wrap
287
 *                                         cka_verify, cka_verify_recover
288
 *     3 CKO_PRIVATE_KEY                   cka_private, cka_modifiable, cka_token
289
 *                                         cka_derive, cka_local, cka_decrypt, cka_unwrap
290
 *                                         cka_sign, cka_sign_recover, cka_sensitive,
291
 *                                         cka_always_sensitive, cka_extractable,
292
 *                                         cka_never_extractable
293
 *     4 CKO_SECRET_KEY                    cka_private, cka_modifiable, cka_token
294
 *                                         cka_derive, cka_local, cka_encrypt, cka_decrypt,
295
 *                                         cka_wrap, cka_unwrap, cka_sign, cka_verify,
296
 *                                         cka_sensitive, cka_always_sensitive,
297
 *                                         cka_extractable, cka_never_extractable
298
 *     5-7 RESERVED                        none
299
 *
300
 */
301
302
/*
303
 * Coolkey attribute record handling functions.
304
 */
305
306
/* get the length of the attribute from a V1 attribute header. If encoded_len == true, then return the length of
307
 * the attribute data field (including any explicit length values, If encoded_len = false return the length of
308
 * the actual attribute data.
309
 */
310
static int
311
coolkey_v1_get_attribute_len(const u8 *attr, size_t buf_len, size_t *len, int encoded_len)
312
1.68M
{
313
1.68M
  coolkey_attribute_header_t *attribute_head = (coolkey_attribute_header_t *)attr;
314
315
1.68M
  *len = 0;
316
  /* don't reference beyond our buffer */
317
1.68M
  if (buf_len < sizeof(coolkey_attribute_header_t)) {
318
1.68M
    return SC_ERROR_CORRUPTED_DATA;
319
1.68M
  }
320
1.29k
  switch (attribute_head->attribute_data_type) {
321
391
  case COOLKEY_ATTR_TYPE_STRING:
322
391
    if (buf_len < (sizeof(coolkey_attribute_header_t) +2)) {
323
1
      break;
324
1
    }
325
390
    *len = bebytes2ushort(attr + sizeof(coolkey_attribute_header_t));
326
390
    if (encoded_len) {
327
390
      *len += 2;
328
390
    }
329
390
    return SC_SUCCESS;
330
336
  case COOLKEY_ATTR_TYPE_BOOL_FALSE:
331
556
  case COOLKEY_ATTR_TYPE_BOOL_TRUE:
332
    /* NOTE: there is no encoded data from TYPE_BOOL_XXX, so we return length 0, but the length
333
     * of the attribute is actually 1 byte, so if encoded_len == false, return 1 */
334
556
    *len = encoded_len ? 0: 1;
335
556
    return SC_SUCCESS;
336
0
    break;
337
285
  case COOLKEY_ATTR_TYPE_INTEGER:
338
285
    *len = 4; /* length is 4 in both encoded length and attribute length */
339
285
    return SC_SUCCESS;
340
64
  default:
341
64
    break;
342
1.29k
  }
343
65
  return SC_ERROR_CORRUPTED_DATA;
344
1.29k
}
345
346
/* length of the attribute data is stored in the header of the v0 record */
347
static int
348
coolkey_v0_get_attribute_len(const u8 *attr, size_t buf_len, size_t *len)
349
0
{
350
0
  coolkey_v0_attribute_header_t *attribute_head = (coolkey_v0_attribute_header_t *)attr;
351
  /* don't reference beyond our buffer */
352
0
  if (buf_len < sizeof(coolkey_v0_attribute_header_t)) {
353
0
    return SC_ERROR_CORRUPTED_DATA;
354
0
  }
355
0
  *len = bebytes2ushort(attribute_head->attribute_data_len);
356
0
  return SC_SUCCESS;
357
0
}
358
359
/* these next 3 functions gets the length of the full attribute record, including
360
 * the attribute header */
361
static size_t
362
coolkey_v1_get_attribute_record_len(const u8 *attr, size_t buf_len)
363
1.68M
{
364
1.68M
  size_t attribute_len = sizeof(coolkey_attribute_header_t);
365
1.68M
  size_t len = 0;
366
1.68M
  int r;
367
368
1.68M
  r = coolkey_v1_get_attribute_len(attr, buf_len, &len, 1);
369
1.68M
  if (r < 0) {
370
1.68M
    return buf_len; /* skip to the end, ignore the rest of the record */
371
1.68M
  }
372
373
1.23k
  return MIN(buf_len,attribute_len+len);
374
1.68M
}
375
376
377
static size_t
378
coolkey_v0_get_attribute_record_len(const u8 *attr, size_t buf_len)
379
0
{
380
0
  size_t attribute_len = sizeof(coolkey_v0_attribute_header_t);
381
0
  size_t len;
382
0
  int r;
383
384
0
  r = coolkey_v0_get_attribute_len(attr, buf_len, &len);
385
0
  if (r < 0) {
386
0
    return buf_len; /* skip to the end, ignore the rest of the record */
387
0
  }
388
0
  return MIN(buf_len,attribute_len+len);
389
0
}
390
391
static size_t
392
coolkey_get_attribute_record_len(const u8 *attr, u8 obj_record_type, size_t buf_len)
393
0
{
394
0
  if (obj_record_type ==  COOLKEY_V0_OBJECT) {
395
0
    return coolkey_v0_get_attribute_record_len(attr, buf_len);
396
0
  }
397
0
  if (obj_record_type != COOLKEY_V1_OBJECT) {
398
0
    return buf_len; /* skip to the end */
399
0
  }
400
0
  return coolkey_v1_get_attribute_record_len(attr, buf_len);
401
0
}
402
403
/*
404
 * Attribute type shows up in the same place in all attribute record types. Carry record_type in case
405
 * this changes in the future.
406
 */
407
static CK_ATTRIBUTE_TYPE
408
coolkey_get_attribute_type(const u8 *attr, u8 obj_record_type, size_t buf_len)
409
0
{
410
0
  coolkey_attribute_header_t *attribute_header = (coolkey_attribute_header_t *) attr;
411
412
0
  return bebytes2ulong(attribute_header->attribute_attr_type);
413
0
}
414
415
/*
416
 * return the start of the attribute section based on the record type
417
 */
418
static const u8 *
419
coolkey_attribute_start(const u8 *obj, u8 object_record_type, size_t buf_len)
420
0
{
421
0
  size_t offset = object_record_type == COOLKEY_V1_OBJECT ? sizeof(coolkey_object_header_t) :
422
0
      sizeof(coolkey_v0_object_header_t);
423
424
0
  if ((object_record_type != COOLKEY_V1_OBJECT) && (object_record_type != COOLKEY_V0_OBJECT)) {
425
0
    return NULL;
426
0
  }
427
0
  if (offset > buf_len) {
428
0
    return NULL;
429
0
  }
430
0
  return obj + offset;
431
0
}
432
433
/*
434
 * We don't have the count in the header for v0 attributes,
435
 * Count them.
436
 */
437
static int
438
coolkey_v0_get_attribute_count(const u8 *obj, size_t buf_len)
439
0
{
440
0
  coolkey_v0_object_header_t *object_head = (coolkey_v0_object_header_t *)obj;
441
0
  const u8 *attr;
442
0
  int count = 0;
443
0
  size_t attribute_data_len;
444
445
  /* make sure we have enough of the object to read the record_type */
446
0
  if (buf_len <= sizeof(coolkey_v0_object_header_t)) {
447
0
    return 0;
448
0
  }
449
  /*
450
   * now loop through all the attributes in the list. first find the start of the list
451
   */
452
0
  attr = coolkey_attribute_start(obj, COOLKEY_V0_OBJECT, buf_len);
453
0
  if (attr == NULL) {
454
0
    return 0;
455
0
  }
456
457
0
  buf_len -= (attr-obj);
458
0
  attribute_data_len = bebytes2ushort(object_head->attribute_data_len);
459
0
  if (buf_len < attribute_data_len) {
460
0
    return 0;
461
0
  }
462
463
0
  while (attribute_data_len) {
464
0
    size_t len = coolkey_v0_get_attribute_record_len(attr, buf_len);
465
466
0
    if (len == 0) {
467
0
      break;
468
0
    }
469
    /*  This is an error in the token data, don't parse the last attribute */
470
0
    if (len > attribute_data_len) {
471
0
      break;
472
0
    }
473
    /* we know that coolkey_v0_get_attribute_record_len never
474
     *  returns more than buf_len, so we can safely assert that.
475
     *  If the assert is true, you can easily see that the loop
476
     *  will eventually break with len == 0, even if attribute_data_len
477
     *  was invalid */
478
0
    assert(len <= buf_len);
479
0
    count++;
480
0
    attr += len;
481
0
    buf_len -= len;
482
0
    attribute_data_len -= len;
483
0
  }
484
0
  return count;
485
0
}
486
487
static int
488
coolkey_v1_get_attribute_count(const u8 *obj, size_t buf_len)
489
0
{
490
0
  coolkey_object_header_t *object_head = (coolkey_object_header_t *)obj;
491
492
0
  if (buf_len <= sizeof(coolkey_object_header_t)) {
493
0
    return 0;
494
0
  }
495
0
  return bebytes2ushort(object_head->attribute_count);
496
0
}
497
498
static int
499
coolkey_get_attribute_count(const u8 *obj, u8 object_record_type, size_t buf_len)
500
0
{
501
0
  if (object_record_type == COOLKEY_V0_OBJECT) {
502
0
    return coolkey_v0_get_attribute_count(obj, buf_len);
503
0
  }
504
0
  if (object_record_type != COOLKEY_V1_OBJECT) {
505
0
    return 0;
506
0
  }
507
0
  return coolkey_v1_get_attribute_count(obj, buf_len);
508
0
}
509
510
/*
511
 * The next three functions return a parsed attribute value from an attribute record.
512
 */
513
static int
514
coolkey_v0_get_attribute_data(const u8 *attr, size_t buf_len, sc_cardctl_coolkey_attribute_t *attr_out)
515
0
{
516
  /* we need to manually detect types CK_ULONG */
517
0
  CK_ATTRIBUTE_TYPE attr_type = coolkey_get_attribute_type(attr, COOLKEY_V0_OBJECT, buf_len);
518
0
  int r;
519
0
  size_t len;
520
521
0
  attr_out->attribute_data_type = SC_CARDCTL_COOLKEY_ATTR_TYPE_STRING;
522
0
  attr_out->attribute_length = 0;
523
0
  attr_out->attribute_value = NULL;
524
525
0
  r = coolkey_v0_get_attribute_len(attr, buf_len, &len);
526
0
  if (r < 0) {
527
0
    return r;
528
0
  }
529
0
  if (len + sizeof(coolkey_v0_attribute_header_t) > buf_len) {
530
0
    return SC_ERROR_CORRUPTED_DATA;
531
0
  }
532
0
  if ((attr_type == CKA_CLASS) || (attr_type == CKA_CERTIFICATE_TYPE)
533
0
                   || (attr_type == CKA_KEY_TYPE)) {
534
0
    if (len != 4) {
535
0
      return SC_ERROR_CORRUPTED_DATA;
536
0
    }
537
0
    attr_out->attribute_data_type = SC_CARDCTL_COOLKEY_ATTR_TYPE_ULONG;
538
0
  }
539
  /* return the length and the data */
540
0
  attr_out->attribute_length = len;
541
0
  attr_out->attribute_value = attr + sizeof(coolkey_v0_attribute_header_t);
542
0
  return SC_SUCCESS;
543
0
}
544
545
static u8 coolkey_static_false = CK_FALSE;
546
static u8 coolkey_static_true = CK_TRUE;
547
548
static int
549
coolkey_v1_get_attribute_data(const u8 *attr, size_t buf_len, sc_cardctl_coolkey_attribute_t *attr_out)
550
0
{
551
0
  int r;
552
0
  size_t len;
553
0
  coolkey_attribute_header_t *attribute_head = (coolkey_attribute_header_t *)attr;
554
555
0
  if (buf_len < sizeof(coolkey_attribute_header_t)) {
556
0
    return SC_ERROR_CORRUPTED_DATA;
557
0
  }
558
559
  /* we must have type V1. Process according to data type */
560
0
  switch (attribute_head->attribute_data_type) {
561
  /* ULONG has implied length of 4 */
562
0
  case COOLKEY_ATTR_TYPE_INTEGER:
563
0
    if (buf_len < (sizeof(coolkey_attribute_header_t) + 4)) {
564
0
      return SC_ERROR_CORRUPTED_DATA;
565
0
    }
566
0
    attr_out->attribute_data_type = SC_CARDCTL_COOLKEY_ATTR_TYPE_ULONG;
567
0
    attr_out->attribute_length = 4;
568
0
    attr_out->attribute_value = attr + sizeof(coolkey_attribute_header_t);
569
0
    return SC_SUCCESS;
570
  /* BOOL_FALSE and BOOL_TRUE have implied length and data */
571
  /* return type STRING for BOOLS */
572
0
  case COOLKEY_ATTR_TYPE_BOOL_FALSE:
573
0
    attr_out->attribute_length = 1;
574
0
    attr_out->attribute_value =  &coolkey_static_false;
575
0
    return SC_SUCCESS;
576
0
  case COOLKEY_ATTR_TYPE_BOOL_TRUE:
577
0
    attr_out->attribute_length = 1;
578
0
    attr_out->attribute_value =  &coolkey_static_true;
579
0
    return SC_SUCCESS;
580
  /* string type has encoded length */
581
0
  case COOLKEY_ATTR_TYPE_STRING:
582
0
    r = coolkey_v1_get_attribute_len(attr, buf_len, &len, 0);
583
0
    if (r < SC_SUCCESS) {
584
0
      return r;
585
0
    }
586
0
    if (buf_len < (len + sizeof(coolkey_attribute_header_t) + 2)) {
587
0
      return SC_ERROR_CORRUPTED_DATA;
588
0
    }
589
0
    attr_out->attribute_value = attr+sizeof(coolkey_attribute_header_t)+2;
590
0
    attr_out->attribute_length = len;
591
0
    return SC_SUCCESS;
592
0
  default:
593
0
    break;
594
0
  }
595
0
  return SC_ERROR_CORRUPTED_DATA;
596
0
}
597
598
int
599
coolkey_get_attribute_data(const u8 *attr, u8 object_record_type, size_t buf_len, sc_cardctl_coolkey_attribute_t *attr_out)
600
0
{
601
  /* handle the V0 objects first */
602
0
  if (object_record_type == COOLKEY_V0_OBJECT) {
603
0
    return coolkey_v0_get_attribute_data(attr, buf_len, attr_out);
604
0
  }
605
606
  /* don't crash if we encounter some new or corrupted coolkey device */
607
0
  if (object_record_type != COOLKEY_V1_OBJECT) {
608
0
    return SC_ERROR_NO_CARD_SUPPORT;
609
0
  }
610
611
0
  return coolkey_v1_get_attribute_data(attr, buf_len, attr_out);
612
613
0
}
614
615
/* convert an attribute type into a  bit in the fixed attribute uint32_t  */
616
static unsigned long
617
coolkey_get_fixed_boolean_bit(CK_ATTRIBUTE_TYPE type)
618
0
{
619
0
  switch(type) {
620
0
  case CKA_TOKEN:               return 0x00000080;
621
0
  case CKA_PRIVATE:             return 0x00000100;
622
0
  case CKA_MODIFIABLE:          return 0x00000200;
623
0
  case CKA_DERIVE:              return 0x00000400;
624
0
  case CKA_LOCAL:               return 0x00000800;
625
0
  case CKA_ENCRYPT:             return 0x00001000;
626
0
  case CKA_DECRYPT:             return 0x00002000;
627
0
  case CKA_WRAP:                return 0x00004000;
628
0
  case CKA_UNWRAP:              return 0x00008000;
629
0
  case CKA_SIGN:                return 0x00010000;
630
0
  case CKA_SIGN_RECOVER:        return 0x00020000;
631
0
  case CKA_VERIFY:              return 0x00040000;
632
0
  case CKA_VERIFY_RECOVER:      return 0x00080000;
633
0
  case CKA_SENSITIVE:           return 0x00100000;
634
0
  case CKA_ALWAYS_SENSITIVE:    return 0x00200000;
635
0
  case CKA_EXTRACTABLE:         return 0x00400000;
636
0
  case CKA_NEVER_EXTRACTABLE:   return 0x00800000;
637
0
  default: break;
638
0
  }
639
0
  return 0; /* return no bits */
640
0
}
641
/* This table lets us return a pointer to the CKA_ID value without allocating data or
642
 * creating a changeable static that could cause thread issues */
643
static const u8 coolkey_static_cka_id[16] = {
644
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
645
};
646
647
/* This table provides the following:
648
 *     1) a mapping from a 3 bit cka_class to a full 32 bit CKA_CLASS_TYPE value we can return.
649
 *     2) the mask of valid boolean attributes in the fixed attributes.
650
 */
651
struct coolkey_fixed_class {
652
  u8 class_value[4];
653
  unsigned long boolean_mask;
654
};
655
656
static const struct coolkey_fixed_class coolkey_static_cka_class[8] = {
657
  { { 0, 0, 0, 0}, 0x00000380 }, /* DATA */
658
  { { 0, 0, 0, 1}, 0x00000380 }, /* CERTIFICATE */
659
  { { 0, 0, 0, 2}, 0x000c5f80 }, /* PUBLIC_KEY */
660
  { { 0, 0, 0, 3}, 0x00f3af80 }, /* PRIVATE_KEY */
661
  { { 0, 0, 0, 4}, 0x00f5ff80 }, /* SECRET_KEY */
662
  { { 0, 0, 0, 5}, 0x00000000 },
663
  { { 0, 0, 0, 6}, 0x00000000 },
664
  { { 0, 0, 0, 7}, 0x00000000 }
665
};
666
667
/*
668
 * handle fixed attributes (V1 only)
669
 */
670
static int
671
coolkey_get_attribute_data_fixed(CK_ATTRIBUTE_TYPE attr_type, unsigned long fixed_attributes,
672
0
                                sc_cardctl_coolkey_attribute_t *attr_out) {
673
0
  unsigned long cka_id = fixed_attributes & 0xf;
674
0
  unsigned long cka_class = ((fixed_attributes) >> 4) & 0x7;
675
0
  unsigned long mask, bit;
676
677
0
  if (attr_type == CKA_ID) {
678
0
    attr_out->attribute_length = 1;
679
0
    attr_out->attribute_value= &coolkey_static_cka_id[cka_id];
680
0
    return SC_SUCCESS;
681
0
  }
682
0
  if (attr_type == CKA_CLASS) {
683
0
    attr_out->attribute_data_type = SC_CARDCTL_COOLKEY_ATTR_TYPE_ULONG;
684
0
    attr_out->attribute_length = 4;
685
0
    attr_out->attribute_value = coolkey_static_cka_class[cka_class].class_value;
686
0
    return SC_SUCCESS;
687
0
  }
688
  /* If it matched, it must be one of the booleans */
689
0
  mask = coolkey_static_cka_class[cka_class].boolean_mask;
690
0
  bit = coolkey_get_fixed_boolean_bit(attr_type);
691
  /* attribute isn't in the list */
692
0
  if ((bit & mask) == 0) {
693
0
    return SC_ERROR_DATA_OBJECT_NOT_FOUND;
694
0
  }
695
0
  attr_out->attribute_length = 1;
696
0
  attr_out->attribute_value = bit & fixed_attributes ? &coolkey_static_true : &coolkey_static_false;
697
0
  return SC_SUCCESS;
698
0
}
699
700
701
702
static int
703
coolkey_v1_get_object_length(u8 *obj, size_t buf_len)
704
204
{
705
204
  coolkey_combined_object_header_t *object_head = (coolkey_combined_object_header_t *) obj;
706
204
  int attribute_count;
707
204
  u8 *current_attribute;
708
204
  int j;
709
204
  size_t len;
710
711
204
  len = sizeof(coolkey_combined_object_header_t);
712
204
  if (buf_len <= len) {
713
1
    return (int)buf_len;
714
1
  }
715
203
  attribute_count = bebytes2ushort(object_head->attribute_count);
716
203
  buf_len -= len;
717
718
1.68M
  for (current_attribute = obj + len, j = 0; j < attribute_count; j++) {
719
1.68M
    size_t attribute_len = coolkey_v1_get_attribute_record_len(current_attribute, buf_len);
720
721
1.68M
    len += attribute_len;
722
1.68M
    current_attribute += attribute_len;
723
1.68M
    buf_len -= attribute_len;
724
1.68M
  }
725
203
  return (int)len;
726
204
}
727
728
/*
729
 * COOLKEY private data per card state
730
 */
731
typedef struct coolkey_private_data {
732
  u8 protocol_version_major;
733
  u8 protocol_version_minor;
734
  u8 format_version_major;
735
  u8 format_version_minor;
736
  unsigned short object_version;
737
  u8 life_cycle;
738
  u8 pin_count;
739
  u8 *token_name;       /* our token name read from the token */
740
  size_t token_name_length;   /* length of our token name */
741
  u8 nonce[COOLKEY_NONCE_SIZE];   /* nonce returned from login */
742
  int nonce_valid;
743
  coolkey_cuid_t cuid;      /* card unique ID from the CCC */
744
  sc_cardctl_coolkey_object_t *obj; /* pointer to the current selected object */
745
  list_t objects_list;      /* list of objects on the token */
746
  unsigned short key_id;      /* key id set by select */
747
  unsigned long algorithm;      /* saved from set_security_env */
748
  int operation;        /* saved from set_security_env */
749
} coolkey_private_data_t;
750
751
86
#define COOLKEY_DATA(card) ((coolkey_private_data_t*)card->drv_data)
752
753
int
754
coolkey_compare_id(const void * a, const void *b)
755
17.7k
{
756
17.7k
  if (a == NULL || b == NULL)
757
0
    return 1;
758
17.7k
  return ((sc_cardctl_coolkey_object_t *)a)->id
759
17.7k
      != ((sc_cardctl_coolkey_object_t *)b)->id;
760
17.7k
}
761
762
/* For SimCList autocopy, we need to know the size of the data elements */
763
893
size_t coolkey_list_meter(const void *el) {
764
893
  return sizeof(sc_cardctl_coolkey_object_t);
765
893
}
766
767
static void coolkey_free_private_data(coolkey_private_data_t *priv);
768
769
static coolkey_private_data_t *coolkey_new_private_data(void)
770
614
{
771
614
  coolkey_private_data_t *priv;
772
773
  /* allocate priv and zero all the fields */
774
614
  priv = calloc(1, sizeof(coolkey_private_data_t));
775
614
  if (!priv)
776
0
    return NULL;
777
778
  /* set other fields as appropriate */
779
614
  priv->key_id = COOLKEY_INVALID_KEY;
780
614
  if (list_init(&priv->objects_list) != 0 ||
781
614
      list_attributes_comparator(&priv->objects_list, coolkey_compare_id) != 0 ||
782
614
      list_attributes_copy(&priv->objects_list, coolkey_list_meter, 1) != 0) {
783
0
    coolkey_free_private_data(priv);
784
0
    return NULL;
785
0
  }
786
787
614
  return priv;
788
614
}
789
790
static void coolkey_free_private_data(coolkey_private_data_t *priv)
791
614
{
792
614
  list_t *l = &priv->objects_list;
793
614
  sc_cardctl_coolkey_object_t *o;
794
795
  /* Clean up the allocated memory in the items */
796
614
  list_iterator_start(l);
797
1.50k
  while (list_iterator_hasnext(l)) {
798
893
    o = (sc_cardctl_coolkey_object_t *)list_iterator_next(l);
799
893
    free(o->data);
800
893
    o->data = NULL;
801
893
  }
802
614
  list_iterator_stop(l);
803
804
614
  list_destroy(&priv->objects_list);
805
614
  free(priv->token_name);
806
614
  free(priv);
807
614
  return;
808
614
}
809
810
/*
811
 * Object list operations
812
 */
813
static int coolkey_add_object_to_list(list_t *list, const sc_cardctl_coolkey_object_t *object)
814
893
{
815
893
  if (list_append(list, object) < 0)
816
0
    return SC_ERROR_UNKNOWN;
817
893
  return SC_SUCCESS;
818
893
}
819
820
6.51k
#define COOLKEY_AID "\xA0\x00\x00\x01\x16"
821
static sc_cardctl_coolkey_object_t *
822
coolkey_find_object_by_id(list_t *list, unsigned long object_id)
823
3.25k
{
824
3.25k
  int pos;
825
3.25k
  static sc_cardctl_coolkey_object_t cmp = {{
826
3.25k
    "", 0, 0, 0, SC_PATH_TYPE_DF_NAME,
827
3.25k
    { COOLKEY_AID, sizeof(COOLKEY_AID)-1 }
828
3.25k
  }, 0, 0, NULL};
829
830
3.25k
  cmp.id = object_id;
831
3.25k
  if ((pos = list_locate(list, &cmp)) < 0)
832
893
    return NULL;
833
834
2.36k
  return list_get_at(list, pos);
835
3.25k
}
836
837
838
static const sc_path_t coolkey_template_path = {
839
  "", 0, 0, 0, SC_PATH_TYPE_DF_NAME,
840
  { COOLKEY_AID, sizeof(COOLKEY_AID)-1 }
841
};
842
843
struct coolkey_error_codes_st {
844
  int sc_error;
845
  char *description;
846
};
847
848
static const struct coolkey_error_codes_st coolkey_error_codes[]= {
849
  {SC_ERROR_UNKNOWN,                       "Reserved 0x9c00" },
850
  {SC_ERROR_NOT_ENOUGH_MEMORY,             "No memory left on card" },
851
  {SC_ERROR_PIN_CODE_INCORRECT,            "Authentication failed" },
852
  {SC_ERROR_NOT_ALLOWED,                   "Operation not allowed" },
853
  {SC_ERROR_UNKNOWN,                       "Reserved 0x9c04" },
854
  {SC_ERROR_NO_CARD_SUPPORT,               "Unsupported feature" },
855
  {SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Not authorized" },
856
  {SC_ERROR_DATA_OBJECT_NOT_FOUND,         "Object not found" },
857
  {SC_ERROR_FILE_ALREADY_EXISTS,           "Object exists" },
858
  {SC_ERROR_NO_CARD_SUPPORT,               "Incorrect Algorithm" },
859
  {SC_ERROR_UNKNOWN,                       "Reserved 0x9c0a" },
860
  {SC_ERROR_SM_INVALID_CHECKSUM,           "Signature invalid" },
861
  {SC_ERROR_AUTH_METHOD_BLOCKED,           "Identity blocked" },
862
  {SC_ERROR_UNKNOWN,                       "Reserved 0x9c0d" },
863
  {SC_ERROR_UNKNOWN,                       "Reserved 0x9c0e" },
864
  {SC_ERROR_INCORRECT_PARAMETERS,          "Invalid parameter" },
865
  {SC_ERROR_INCORRECT_PARAMETERS,          "Incorrect P1" },
866
  {SC_ERROR_INCORRECT_PARAMETERS,          "Incorrect P2" },
867
  {SC_ERROR_FILE_END_REACHED,              "Sequence End" },
868
};
869
870
static const unsigned int
871
coolkey_number_of_error_codes = sizeof(coolkey_error_codes)/sizeof(coolkey_error_codes[0]);
872
873
static int coolkey_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2)
874
13.2k
{
875
13.2k
  sc_log(card->ctx,
876
13.2k
    "sw1 = 0x%02x, sw2 = 0x%02x\n", sw1, sw2);
877
878
13.2k
  if (sw1 == 0x90 && sw2 == 0x00)
879
7.39k
    return SC_SUCCESS;
880
881
5.88k
  if (sw1 == 0x9c) {
882
46
    if (sw2 == 0xff) {
883
      /* shouldn't happen on a production applet, 0x9cff is a debugging error code */
884
5
      return SC_ERROR_INTERNAL;
885
5
    }
886
41
    if (sw2 >= coolkey_number_of_error_codes) {
887
20
      return SC_ERROR_UNKNOWN;
888
20
    }
889
21
    return coolkey_error_codes[sw2].sc_error;
890
41
  }
891
892
  /* iso error */
893
5.83k
        return sc_get_iso7816_driver()->ops->check_sw(card, sw1, sw2);
894
5.88k
}
895
896
/*
897
 * Send a command and receive data.
898
 *
899
 * A caller may provide a buffer, and length to read. If not provided,
900
 * an internal 4096 byte buffer is used, and a copy is returned to the
901
 * caller. that need to be freed by the caller.
902
 *
903
 * modelled after a similar function in card-piv.c. The coolkey version
904
 * adds the coolkey nonce to user authenticated operations.
905
 */
906
907
static int coolkey_apdu_io(sc_card_t *card, int cla, int ins, int p1, int p2,
908
  const u8 * sendbuf, size_t sendbuflen, u8 ** recvbuf, size_t * recvbuflen,
909
  const u8 *nonce, size_t nonce_len)
910
13.1k
{
911
13.1k
  int r;
912
13.1k
  sc_apdu_t apdu;
913
13.1k
  u8 rbufinitbuf[COOLKEY_MAX_SIZE];
914
13.1k
  u8 rsendbuf[COOLKEY_MAX_SIZE];
915
13.1k
  u8 *rbuf;
916
13.1k
  size_t rbuflen;
917
13.1k
  int cse = 0;
918
919
920
13.1k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
921
922
13.1k
  sc_log(card->ctx,
923
13.1k
     "%02x %02x %02x %"SC_FORMAT_LEN_SIZE_T"u : %"SC_FORMAT_LEN_SIZE_T"u %"SC_FORMAT_LEN_SIZE_T"u\n",
924
13.1k
     ins, p1, p2, sendbuflen, card->max_send_size,
925
13.1k
     card->max_recv_size);
926
927
13.1k
  rbuf = rbufinitbuf;
928
13.1k
  rbuflen = sizeof(rbufinitbuf);
929
930
  /* if caller provided a buffer and length */
931
13.1k
  if (recvbuf && *recvbuf && recvbuflen && *recvbuflen) {
932
6.54k
    rbuf = *recvbuf;
933
6.54k
    rbuflen = *recvbuflen;
934
6.54k
  }
935
936
13.1k
  if (sendbuf || nonce) {
937
8.41k
    if (recvbuf) {
938
1.80k
      cse = SC_APDU_CASE_4_SHORT;
939
6.61k
    } else {
940
6.61k
      cse = SC_APDU_CASE_3_SHORT;
941
6.61k
    }
942
8.41k
  } else {
943
4.75k
    if (recvbuf) {
944
4.75k
      cse = SC_APDU_CASE_2_SHORT;
945
4.75k
    } else {
946
0
      cse = SC_APDU_CASE_1;
947
0
    }
948
4.75k
  }
949
950
  /* append the nonce if we have it. Coolkey just blindly puts this at the end
951
   * of the APDU (while adjusting lc). This converts case 1 to case 3. coolkey
952
   * also always drops le in case 4 (which happens when proto = T0). nonces are
953
   * never used on case 2 commands, so we can simply append the nonce to the data
954
   * and we should be fine */
955
13.1k
  if (nonce) {
956
1.80k
    u8 *buf = rsendbuf;
957
1.80k
    if (sendbuf) {
958
1.80k
      sendbuflen = MIN(sendbuflen,sizeof(rsendbuf)-nonce_len);
959
1.80k
      memcpy(rsendbuf, sendbuf, sendbuflen);
960
1.80k
      buf += sendbuflen;
961
1.80k
    }
962
1.80k
    memcpy(buf, nonce, nonce_len);
963
1.80k
    sendbuflen += nonce_len;
964
1.80k
    sendbuf =rsendbuf;
965
1.80k
  }
966
967
13.1k
  sc_format_apdu(card, &apdu, cse, ins, p1, p2);
968
969
13.1k
  apdu.lc = sendbuflen;
970
13.1k
  apdu.datalen = sendbuflen;
971
13.1k
  apdu.data = sendbuf;
972
973
974
  /* coolkey uses non-standard classes */
975
13.1k
  apdu.cla = cla;
976
977
13.1k
  if (recvbuf) {
978
6.55k
    apdu.resp = rbuf;
979
6.55k
    apdu.le = (rbuflen > 255) ? 255 : rbuflen;
980
6.55k
    apdu.resplen = rbuflen;
981
6.61k
  } else {
982
6.61k
     apdu.resp =  rbuf;
983
6.61k
     apdu.le = 0;
984
6.61k
     apdu.resplen = 0;
985
6.61k
  }
986
987
13.1k
  sc_log(card->ctx,
988
13.1k
     "calling sc_transmit_apdu flags=%lx le=%"SC_FORMAT_LEN_SIZE_T"u, resplen=%"SC_FORMAT_LEN_SIZE_T"u, resp=%p",
989
13.1k
     apdu.flags, apdu.le, apdu.resplen, apdu.resp);
990
991
  /* with new adpu.c and chaining, this actually reads the whole object */
992
13.1k
  r = sc_transmit_apdu(card, &apdu);
993
994
13.1k
  sc_log(card->ctx,
995
13.1k
     "result r=%d apdu.resplen=%"SC_FORMAT_LEN_SIZE_T"u sw1=%02x sw2=%02x",
996
13.1k
     r, apdu.resplen, apdu.sw1, apdu.sw2);
997
998
13.1k
  if (r < 0) {
999
48
    sc_log(card->ctx, "Transmit failed");
1000
48
    goto err;
1001
48
  }
1002
13.1k
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1003
13.1k
  if (r < 0) {
1004
5.83k
    sc_log(card->ctx, "Transmit failed");
1005
5.83k
    goto err;
1006
5.83k
  }
1007
1008
7.27k
  if (recvbuflen) {
1009
6.08k
    if (recvbuf && *recvbuf == NULL) {
1010
0
      *recvbuf =  malloc(apdu.resplen);
1011
0
      if (*recvbuf == NULL) {
1012
0
        r = SC_ERROR_OUT_OF_MEMORY;
1013
0
        goto err;
1014
0
      }
1015
0
      memcpy(*recvbuf, rbuf, apdu.resplen);
1016
0
    }
1017
6.08k
    *recvbuflen =  apdu.resplen;
1018
6.08k
    r = (int)*recvbuflen;
1019
6.08k
  }
1020
1021
13.1k
err:
1022
13.1k
  LOG_FUNC_RETURN(card->ctx, r);
1023
13.1k
}
1024
1025
/*
1026
 * Helpers to handle coolkey commands
1027
 */
1028
static int
1029
coolkey_get_life_cycle(sc_card_t *card, coolkey_life_cycle_t *life_cycle)
1030
614
{
1031
614
  coolkey_status_t status;
1032
614
  u8 *receive_buf;
1033
614
  size_t receive_len;
1034
614
  int len;
1035
1036
614
  receive_len = sizeof(*life_cycle);
1037
614
  receive_buf = (u8 *)life_cycle;
1038
614
  len = coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_GET_LIFE_CYCLE, 0, 0,
1039
614
      NULL, 0, &receive_buf, &receive_len, NULL, 0);
1040
614
  if (len == sizeof(*life_cycle)) {
1041
537
    return SC_SUCCESS;
1042
537
  }
1043
1044
77
  receive_len = 1;
1045
77
  receive_buf = &life_cycle->life_cycle;
1046
77
  len = coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_GET_LIFE_CYCLE, 0, 0,
1047
77
      NULL, 0, &receive_buf, &receive_len, NULL, 0);
1048
77
  if (len < 0) { /* Error from the trasmittion */
1049
45
    return len;
1050
45
  }
1051
32
  if (len != 1) { /* The returned data is invalid */
1052
12
    return SC_ERROR_INTERNAL;
1053
12
  }
1054
20
  receive_len = sizeof(status);
1055
20
  receive_buf = (u8 *)&status;
1056
20
  len = coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_GET_STATUS, 0, 0,
1057
20
      NULL, 0, &receive_buf, &receive_len, NULL, 0);
1058
20
  if (len < 0) { /* Error from the trasmittion */
1059
5
    return len;
1060
5
  }
1061
15
  if (len != sizeof(status)) { /* The returned data is invalid */
1062
10
    return SC_ERROR_INTERNAL;
1063
10
  }
1064
5
  life_cycle->protocol_version_major = status.protocol_version_major;
1065
5
  life_cycle->protocol_version_minor = status.protocol_version_minor;
1066
5
  life_cycle->pin_count = status.pin_count;
1067
5
  return SC_SUCCESS;
1068
15
}
1069
1070
/* select the coolkey applet */
1071
static int coolkey_select_applet(sc_card_t *card)
1072
6.61k
{
1073
6.61k
  u8 aid[] = { 0x62, 0x76, 0x01, 0xff, 0x00, 0x00, 0x00 };
1074
6.61k
  return coolkey_apdu_io(card, ISO7816_CLASS, ISO7816_INS_SELECT_FILE, 4, 0,
1075
6.61k
      &aid[0], sizeof(aid), NULL, NULL,  NULL, 0);
1076
6.61k
}
1077
1078
static void
1079
coolkey_make_cuid_from_cplc(coolkey_cuid_t *cuid, global_platform_cplc_data_t *cplc_data)
1080
42
{
1081
42
  cuid->ic_fabricator[0]    = cplc_data->ic_fabricator[0];
1082
42
  cuid->ic_fabricator[1]    = cplc_data->ic_fabricator[1];
1083
42
  cuid->ic_type[0]          = cplc_data->ic_type[0];
1084
42
  cuid->ic_type[1]          = cplc_data->ic_type[1];
1085
42
  cuid->ic_batch[0]         = cplc_data->ic_batch[0];
1086
42
  cuid->ic_batch[1]         = cplc_data->ic_batch[1];
1087
42
  cuid->ic_serial_number[0] = cplc_data->ic_serial_number[0];
1088
42
  cuid->ic_serial_number[1] = cplc_data->ic_serial_number[1];
1089
42
  cuid->ic_serial_number[2] = cplc_data->ic_serial_number[2];
1090
42
  cuid->ic_serial_number[3] = cplc_data->ic_serial_number[3];
1091
42
}
1092
1093
/*
1094
 * Read a COOLKEY coolkey object.
1095
 */
1096
static int coolkey_read_object(sc_card_t *card, unsigned long object_id, size_t offset,
1097
      u8 *out_buf, size_t out_len, u8 *nonce, size_t nonce_size)
1098
315
{
1099
315
  coolkey_read_object_param_t params;
1100
315
  u8 *out_ptr;
1101
315
  size_t left = 0;
1102
315
  size_t len;
1103
315
  int r;
1104
1105
315
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1106
1107
315
  ulong2bebytes(&params.object_id[0], object_id);
1108
1109
315
  out_ptr = out_buf;
1110
315
  left = out_len;
1111
1.80k
  do {
1112
1.80k
    ulong2bebytes(&params.offset[0], offset);
1113
1.80k
    params.length = MIN(left, COOLKEY_MAX_CHUNK_SIZE);
1114
1.80k
    len = left;
1115
1.80k
    r = coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_READ_OBJECT, 0, 0,
1116
1.80k
      (u8 *)&params, sizeof(params), &out_ptr, &len, nonce, nonce_size);
1117
1.80k
    if (r < 0) {
1118
76
      goto fail;
1119
76
    }
1120
    /* sanity check to make sure we don't overflow left */
1121
1.72k
    if ((left < len) || (len == 0)) {
1122
20
      r = SC_ERROR_INTERNAL;
1123
20
      goto fail;
1124
20
    }
1125
1.70k
    out_ptr += len;
1126
1.70k
    offset += len;
1127
1.70k
    left -= len;
1128
1.70k
  } while (left != 0);
1129
1130
219
  return (int)out_len;
1131
1132
96
fail:
1133
96
  LOG_FUNC_RETURN(card->ctx, r);
1134
96
}
1135
1136
/*
1137
 * Write a COOLKEY coolkey object.
1138
 */
1139
static int coolkey_write_object(sc_card_t *card, unsigned long object_id,
1140
      size_t offset, const u8 *buf, size_t buf_len, const u8 *nonce, size_t nonce_size)
1141
0
{
1142
0
  coolkey_write_object_param_t params;
1143
0
  size_t operation_len;
1144
0
  size_t left = buf_len;
1145
0
  int r;
1146
0
  size_t max_operation_len;
1147
1148
  /* set limit for the card's maximum send size and short write */
1149
0
  max_operation_len = MIN(COOLKEY_MAX_CHUNK_SIZE, (card->max_send_size - sizeof(coolkey_read_object_param_t) - nonce_size));
1150
1151
0
  ulong2bebytes(&params.head.object_id[0], object_id);
1152
1153
0
  do {
1154
0
    ulong2bebytes(&params.head.offset[0], offset);
1155
0
    operation_len = MIN(left, max_operation_len);
1156
0
    params.head.length = operation_len;
1157
0
    memcpy(params.buf, buf, operation_len);
1158
0
    r = coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_WRITE_OBJECT, 0, 0,
1159
0
      (u8 *)&params, sizeof(params.head)+operation_len, NULL, 0, nonce, nonce_size);
1160
0
    if (r < 0) {
1161
0
      goto fail;
1162
0
    }
1163
0
    buf += operation_len;
1164
0
    offset += operation_len;
1165
0
    left -= operation_len;
1166
0
  } while (left != 0);
1167
1168
0
  return (int)(buf_len - left);
1169
1170
0
fail:
1171
0
  return r;
1172
0
}
1173
1174
/*
1175
 * coolkey_read_binary will read a coolkey object off the card. That object is selected
1176
 * by select file. If we've already read the object, we'll return the data from the cache.
1177
 * coolkey objects are encoded PKCS #11 entries, not pkcs #15 data. pkcs15-coolkey will
1178
 * translate the objects into their PKCS #15 equivalent data structures.
1179
 */
1180
static int coolkey_read_binary(sc_card_t *card, unsigned int idx,
1181
    u8 *buf, size_t count, unsigned long *flags)
1182
0
{
1183
0
  coolkey_private_data_t * priv = COOLKEY_DATA(card);
1184
0
  int r = 0;
1185
0
  size_t len;
1186
0
  u8 *data = NULL;
1187
1188
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1189
0
  if (idx > priv->obj->length) {
1190
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_END_REACHED);
1191
0
  }
1192
1193
  /* if we've already read the data, just return it */
1194
0
  if (priv->obj->data) {
1195
0
    sc_log(card->ctx,
1196
0
       "returning cached value idx=%u count=%"SC_FORMAT_LEN_SIZE_T"u",
1197
0
       idx, count);
1198
0
    len = MIN(count, priv->obj->length-idx);
1199
0
    memcpy(buf, &priv->obj->data[idx], len);
1200
0
    LOG_FUNC_RETURN(card->ctx, (int)len);
1201
0
  }
1202
1203
0
  sc_log(card->ctx,
1204
0
     "clearing cache idx=%u count=%"SC_FORMAT_LEN_SIZE_T"u",
1205
0
     idx, count);
1206
1207
0
  data = malloc(priv->obj->length);
1208
0
  if (data == NULL) {
1209
0
    r = SC_ERROR_OUT_OF_MEMORY;
1210
0
    goto done;
1211
0
  }
1212
1213
1214
0
  r = coolkey_read_object(card, priv->obj->id, 0, data, priv->obj->length,
1215
0
    priv->nonce, sizeof(priv->nonce));
1216
0
  if (r < 0)
1217
0
    goto done;
1218
1219
0
  if ((size_t) r != priv->obj->length) {
1220
0
    priv->obj->length = r;
1221
0
  }
1222
1223
1224
  /* OK we've read the data, now copy the required portion out to the callers buffer */
1225
0
  len = MIN(count, priv->obj->length-idx);
1226
0
  memcpy(buf, &data[idx], len);
1227
0
  r = (int)len;
1228
  /* cache the data in the object */
1229
0
  priv->obj->data=data;
1230
0
  data = NULL;
1231
1232
0
done:
1233
0
  if (data)
1234
0
    free(data);
1235
0
  LOG_FUNC_RETURN(card->ctx, r);
1236
0
}
1237
1238
/* COOLKEY driver is read only. NOTE: The applet supports w/r operations, so it's perfectly
1239
 * reasonable to try to create new objects, but currently TPS does not create applets
1240
 * That allow user created objects, so this is a nice 2.0 feature. */
1241
static int coolkey_write_binary(sc_card_t *card, unsigned int idx,
1242
    const u8 *buf, size_t count, unsigned long flags)
1243
10
{
1244
1245
10
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1246
10
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1247
10
}
1248
1249
/* initialize getting a list and return the number of elements in the list */
1250
static int coolkey_get_init_and_get_count(list_t *list, int *countp)
1251
0
{
1252
0
  *countp = list_size(list);
1253
0
  list_iterator_start(list);
1254
0
  return SC_SUCCESS;
1255
0
}
1256
1257
/* fill in the obj_info for the current object on the list and advance to the next object */
1258
static int coolkey_fetch_object(list_t *list, sc_cardctl_coolkey_object_t *coolkey_obj)
1259
0
{
1260
0
  sc_cardctl_coolkey_object_t *ptr;
1261
0
  if (!list_iterator_hasnext(list)) {
1262
0
    return SC_ERROR_FILE_END_REACHED;
1263
0
  }
1264
1265
0
  ptr = list_iterator_next(list);
1266
0
  *coolkey_obj = *ptr;
1267
0
  return SC_SUCCESS;
1268
0
}
1269
1270
/* Finalize iterator */
1271
static int coolkey_final_iterator(list_t *list)
1272
0
{
1273
0
  list_iterator_stop(list);
1274
0
  return SC_SUCCESS;
1275
0
}
1276
1277
static char * coolkey_cuid_to_string(coolkey_cuid_t *cuid)
1278
0
{
1279
0
  char *buf;
1280
0
  size_t len = sizeof(coolkey_cuid_t)*2 + 1;
1281
0
  buf = malloc(len);
1282
0
  if (buf == NULL) {
1283
0
    return NULL;
1284
0
  }
1285
0
  sc_bin_to_hex((u8 *)cuid, sizeof(*cuid), buf, len, 0);
1286
0
  return buf;
1287
0
}
1288
1289
static const struct manufacturer_list_st {
1290
  unsigned short id;
1291
  char *string;
1292
} manufacturer_list[] = {
1293
  { 0x2050, "%04x Oberthur" },
1294
  { 0x4090, "%04x GemAlto (Infineon)" },
1295
  { 0x4780, "%04x STMicroElectronics" },
1296
  { 0x4780, "%04x RSA" },
1297
  { 0x534e, "%04x SafeNet" },
1298
};
1299
1300
int manufacturer_list_count = sizeof(manufacturer_list)/sizeof(manufacturer_list[0]);
1301
1302
static char * coolkey_get_manufacturer(coolkey_cuid_t *cuid)
1303
0
{
1304
0
  unsigned short fabricator = bebytes2ushort(cuid->ic_fabricator);
1305
0
  int i;
1306
0
  char *buf;
1307
0
  const char *manufacturer_string = "%04x Unknown";
1308
0
  size_t len;
1309
0
  int r;
1310
1311
0
  for (i=0; i < manufacturer_list_count; i++) {
1312
0
    if (manufacturer_list[i].id == fabricator) {
1313
0
      manufacturer_string = manufacturer_list[i].string;
1314
0
      break;
1315
0
    }
1316
0
  }
1317
0
  len = strlen(manufacturer_string)+1;
1318
0
  buf= malloc(len);
1319
0
  if (buf == NULL) {
1320
0
    return NULL;
1321
0
  }
1322
0
  r = snprintf(buf, len, manufacturer_string, fabricator);
1323
0
  if (r < 0) {
1324
0
    free(buf);
1325
0
    return NULL;
1326
0
  }
1327
0
  return buf;
1328
0
}
1329
1330
1331
static int coolkey_get_token_info(sc_card_t *card, sc_pkcs15_tokeninfo_t * token_info)
1332
0
{
1333
0
  coolkey_private_data_t * priv = COOLKEY_DATA(card);
1334
0
  char *label = NULL;
1335
0
  char *manufacturer_id = NULL;
1336
0
  char *serial_number = NULL;
1337
1338
0
  LOG_FUNC_CALLED(card->ctx);
1339
0
  label = strdup((char *)priv->token_name);
1340
0
  manufacturer_id = coolkey_get_manufacturer(&priv->cuid);
1341
0
  serial_number = coolkey_cuid_to_string(&priv->cuid);
1342
1343
0
  if (label && manufacturer_id && serial_number) {
1344
0
    free(token_info->label);
1345
0
    token_info->label = label;
1346
0
    free(token_info->manufacturer_id);
1347
0
    token_info->manufacturer_id = manufacturer_id;
1348
0
    free(token_info->serial_number);
1349
0
    token_info->serial_number = serial_number;
1350
0
    return SC_SUCCESS;
1351
0
  }
1352
0
  free(label);
1353
0
  free(manufacturer_id);
1354
0
  free(serial_number);
1355
0
  return SC_ERROR_OUT_OF_MEMORY;
1356
0
}
1357
1358
static int coolkey_get_serial_nr_from_CUID(sc_card_t* card, sc_serial_number_t* serial)
1359
0
{
1360
0
  coolkey_private_data_t * priv = COOLKEY_DATA(card);
1361
1362
0
  LOG_FUNC_CALLED(card->ctx);
1363
0
  memcpy(serial->value, &priv->cuid, sizeof(priv->cuid));
1364
0
  serial->len = sizeof(priv->cuid);
1365
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1366
0
}
1367
1368
int
1369
coolkey_fill_object(sc_card_t *card, sc_cardctl_coolkey_object_t *obj)
1370
0
{
1371
0
  int r;
1372
0
  size_t buf_len = obj->length;
1373
0
  u8 *new_obj_data = NULL;
1374
0
  sc_cardctl_coolkey_object_t *obj_entry;
1375
0
  coolkey_private_data_t * priv = COOLKEY_DATA(card);
1376
1377
0
  LOG_FUNC_CALLED(card->ctx);
1378
1379
0
  if (obj->data != NULL) {
1380
0
    return SC_SUCCESS;
1381
0
  }
1382
0
  new_obj_data = malloc(buf_len);
1383
0
  if (new_obj_data == NULL) {
1384
0
    return SC_ERROR_OUT_OF_MEMORY;
1385
0
  }
1386
0
  r = coolkey_read_object(card, obj->id, 0, new_obj_data, buf_len,
1387
0
        priv->nonce, sizeof(priv->nonce));
1388
0
  if (r != (int)buf_len) {
1389
0
    free(new_obj_data);
1390
0
    if (r < 0) {
1391
0
      LOG_FUNC_RETURN(card->ctx, r);
1392
0
    }
1393
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_CORRUPTED_DATA);
1394
0
  }
1395
0
  obj_entry = coolkey_find_object_by_id(&priv->objects_list, obj->id);
1396
0
  if (obj_entry == NULL) {
1397
0
    free(new_obj_data);
1398
0
    return SC_ERROR_INTERNAL; /* shouldn't happen */
1399
0
  }
1400
0
  if (obj_entry->data != NULL) {
1401
0
    free(new_obj_data);
1402
0
    return SC_ERROR_INTERNAL; /* shouldn't happen */
1403
0
  }
1404
  /* Make sure we will not go over the allocated limits in the other
1405
   * objects if they somehow got different lengths in matching objects */
1406
0
  if (obj_entry->length != obj->length) {
1407
0
    free(new_obj_data);
1408
0
    return SC_ERROR_INTERNAL; /* shouldn't happen */
1409
0
  }
1410
0
  obj_entry->data = new_obj_data;
1411
0
  obj->data = new_obj_data;
1412
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1413
0
}
1414
1415
/*
1416
 * return a parsed record for the attribute which includes value, type, and length.
1417
 * Handled both v1 and v0 record types. determine record type from the object.
1418
 *  make sure we don't overrun the buffer if the token gives us bad data.
1419
 */
1420
static int
1421
coolkey_find_attribute(sc_card_t *card, sc_cardctl_coolkey_attribute_t *attribute)
1422
0
{
1423
0
  u8 object_record_type;
1424
0
  CK_ATTRIBUTE_TYPE attr_type = attribute->attribute_type;
1425
0
  const u8 *obj = attribute->object->data;
1426
0
  const u8 *attr = NULL;
1427
0
  size_t buf_len = attribute->object->length;
1428
0
  coolkey_object_header_t *object_head;
1429
0
  int attribute_count,i;
1430
0
  attribute->attribute_data_type = SC_CARDCTL_COOLKEY_ATTR_TYPE_STRING;
1431
0
  attribute->attribute_length = 0;
1432
0
  attribute->attribute_value = NULL;
1433
1434
0
  LOG_FUNC_CALLED(card->ctx);
1435
1436
0
  if (obj == NULL) {
1437
    /* cast away const so we can cache the data value */
1438
0
    int r = coolkey_fill_object(card, (sc_cardctl_coolkey_object_t *)attribute->object);
1439
0
    if (r < 0) {
1440
0
      return r;
1441
0
    }
1442
0
    obj = attribute->object->data;
1443
0
    if (obj == NULL) {
1444
0
      return SC_ERROR_INTERNAL;
1445
0
    }
1446
0
  }
1447
1448
  /* should be a static assert so we catch this at compile time */
1449
0
  assert(sizeof(coolkey_object_header_t) >= sizeof(coolkey_v0_object_header_t));
1450
  /* make sure we have enough of the object to read the record_type */
1451
0
  if (buf_len <= sizeof(coolkey_v0_object_header_t)) {
1452
0
    return SC_ERROR_CORRUPTED_DATA;
1453
0
  }
1454
0
  object_head = (coolkey_object_header_t *)obj;
1455
0
  object_record_type = object_head->record_type;
1456
  /* make sure it's a type we recognize */
1457
0
  if ((object_record_type != COOLKEY_V1_OBJECT) && (object_record_type != COOLKEY_V0_OBJECT)) {
1458
0
    return SC_ERROR_CORRUPTED_DATA;
1459
0
  }
1460
1461
  /*
1462
   * now loop through all the attributes in the list. first find the start of the list
1463
   */
1464
0
  attr = coolkey_attribute_start(obj, object_record_type, buf_len);
1465
0
  if (attr == NULL) {
1466
0
    return SC_ERROR_CORRUPTED_DATA;
1467
0
  }
1468
0
  buf_len -= (attr-obj);
1469
1470
  /* now get the count */
1471
0
  attribute_count = coolkey_get_attribute_count(obj, object_record_type, buf_len);
1472
0
  for (i=0; i < attribute_count; i++) {
1473
0
    size_t record_len = coolkey_get_attribute_record_len(attr, object_record_type, buf_len);
1474
    /* make sure we have the complete record */
1475
0
    if (buf_len < record_len || record_len < 4) {
1476
0
      return SC_ERROR_CORRUPTED_DATA;
1477
0
    }
1478
    /* does the attribute match the one we are looking for */
1479
0
    if (attr_type == coolkey_get_attribute_type(attr, object_record_type, record_len)) {
1480
      /* yup, return it */
1481
0
      return coolkey_get_attribute_data(attr, object_record_type, record_len, attribute);
1482
0
    }
1483
    /* go to the next attribute on the list */
1484
0
    buf_len -= record_len;
1485
0
    attr += record_len;
1486
0
  }
1487
  /* not find in attribute list, check the fixed attribute record */
1488
0
  if (object_record_type == COOLKEY_V1_OBJECT) {
1489
0
    unsigned long fixed_attributes = bebytes2ulong(object_head->fixed_attributes_values);
1490
1491
0
    return coolkey_get_attribute_data_fixed(attr_type, fixed_attributes, attribute);
1492
0
  }
1493
0
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_DATA_OBJECT_NOT_FOUND);
1494
0
}
1495
1496
/*
1497
 * pkcs 15 needs to find the cert matching the keys to fill in some of the fields that wasn't stored
1498
 * with the key. To do this we need to look for the cert matching the key's CKA_ID. For flexibility,
1499
 * We simply search using a pkcs #11 style template using the cardctl_coolkey_attribute_t structure */
1500
sc_cardctl_coolkey_object_t *
1501
coolkey_find_object_by_template(sc_card_t *card, sc_cardctl_coolkey_attribute_t *template, int count)
1502
0
{
1503
0
  list_t *list;
1504
0
  sc_cardctl_coolkey_object_t *current, *rv = NULL;
1505
0
  coolkey_private_data_t * priv = COOLKEY_DATA(card);
1506
0
  int i, r;
1507
0
  unsigned int tmp_pos = (unsigned int) -1;
1508
1509
0
  list = &priv->objects_list;
1510
0
  if (list->iter_active) {
1511
    /* workaround missing functionality of second iterator */
1512
0
    tmp_pos = list->iter_pos;
1513
0
    list_iterator_stop(list);
1514
0
  }
1515
1516
0
  list_iterator_start(list);
1517
0
  while (list_iterator_hasnext(list)) {
1518
0
    sc_cardctl_coolkey_attribute_t attribute;
1519
0
    current = list_iterator_next(list);
1520
0
    attribute.object = current;
1521
1522
0
    for (i=0; i < count; i++) {
1523
0
      attribute.attribute_type = template[i].attribute_type;
1524
0
      r = coolkey_find_attribute(card, &attribute);
1525
0
      if (r < 0) {
1526
0
        break;
1527
0
      }
1528
0
      if (template[i].attribute_data_type != attribute.attribute_data_type) {
1529
0
        break;
1530
0
      }
1531
0
      if (template[i].attribute_length != attribute.attribute_length) {
1532
0
        break;
1533
0
      }
1534
0
      if (memcmp(attribute.attribute_value, template[i].attribute_value,
1535
0
              attribute.attribute_length) != 0) {
1536
0
        break;
1537
0
      }
1538
0
    }
1539
    /* just return the first one */
1540
0
    if (i == count) {
1541
0
      rv = current;
1542
0
      break;
1543
0
    }
1544
0
  }
1545
1546
0
  list_iterator_stop(list);
1547
0
  if (tmp_pos != (unsigned int)-1) {
1548
    /* workaround missing functionality of second iterator */
1549
0
    list_iterator_start(list);
1550
0
    while (list_iterator_hasnext(list) && list->iter_pos < tmp_pos)
1551
0
      (void) list_iterator_next(list);
1552
0
  }
1553
0
  return rv;
1554
0
}
1555
1556
static int
1557
coolkey_find_object(sc_card_t *card, sc_cardctl_coolkey_find_object_t *fobj)
1558
0
{
1559
0
  sc_cardctl_coolkey_object_t *obj = NULL;
1560
0
  coolkey_private_data_t * priv = COOLKEY_DATA(card);
1561
0
  int r;
1562
1563
0
  switch (fobj->type) {
1564
0
  case SC_CARDCTL_COOLKEY_FIND_BY_ID:
1565
0
    obj = coolkey_find_object_by_id(&priv->objects_list, fobj->find_id);
1566
0
    break;
1567
0
  case SC_CARDCTL_COOLKEY_FIND_BY_TEMPLATE:
1568
0
    obj = coolkey_find_object_by_template(card, fobj->coolkey_template, fobj->template_count);
1569
0
    break;
1570
0
  default:
1571
0
    break;
1572
0
  }
1573
0
  if (obj == NULL) {
1574
0
    return SC_ERROR_DATA_OBJECT_NOT_FOUND;
1575
0
  }
1576
0
  if (obj->data == NULL) {
1577
0
    r = coolkey_fill_object(card, obj);
1578
0
    if (r < 0) {
1579
0
      return r;
1580
0
    }
1581
0
  }
1582
0
  fobj->obj = obj;
1583
0
  return SC_SUCCESS;
1584
0
}
1585
1586
static int coolkey_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
1587
0
{
1588
0
  coolkey_private_data_t * priv = COOLKEY_DATA(card);
1589
1590
0
  LOG_FUNC_CALLED(card->ctx);
1591
0
  sc_log(card->ctx, "cmd=%ld ptr=%p", cmd, ptr);
1592
1593
0
  if (priv == NULL) {
1594
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
1595
0
  }
1596
0
  switch(cmd) {
1597
0
    case SC_CARDCTL_GET_SERIALNR:
1598
0
      return coolkey_get_serial_nr_from_CUID(card, (sc_serial_number_t *) ptr);
1599
0
    case SC_CARDCTL_COOLKEY_GET_TOKEN_INFO:
1600
0
      return coolkey_get_token_info(card, (sc_pkcs15_tokeninfo_t *) ptr);
1601
0
    case SC_CARDCTL_COOLKEY_FIND_OBJECT:
1602
0
      return coolkey_find_object(card, (sc_cardctl_coolkey_find_object_t *)ptr);
1603
0
    case SC_CARDCTL_COOLKEY_INIT_GET_OBJECTS:
1604
0
      return coolkey_get_init_and_get_count(&priv->objects_list, (int *)ptr);
1605
0
    case SC_CARDCTL_COOLKEY_GET_NEXT_OBJECT:
1606
0
      return coolkey_fetch_object(&priv->objects_list, (sc_cardctl_coolkey_object_t *)ptr);
1607
0
    case SC_CARDCTL_COOLKEY_FINAL_GET_OBJECTS:
1608
0
      return coolkey_final_iterator(&priv->objects_list);
1609
0
    case SC_CARDCTL_COOLKEY_GET_ATTRIBUTE:
1610
0
      return coolkey_find_attribute(card,(sc_cardctl_coolkey_attribute_t *)ptr);
1611
0
  }
1612
1613
0
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1614
0
}
1615
1616
static int coolkey_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
1617
430
{
1618
430
  LOG_FUNC_CALLED(card->ctx);
1619
1620
430
  if (len > COOLKEY_MAX_CHUNK_SIZE)
1621
31
    len = COOLKEY_MAX_CHUNK_SIZE;
1622
1623
430
  LOG_TEST_RET(card->ctx,
1624
388
      coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_GET_RANDOM, 0, 0,
1625
388
        NULL, 0, &rnd, &len,  NULL, 0),
1626
388
      "Could not get challenge");
1627
1628
388
  LOG_FUNC_RETURN(card->ctx, (int) len);
1629
388
}
1630
1631
static int coolkey_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num)
1632
0
{
1633
0
  int r = SC_SUCCESS;
1634
0
  coolkey_private_data_t * priv = COOLKEY_DATA(card);
1635
1636
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1637
1638
0
  sc_log(card->ctx,
1639
0
     "flags=%08lx op=%d alg=%lu algf=%08lx algr=%08lx kr0=%02x, krfl=%"SC_FORMAT_LEN_SIZE_T"u\n",
1640
0
     env->flags, env->operation, env->algorithm,
1641
0
     env->algorithm_flags, env->algorithm_ref, env->key_ref[0],
1642
0
     env->key_ref_len);
1643
1644
0
  if ((env->algorithm != SC_ALGORITHM_RSA) && (env->algorithm != SC_ALGORITHM_EC)) {
1645
0
     r = SC_ERROR_NO_CARD_SUPPORT;
1646
0
  }
1647
0
  priv->algorithm = env->algorithm;
1648
0
  priv->operation = env->operation;
1649
1650
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
1651
0
}
1652
1653
1654
static int coolkey_restore_security_env(sc_card_t *card, int se_num)
1655
0
{
1656
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1657
1658
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1659
0
}
1660
1661
0
#define MAX_COMPUTE_BUF 200
1662
typedef struct coolkey_compute_crypt_init_params {
1663
  u8 mode;
1664
  u8 direction;
1665
  u8 location;
1666
  u8 buf_len[2];
1667
} coolkey_compute_crypt_init_params_t;
1668
1669
typedef struct coolkey_compute_crypt_params {
1670
    coolkey_compute_crypt_init_params_t init;
1671
  u8 buf[MAX_COMPUTE_BUF];
1672
} coolkey_compute_crypt_params_t;
1673
1674
typedef struct coolkey_compute_ecc_params {
1675
  u8 location;
1676
  u8 buf_len[2];
1677
  u8 buf[MAX_COMPUTE_BUF];
1678
} coolkey_compute_ecc_params_t;
1679
1680
static int coolkey_rsa_op(sc_card_t *card, const u8 * data, size_t datalen,
1681
  u8 * out, size_t max_out_len)
1682
0
{
1683
0
  int r;
1684
0
  u8 **crypt_out_p = NULL;
1685
0
  size_t crypt_out_len_p = 0;
1686
0
  coolkey_private_data_t *priv = COOLKEY_DATA(card);
1687
0
  coolkey_compute_crypt_params_t params;
1688
0
  u8 key_number;
1689
0
  size_t params_len;
1690
0
  u8 buf[MAX_COMPUTE_BUF + 2];
1691
0
  size_t buf_len;
1692
0
  u8 *buf_out;
1693
1694
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1695
0
  sc_log(card->ctx, "datalen=%"SC_FORMAT_LEN_SIZE_T"u outlen=%"SC_FORMAT_LEN_SIZE_T"u\n",
1696
0
    datalen, max_out_len);
1697
1698
0
  if (priv->key_id > 0xff) {
1699
0
    r = SC_ERROR_NO_DEFAULT_KEY;
1700
0
    goto done;
1701
0
  }
1702
0
  key_number = priv->key_id;
1703
1704
0
  memset(&params, 0, sizeof(params));
1705
0
  params.init.mode = COOLKEY_CRYPT_MODE_RSA_NO_PAD;
1706
0
  params.init.direction = COOLKEY_CRYPT_DIRECTION_ENCRYPT; /* for no pad, direction is irrelevant */
1707
1708
  /* send the data to the card if necessary */
1709
0
  if (datalen > MAX_COMPUTE_BUF) {
1710
    /* We need to write data to special object on the card as it does not safely fit APDU */
1711
0
    u8 len_buf[2];
1712
1713
0
    params.init.location = COOLKEY_CRYPT_LOCATION_DL_OBJECT;
1714
1715
0
    params_len = sizeof(params.init);
1716
1717
0
    ushort2bebytes(len_buf, datalen);
1718
1719
0
    r = coolkey_write_object(card, COOLKEY_DL_OBJECT_ID, 0, len_buf, sizeof(len_buf),
1720
0
          priv->nonce, sizeof(priv->nonce));
1721
0
    if (r < 0) {
1722
0
      goto done;
1723
0
    }
1724
1725
0
    r = coolkey_write_object(card, COOLKEY_DL_OBJECT_ID, 2, data, datalen, priv->nonce, sizeof(priv->nonce));
1726
0
    if (r < 0) {
1727
0
      goto done;
1728
0
    }
1729
0
    ushort2bebytes(params.init.buf_len, 0);
1730
0
  } else {
1731
    /* The data fits in APDU. Copy it to the params object */
1732
0
    params.init.location = COOLKEY_CRYPT_LOCATION_APDU;
1733
1734
0
    params_len = sizeof(params.init) + datalen;
1735
1736
0
    buf_out = &buf[0];
1737
0
    crypt_out_p = &buf_out;
1738
0
    buf_len = sizeof(buf);
1739
0
    crypt_out_len_p = buf_len;
1740
1741
0
    ushort2bebytes(params.init.buf_len, datalen);
1742
0
    memcpy(params.buf, data, datalen);
1743
0
  }
1744
1745
0
  r = coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_COMPUTE_CRYPT,
1746
0
      key_number, COOLKEY_CRYPT_ONE_STEP, (u8 *)&params, params_len,
1747
0
      crypt_out_p, &crypt_out_len_p, priv->nonce, sizeof(priv->nonce));
1748
0
  if (r < 0) {
1749
0
    goto done;
1750
0
  }
1751
0
  buf_len = crypt_out_len_p;
1752
1753
0
  if (datalen > MAX_COMPUTE_BUF) {
1754
0
    u8 len_buf[2];
1755
0
    size_t out_length;
1756
1757
0
    r = coolkey_read_object(card, COOLKEY_DL_OBJECT_ID, 0, len_buf, sizeof(len_buf),
1758
0
          priv->nonce, sizeof(priv->nonce));
1759
0
    if (r < 0) {
1760
0
      goto done;
1761
0
    }
1762
1763
0
    out_length = bebytes2ushort(len_buf);
1764
0
    out_length = MIN(out_length,max_out_len);
1765
1766
0
    r = coolkey_read_object(card, COOLKEY_DL_OBJECT_ID, sizeof(len_buf), out, out_length,
1767
0
          priv->nonce, sizeof(priv->nonce));
1768
1769
0
  } else {
1770
0
    size_t out_length;
1771
0
    if (buf_len < 2) {
1772
0
      r = SC_ERROR_WRONG_LENGTH;
1773
0
      goto done;
1774
0
    }
1775
0
    out_length = bebytes2ushort(buf);
1776
0
    if (out_length > sizeof buf - 2) {
1777
0
      r = SC_ERROR_WRONG_LENGTH;
1778
0
      goto done;
1779
0
    }
1780
0
    out_length = MIN(out_length, max_out_len);
1781
0
    memcpy(out, buf + 2, out_length);
1782
0
    r = (int)out_length;
1783
0
  }
1784
1785
0
done:
1786
0
  return r;
1787
0
}
1788
1789
static int coolkey_ecc_op(sc_card_t *card,
1790
          const u8 * data, size_t datalen,
1791
          u8 * out, size_t outlen)
1792
0
{
1793
0
  int r;
1794
0
  const u8 *crypt_in;
1795
0
  u8  **crypt_out_p;
1796
0
  u8  ins = 0;
1797
0
  size_t crypt_in_len, *crypt_out_len_p;
1798
0
  coolkey_private_data_t * priv = COOLKEY_DATA(card);
1799
0
  coolkey_compute_ecc_params_t params;
1800
0
  size_t params_len;
1801
0
  u8 key_number;
1802
1803
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1804
0
  sc_log(card->ctx,
1805
0
     "datalen=%"SC_FORMAT_LEN_SIZE_T"u outlen=%"SC_FORMAT_LEN_SIZE_T"u\n",
1806
0
     datalen, outlen);
1807
1808
0
  crypt_in = data;
1809
0
  crypt_in_len = datalen;
1810
1811
0
  crypt_out_p = &out;
1812
0
  crypt_out_len_p = &outlen;
1813
0
  key_number = priv->key_id;
1814
0
  params.location = COOLKEY_CRYPT_LOCATION_APDU;
1815
1816
0
  if (priv->key_id > 0xff) {
1817
0
    r = SC_ERROR_NO_DEFAULT_KEY;
1818
0
    goto done;
1819
0
  }
1820
1821
0
  switch (priv->operation) {
1822
0
  case SC_SEC_OPERATION_DERIVE:
1823
0
    ins = COOLKEY_INS_COMPUTE_ECC_KEY_AGREEMENT;
1824
0
    break;
1825
0
  case SC_SEC_OPERATION_SIGN:
1826
0
    ins = COOLKEY_INS_COMPUTE_ECC_SIGNATURE;
1827
0
    break;
1828
0
  default:
1829
0
    r = SC_ERROR_NOT_SUPPORTED;
1830
0
    goto done;
1831
0
  }
1832
1833
0
  params_len = (sizeof(params) - sizeof(params.buf))  + crypt_in_len;
1834
1835
0
  ushort2bebytes(params.buf_len, crypt_in_len);
1836
0
  if (crypt_in_len) {
1837
0
    memcpy(params.buf, crypt_in, crypt_in_len);
1838
0
  }
1839
1840
1841
0
  r = coolkey_apdu_io(card, COOLKEY_CLASS, ins,
1842
0
      key_number, COOLKEY_CRYPT_ONE_STEP, (u8 *)&params, params_len,
1843
0
      crypt_out_p, crypt_out_len_p, priv->nonce, sizeof(priv->nonce));
1844
1845
0
done:
1846
0
  return r;
1847
0
}
1848
1849
1850
static int coolkey_compute_crypt(sc_card_t *card,
1851
          const u8 * data, size_t datalen,
1852
          u8 * out, size_t outlen)
1853
0
{
1854
0
  coolkey_private_data_t * priv = COOLKEY_DATA(card);
1855
0
  int r;
1856
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1857
1858
0
  switch (priv->algorithm) {
1859
0
  case SC_ALGORITHM_RSA:
1860
0
    r = coolkey_rsa_op(card, data, datalen, out, outlen);
1861
0
    break;
1862
0
  case SC_ALGORITHM_EC:
1863
0
    r = coolkey_ecc_op(card, data, datalen, out, outlen);
1864
0
    break;
1865
0
  default:
1866
0
    r = SC_ERROR_NO_CARD_SUPPORT;
1867
0
    break;
1868
0
  }
1869
1870
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
1871
0
}
1872
1873
1874
0
static u8 coolkey_class(unsigned long object_id) {
1875
0
  return (object_id >> 24) & 0xff;
1876
0
}
1877
1878
0
static unsigned short coolkey_get_key_id(unsigned long object_id) {
1879
0
  char char_index = (object_id >> 16) & 0xff;
1880
0
  if (char_index >= '0' && char_index <= '9') {
1881
0
    return (u8)(char_index - '0');
1882
0
  }
1883
0
  if (char_index >= 'A' && char_index <= 'Z') {
1884
0
    return (u8)(char_index - 'A' + 10);
1885
0
  }
1886
0
  if (char_index >= 'a' && char_index <= 'z') {
1887
0
    return (u8)(char_index - 'a' + 26 + 10);
1888
0
  }
1889
0
  return COOLKEY_INVALID_KEY;
1890
0
}
1891
1892
/*
1893
 * COOLKEY cards don't select objects in the applet, objects are selected by a parameter
1894
 * to the APDU. We create paths for the object in which the path value is the object_id
1895
 * and the path type is SC_PATH_SELECT_FILE_ID (so we could cache at the PKCS #15 level if
1896
 * we wanted to.
1897
 *
1898
 * This select simply records what object was selected so that read knows how to access it.
1899
 */
1900
static int coolkey_select_file(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out)
1901
0
{
1902
0
  int r;
1903
0
  struct sc_file *file = NULL;
1904
0
  coolkey_private_data_t * priv = COOLKEY_DATA(card);
1905
0
  unsigned long object_id;
1906
1907
0
  assert(card != NULL && in_path != NULL);
1908
1909
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1910
1911
0
  if (in_path->len != 4) {
1912
0
    return SC_ERROR_OBJECT_NOT_FOUND;
1913
0
  }
1914
0
  r = coolkey_select_applet(card);
1915
0
  if (r != SC_SUCCESS) {
1916
0
    return r;
1917
0
  }
1918
0
  object_id = bebytes2ulong(in_path->value);
1919
0
  priv->obj = coolkey_find_object_by_id(&priv->objects_list, object_id);
1920
0
  if (priv->obj == NULL) {
1921
0
    return SC_ERROR_OBJECT_NOT_FOUND;
1922
0
  }
1923
1924
0
  priv->key_id = COOLKEY_INVALID_KEY;
1925
0
  if (coolkey_class(object_id) == COOLKEY_KEY_CLASS) {
1926
0
    priv->key_id = coolkey_get_key_id(object_id);
1927
0
  }
1928
0
  if (file_out) {
1929
0
    file = sc_file_new();
1930
0
    if (file == NULL)
1931
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1932
0
    file->path = *in_path;
1933
    /* this could be like the FCI */
1934
0
    file->type =  SC_PATH_TYPE_FILE_ID;
1935
0
    file->shareable = 0;
1936
0
    file->ef_structure = 0;
1937
0
    file->size = priv->obj->length;
1938
0
    *file_out = file;
1939
0
  }
1940
1941
0
  return SC_SUCCESS;
1942
0
}
1943
1944
static int coolkey_finish(sc_card_t *card)
1945
43
{
1946
43
  coolkey_private_data_t * priv = COOLKEY_DATA(card);
1947
1948
43
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1949
43
  if (priv) {
1950
43
    coolkey_free_private_data(priv);
1951
43
  }
1952
43
  return SC_SUCCESS;
1953
43
}
1954
1955
static int
1956
coolkey_add_object(coolkey_private_data_t *priv, unsigned long object_id, const u8 *object_data, size_t object_length, int add_v1_record)
1957
3.25k
{
1958
3.25k
  sc_cardctl_coolkey_object_t new_object;
1959
3.25k
  int r;
1960
1961
3.25k
  memset(&new_object, 0, sizeof(new_object));
1962
3.25k
  new_object.path = coolkey_template_path;
1963
3.25k
  new_object.path.len = 4;
1964
3.25k
  ulong2bebytes(new_object.path.value, object_id);
1965
3.25k
  new_object.id = object_id;
1966
3.25k
  new_object.length = object_length;
1967
1968
  /* The object ID needs to be unique */
1969
3.25k
  if (coolkey_find_object_by_id(&priv->objects_list, object_id) != NULL) {
1970
2.36k
    return SC_ERROR_INTERNAL;
1971
2.36k
  }
1972
1973
893
  if (object_data) {
1974
191
    new_object.data = malloc(object_length + add_v1_record);
1975
191
    if (new_object.data == NULL) {
1976
0
      return SC_ERROR_OUT_OF_MEMORY;
1977
0
    }
1978
191
    if (add_v1_record) {
1979
191
      new_object.data[0] = COOLKEY_V1_OBJECT;
1980
191
      new_object.length++;
1981
191
    }
1982
191
    memcpy(&new_object.data[add_v1_record], object_data, object_length);
1983
191
  }
1984
1985
893
  r = coolkey_add_object_to_list(&priv->objects_list, &new_object);
1986
893
  if (r != SC_SUCCESS) {
1987
    /* if we didn't successfully put the object on the list,
1988
     * the data space didn't get adopted. free it before we return */
1989
0
    free(new_object.data);
1990
0
    new_object.data = NULL;
1991
0
  }
1992
893
  return r;
1993
893
}
1994
1995
1996
static int
1997
coolkey_process_combined_object(sc_card_t *card, coolkey_private_data_t *priv, u8 *object, size_t object_length)
1998
219
{
1999
219
  coolkey_combined_header_t *header = (coolkey_combined_header_t *)object;
2000
219
  unsigned short compressed_offset;
2001
219
  unsigned short compressed_length;
2002
219
  unsigned short compressed_type;
2003
219
  unsigned short object_offset;
2004
219
  unsigned short object_count;
2005
219
  coolkey_decompressed_header_t *decompressed_header;
2006
219
  u8 *decompressed_object = NULL;
2007
219
  size_t decompressed_object_len = 0;
2008
219
  int free_decompressed = 0;
2009
219
  int i, r;
2010
2011
219
  if (object_length < sizeof(coolkey_combined_header_t)) {
2012
3
    return SC_ERROR_CORRUPTED_DATA;
2013
3
  }
2014
216
  compressed_offset = bebytes2ushort(header->compression_offset);
2015
216
  compressed_length = bebytes2ushort(header->compression_length);
2016
216
  compressed_type   = bebytes2ushort(header->compression_type);
2017
2018
216
  if ((((size_t)compressed_offset) + (size_t)compressed_length) >  object_length) {
2019
22
    return SC_ERROR_CORRUPTED_DATA;
2020
22
  }
2021
2022
  /* store the CUID */
2023
194
  memcpy(&priv->cuid, &header->cuid, sizeof(priv->cuid));
2024
2025
194
  if (compressed_type == COOLKEY_COMPRESSION_ZLIB) {
2026
42
#ifdef ENABLE_ZLIB
2027
42
    r = sc_decompress_alloc(&decompressed_object, &decompressed_object_len, &object[compressed_offset], compressed_length, COMPRESSION_AUTO);
2028
42
    if (r)
2029
40
      goto done;
2030
2
    free_decompressed = 1;
2031
#else
2032
    sc_log(card->ctx, "Coolkey compression not supported, no zlib");
2033
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2034
#endif
2035
152
  }  else {
2036
152
    decompressed_object =&object[compressed_offset];
2037
152
    decompressed_object_len = (size_t) compressed_length;
2038
152
  }
2039
2040
154
  decompressed_header = (coolkey_decompressed_header_t *)decompressed_object;
2041
2042
154
  if (decompressed_object_len < sizeof(coolkey_decompressed_header_t)) {
2043
24
    r = SC_ERROR_CORRUPTED_DATA;
2044
24
    goto done;
2045
24
  }
2046
130
  object_offset = bebytes2ushort(decompressed_header->object_offset);
2047
130
  object_count = bebytes2ushort(decompressed_header->object_count);
2048
2049
2050
  /*
2051
   * using 2 different tests here so we can log different errors if logging is
2052
   * turned on.
2053
   */
2054
  /* make sure token_name doesn't overrun the buffer */
2055
130
  if (decompressed_header->token_name_length +
2056
130
    offsetof(coolkey_decompressed_header_t, token_name) > decompressed_object_len) {
2057
0
    r = SC_ERROR_CORRUPTED_DATA;
2058
0
    goto done;
2059
0
  }
2060
  /* make sure it doesn't overlap the object space */
2061
130
  if (decompressed_header->token_name_length +
2062
130
    offsetof(coolkey_decompressed_header_t, token_name) > object_offset) {
2063
1
    r = SC_ERROR_CORRUPTED_DATA;
2064
1
    goto done;
2065
1
  }
2066
2067
  /* store the token name in the priv structure so the emulator can set it */
2068
129
  free(priv->token_name);
2069
129
  priv->token_name = malloc(decompressed_header->token_name_length+1);
2070
129
  if (priv->token_name == NULL) {
2071
0
    r = SC_ERROR_OUT_OF_MEMORY;
2072
0
    goto done;
2073
0
  }
2074
129
  memcpy(priv->token_name, &decompressed_header->token_name[0],
2075
129
              decompressed_header->token_name_length);
2076
129
  priv->token_name[decompressed_header->token_name_length] = '\0';
2077
129
  priv->token_name_length = decompressed_header->token_name_length;
2078
2079
2080
320
  for (i=0; i < object_count; i++) {
2081
293
    u8 *current_object = NULL;
2082
293
    coolkey_combined_object_header_t *object_header = NULL;
2083
293
    unsigned long object_id;
2084
293
    int current_object_len;
2085
2086
    /* Can we read the object header at all? */
2087
293
    if ((object_offset + sizeof(coolkey_combined_object_header_t)) > decompressed_object_len) {
2088
89
      r = SC_ERROR_CORRUPTED_DATA;
2089
89
      goto done;
2090
89
    }
2091
2092
204
    current_object = &decompressed_object[object_offset];
2093
204
    object_header = (coolkey_combined_object_header_t *)current_object;
2094
2095
    /* Parse object ID */
2096
204
    object_id = bebytes2ulong(object_header->object_id);
2097
2098
    /* figure out how big it is */
2099
204
    r = coolkey_v1_get_object_length(current_object, decompressed_object_len-object_offset);
2100
204
    if (r < 0) {
2101
0
      goto done;
2102
0
    }
2103
204
    if ((size_t)r + object_offset > decompressed_object_len) {
2104
0
      r = SC_ERROR_CORRUPTED_DATA;
2105
0
      goto done;
2106
0
    }
2107
204
    current_object_len = r;
2108
204
    object_offset += current_object_len;
2109
2110
    /* record this object */
2111
204
    sc_log(card->ctx, "Add new object id=%ld", object_id);
2112
204
    r = coolkey_add_object(priv, object_id, current_object, current_object_len, 1);
2113
204
    if (r) {
2114
13
      goto done;
2115
13
    }
2116
2117
204
  }
2118
27
  r = SC_SUCCESS;
2119
2120
194
done:
2121
194
  if (free_decompressed) {
2122
2
    free(decompressed_object);
2123
2
  }
2124
194
  return r;
2125
27
}
2126
2127
static int
2128
coolkey_list_object(sc_card_t *card, u8 seq, coolkey_object_info_t *object_info)
2129
3.60k
{
2130
3.60k
  u8 *rbuf = (u8 *) object_info;
2131
3.60k
  size_t rbuflen = sizeof(*object_info);
2132
2133
3.60k
  return coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_LIST_OBJECTS, seq, 0,
2134
3.60k
      NULL, 0, &rbuf, &rbuflen, NULL, 0);
2135
2136
3.60k
}
2137
2138
/*
2139
 * Initialize the Coolkey data structures.
2140
 */
2141
static int coolkey_initialize(sc_card_t *card)
2142
614
{
2143
614
  int r;
2144
614
  coolkey_private_data_t *priv = NULL;
2145
614
  coolkey_life_cycle_t life_cycle;
2146
614
  coolkey_object_info_t object_info;
2147
614
  int combined_processed = 0;
2148
2149
  /* already found? */
2150
614
  if (card->drv_data) {
2151
0
    return SC_SUCCESS;
2152
0
  }
2153
614
  sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"Coolkey Applet found");
2154
2155
614
  priv = coolkey_new_private_data();
2156
614
  if (priv == NULL) {
2157
0
    r = SC_ERROR_OUT_OF_MEMORY;
2158
0
    goto cleanup;
2159
0
  }
2160
614
  r = coolkey_get_life_cycle(card, &life_cycle);
2161
614
  if (r < 0) {
2162
72
    goto cleanup;
2163
72
  }
2164
2165
  /* Select a coolkey read the coolkey objects out */
2166
542
  r = coolkey_select_applet(card);
2167
542
  if (r < 0) {
2168
11
    goto cleanup;
2169
11
  }
2170
2171
531
  priv->protocol_version_major = life_cycle.protocol_version_major;
2172
531
  priv->protocol_version_minor = life_cycle.protocol_version_minor;
2173
531
  priv->pin_count = life_cycle.pin_count;
2174
531
  priv->life_cycle = life_cycle.life_cycle;
2175
2176
  /* walk down the list of objects and read them off the token */
2177
531
  r = coolkey_list_object(card, COOLKEY_LIST_RESET, &object_info);
2178
3.60k
  while (r >= 0) {
2179
3.38k
    unsigned long object_id;
2180
3.38k
    unsigned long object_len;
2181
2182
    /* The card did not return what we expected: Lets try other objects */
2183
3.38k
    if ((size_t)r < (sizeof(object_info)))
2184
5
      break;
2185
2186
    /* TODO also look at the ACL... */
2187
2188
3.37k
    object_id = bebytes2ulong(object_info.object_id);
2189
3.37k
    object_len = bebytes2ulong(object_info.object_length);
2190
    /* Avoid insanely large data */
2191
3.37k
    if (object_len > MAX_FILE_SIZE) {
2192
11
      r = SC_ERROR_CORRUPTED_DATA;
2193
11
      goto cleanup;
2194
11
    }
2195
2196
    /* the combined object is a single object that can store the other objects.
2197
     * most coolkeys provisioned by TPS has a single combined object that is
2198
     * compressed greatly increasing the effectiveness of compress (since lots
2199
     * of certs on the token share the same Subject and Issuer DN's). We now
2200
     * process it separately so that we can have both combined objects managed
2201
     * by TPS and user managed certs on the same token */
2202
3.36k
    if (object_id == COOLKEY_COMBINED_OBJECT_ID) {
2203
315
      u8 *object = malloc(object_len);
2204
315
      if (object == NULL) {
2205
0
        r = SC_ERROR_OUT_OF_MEMORY;
2206
0
        break;
2207
0
      }
2208
315
      r = coolkey_read_object(card, COOLKEY_COMBINED_OBJECT_ID, 0, object, object_len,
2209
315
        priv->nonce, sizeof(priv->nonce));
2210
315
      if (r < 0) {
2211
96
        free(object);
2212
96
        break;
2213
96
      }
2214
219
      r = coolkey_process_combined_object(card, priv, object, r);
2215
219
      free(object);
2216
219
      if (r != SC_SUCCESS) {
2217
192
        break;
2218
192
      }
2219
27
      combined_processed = 1;
2220
3.05k
    } else {
2221
3.05k
      sc_log(card->ctx, "Add new object id=%ld, len=%lu", object_id, object_len);
2222
3.05k
      r = coolkey_add_object(priv, object_id, NULL, object_len, 0);
2223
3.05k
      if (r != SC_SUCCESS)
2224
2.34k
        sc_log(card->ctx, "coolkey_add_object() returned %d", r);
2225
3.05k
    }
2226
2227
    /* Read next object: error is handled on the cycle condition and below after cycle */
2228
3.07k
    r = coolkey_list_object(card, COOLKEY_LIST_NEXT, &object_info);
2229
3.07k
  }
2230
520
  if (r != SC_ERROR_FILE_END_REACHED) {
2231
    /* This means the card does not cooperate at all: bail out */
2232
451
    if (r >= 0) {
2233
5
      r = SC_ERROR_INVALID_CARD;
2234
5
    }
2235
451
    goto cleanup;
2236
451
  }
2237
  /* if we didn't pull the cuid from the combined object, then grab it now */
2238
69
  if (!combined_processed) {
2239
68
    global_platform_cplc_data_t cplc_data;
2240
    /* select the card manager, because a card with applet only will have
2241
       already selected the coolkey applet */
2242
2243
68
    r = gp_select_card_manager(card);
2244
68
    if (r < 0) {
2245
4
      goto cleanup;
2246
4
    }
2247
2248
64
    r = gp_get_cplc_data(card, &cplc_data);
2249
64
    if (r < 0) {
2250
22
      goto cleanup;
2251
22
    }
2252
42
    coolkey_make_cuid_from_cplc(&priv->cuid, &cplc_data);
2253
42
    priv->token_name = (u8 *)strdup("COOLKEY");
2254
42
    if (priv->token_name == NULL) {
2255
0
      r = SC_ERROR_OUT_OF_MEMORY;
2256
0
      goto cleanup;
2257
0
    }
2258
42
    priv->token_name_length = sizeof("COOLKEY")-1;
2259
42
  }
2260
43
  card->drv_data = priv;
2261
43
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2262
2263
571
cleanup:
2264
571
  if (priv) {
2265
571
    coolkey_free_private_data(priv);
2266
571
  }
2267
571
  LOG_FUNC_RETURN(card->ctx, r);
2268
571
}
2269
2270
2271
/* NOTE: returns a bool, 1 card matches, 0 it does not */
2272
static int coolkey_match_card(sc_card_t *card)
2273
6.06k
{
2274
6.06k
  int r;
2275
2276
6.06k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
2277
2278
6.06k
  r = coolkey_select_applet(card);
2279
6.06k
  if (r == SC_SUCCESS) {
2280
660
    sc_apdu_t apdu;
2281
2282
    /* The GET STATUS INS with P1 = 1 returns invalid instruction (0x6D00)
2283
     * on Coolkey applet (reserved for GetMemory function),
2284
     * while incorrect P1 (0x9C10) on Muscle applets
2285
     */
2286
660
    sc_format_apdu(card, &apdu, SC_APDU_CASE_1, COOLKEY_INS_GET_STATUS, 0x01, 0x00);
2287
660
    apdu.cla = COOLKEY_CLASS;
2288
660
    apdu.le = 0x00;
2289
660
    apdu.resplen = 0;
2290
660
    apdu.resp = NULL;
2291
660
    r = sc_transmit_apdu(card, &apdu);
2292
660
    if (r == SC_SUCCESS && apdu.sw1 == 0x6d && apdu.sw2 == 0x00) {
2293
614
      return 1;
2294
614
    }
2295
46
    return 0;
2296
660
  }
2297
5.40k
  return 0;
2298
6.06k
}
2299
2300
2301
static int coolkey_init(sc_card_t *card)
2302
614
{
2303
614
  int r;
2304
614
  unsigned long flags;
2305
614
  unsigned long ext_flags;
2306
614
  coolkey_private_data_t * priv;
2307
2308
614
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
2309
2310
614
  r = coolkey_initialize(card);
2311
614
  if (r < 0) {
2312
571
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD);
2313
571
  }
2314
2315
43
  card->type = SC_CARD_TYPE_COOLKEY_GENERIC;
2316
2317
  /* set Token Major/minor version */
2318
43
  flags = SC_ALGORITHM_RSA_RAW;
2319
2320
43
  _sc_card_add_rsa_alg(card, 1024, flags, 0); /* mandatory */
2321
43
  _sc_card_add_rsa_alg(card, 2048, flags, 0); /* optional */
2322
43
  _sc_card_add_rsa_alg(card, 3072, flags, 0); /* optional */
2323
2324
43
  flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE;
2325
43
  ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES;
2326
2327
43
  _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL);
2328
43
  _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL);
2329
43
  _sc_card_add_ec_alg(card, 521, flags, ext_flags, NULL);
2330
2331
2332
43
  priv = COOLKEY_DATA(card);
2333
43
  if (priv->pin_count != 0) {
2334
29
    card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO;
2335
29
  }
2336
2337
43
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2338
43
}
2339
2340
2341
static int
2342
coolkey_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left)
2343
0
{
2344
0
  int r;
2345
0
  coolkey_private_data_t * priv = COOLKEY_DATA(card);
2346
0
  size_t rbuflen;
2347
0
  u8 *rbuf;
2348
2349
  /* COOLKEY uses a separate pin from the card pin, managed by the applet.
2350
   * if we successfully log into coolkey, we will get a nonce, which we append
2351
   * to our APDUs to authenticate the apdu to the card. This allows coolkey to
2352
   * maintain separate per application login states without the application
2353
   * having to cache the pin */
2354
0
  switch (data->cmd) {
2355
0
  case SC_PIN_CMD_GET_INFO:
2356
0
    if (priv->nonce_valid) {
2357
0
      data->pin1.logged_in = SC_PIN_STATE_LOGGED_IN;
2358
0
    } else {
2359
0
      data->pin1.logged_in = SC_PIN_STATE_LOGGED_OUT;
2360
      /* coolkey retries is 100. It's unlikely the pin is block.
2361
       * instead, coolkey slows down the login command exponentially
2362
       */
2363
0
      data->pin1.tries_left = 0xf;
2364
0
    }
2365
0
    if (tries_left) {
2366
0
      *tries_left = data->pin1.tries_left;
2367
0
    }
2368
0
    r = SC_SUCCESS;
2369
0
    break;
2370
2371
0
  case SC_PIN_CMD_UNBLOCK:
2372
0
  case SC_PIN_CMD_CHANGE:
2373
    /* these 2 commands are currently reserved for TPS */
2374
0
  default:
2375
0
    r = SC_ERROR_NOT_SUPPORTED;
2376
0
    break;
2377
0
  case SC_PIN_CMD_VERIFY:
2378
    /* coolkey applet supports multiple pins, but TPS currently only uses one.
2379
     * just support the one pin for now (we need an array of nonces to handle
2380
     * multiple pins) */
2381
    /* coolkey only supports unpadded ascii pins, so no need to format the pin */
2382
0
    rbuflen = sizeof(priv->nonce);
2383
0
    rbuf = &priv->nonce[0];
2384
0
    r = coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_VERIFY_PIN,
2385
0
      data->pin_reference, 0, data->pin1.data, data->pin1.len,
2386
0
      &rbuf, &rbuflen, NULL, 0);
2387
0
    if (r < 0) {
2388
0
      break;
2389
0
    }
2390
0
    priv->nonce_valid = 1;
2391
0
    r = SC_SUCCESS;
2392
0
  }
2393
0
  return r;
2394
0
}
2395
2396
2397
static int
2398
coolkey_logout(sc_card_t *card)
2399
0
{
2400
  /* when we add multi pin support here, how do we know which pin to logout? */
2401
0
  coolkey_private_data_t * priv = COOLKEY_DATA(card);
2402
0
  u8 pin_ref = 0;
2403
2404
0
  (void) coolkey_apdu_io(card, COOLKEY_CLASS, COOLKEY_INS_LOGOUT, pin_ref, 0, NULL, 0, NULL, NULL,
2405
0
    priv->nonce, sizeof(priv->nonce));
2406
  /* even if logout failed on the card, flush the nonce and clear the nonce_valid and we are effectively
2407
   * logged out... needing to login again to get a nonce back */
2408
0
  memset(priv->nonce, 0, sizeof(priv->nonce));
2409
0
  priv->nonce_valid = 0;
2410
0
  return SC_SUCCESS;
2411
0
}
2412
2413
2414
static int coolkey_card_reader_lock_obtained(sc_card_t *card, int was_reset)
2415
13.5k
{
2416
13.5k
  int r = SC_SUCCESS;
2417
2418
13.5k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
2419
2420
13.5k
  if (was_reset > 0) {
2421
0
    r = coolkey_select_applet(card);
2422
0
  }
2423
2424
13.5k
  LOG_FUNC_RETURN(card->ctx, r);
2425
13.5k
}
2426
2427
static struct sc_card_operations coolkey_ops;
2428
2429
static struct sc_card_driver coolkey_drv = {
2430
  "COOLKEY",
2431
  "coolkey",
2432
  &coolkey_ops,
2433
  NULL, 0, NULL
2434
};
2435
2436
static struct sc_card_driver * sc_get_driver(void)
2437
9.27k
{
2438
9.27k
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
2439
2440
9.27k
  coolkey_ops = *iso_drv->ops;
2441
9.27k
  coolkey_ops.match_card = coolkey_match_card;
2442
9.27k
  coolkey_ops.init = coolkey_init;
2443
9.27k
  coolkey_ops.finish = coolkey_finish;
2444
2445
9.27k
  coolkey_ops.select_file =  coolkey_select_file; /* need to record object type */
2446
9.27k
  coolkey_ops.get_challenge = coolkey_get_challenge;
2447
9.27k
  coolkey_ops.read_binary = coolkey_read_binary;
2448
9.27k
  coolkey_ops.write_binary = coolkey_write_binary;
2449
9.27k
  coolkey_ops.set_security_env = coolkey_set_security_env;
2450
9.27k
  coolkey_ops.restore_security_env = coolkey_restore_security_env;
2451
9.27k
  coolkey_ops.compute_signature = coolkey_compute_crypt;
2452
9.27k
  coolkey_ops.decipher =  coolkey_compute_crypt;
2453
9.27k
  coolkey_ops.card_ctl = coolkey_card_ctl;
2454
9.27k
  coolkey_ops.check_sw = coolkey_check_sw;
2455
9.27k
  coolkey_ops.pin_cmd = coolkey_pin_cmd;
2456
9.27k
  coolkey_ops.logout = coolkey_logout;
2457
9.27k
  coolkey_ops.card_reader_lock_obtained = coolkey_card_reader_lock_obtained;
2458
2459
9.27k
  return &coolkey_drv;
2460
9.27k
}
2461
2462
2463
struct sc_card_driver * sc_get_coolkey_driver(void)
2464
9.27k
{
2465
9.27k
  return sc_get_driver();
2466
9.27k
}
2467