Coverage Report

Created: 2026-07-24 06:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/card-oberthur.c
Line
Count
Source
1
/*
2
 * card-oberthur.c: Support for Oberthur smart cards
3
 *    CosmopolIC  v5;
4
 *
5
 * Copyright (C) 2001, 2002  Juha Yrjölä <juha.yrjola@iki.fi>
6
 * Copyright (C) 2009  Viktor Tarasov <viktor.tarasov@opentrust.com>,
7
 *                     OpenTrust <www.opentrust.com>
8
 *
9
 * This library is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with this library; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
 *
23
 * best view with tabstop=4
24
 */
25
26
#ifdef HAVE_CONFIG_H
27
#include "config.h"
28
#endif
29
30
#ifdef ENABLE_OPENSSL /* empty file without openssl */
31
#include <stdlib.h>
32
#include <string.h>
33
#include <ctype.h>
34
#include <openssl/evp.h>
35
36
#include "internal.h"
37
#include "cardctl.h"
38
#include "pkcs15.h"
39
#include "gp.h"
40
41
23
#define OBERTHUR_PIN_LOCAL  0x80
42
0
#define OBERTHUR_PIN_REFERENCE_USER 0x81
43
0
#define OBERTHUR_PIN_REFERENCE_ONETIME  0x82
44
#define OBERTHUR_PIN_REFERENCE_SO 0x04
45
0
#define OBERTHUR_PIN_REFERENCE_PUK  0x84
46
47
static const struct sc_atr_table oberthur_atrs[] = {
48
  { "3B:7D:18:00:00:00:31:80:71:8E:64:77:E3:01:00:82:90:00", NULL,
49
      "Oberthur 64k v4/2.1.1", SC_CARD_TYPE_OBERTHUR_64K, 0, NULL },
50
  { "3B:7D:18:00:00:00:31:80:71:8E:64:77:E3:02:00:82:90:00", NULL,
51
      "Oberthur 64k v4/2.1.1", SC_CARD_TYPE_OBERTHUR_64K, 0, NULL },
52
  { "3B:7D:11:00:00:00:31:80:71:8E:64:77:E3:01:00:82:90:00", NULL,
53
      "Oberthur 64k v5", SC_CARD_TYPE_OBERTHUR_64K, 0, NULL },
54
  { "3B:7D:11:00:00:00:31:80:71:8E:64:77:E3:02:00:82:90:00", NULL,
55
      "Oberthur 64k v5/2.2.0", SC_CARD_TYPE_OBERTHUR_64K, 0, NULL },
56
  { "3B:7B:18:00:00:00:31:C0:64:77:E3:03:00:82:90:00", NULL,
57
      "Oberthur 64k CosmopolIC v5.2/2.2", SC_CARD_TYPE_OBERTHUR_64K, 0, NULL },
58
  { "3B:FB:11:00:00:81:31:FE:45:00:31:C0:64:77:E9:10:00:00:90:00:6A", NULL,
59
      "OCS ID-One Cosmo Card", SC_CARD_TYPE_OBERTHUR_64K, 0, NULL },
60
  { NULL, NULL, NULL, 0, 0, NULL }
61
};
62
63
struct auth_senv {
64
  unsigned long algorithm;
65
  int key_file_id;
66
  size_t key_size;
67
};
68
69
struct auth_private_data {
70
  unsigned char aid[SC_MAX_AID_SIZE];
71
  int aid_len;
72
73
  struct sc_pin_cmd_pin pin_info;
74
  struct auth_senv senv;
75
76
  long int sn;
77
};
78
79
struct auth_update_component_info {
80
  enum SC_CARDCTL_OBERTHUR_KEY_TYPE  type;
81
  unsigned int    component;
82
  unsigned char   *data;
83
  size_t    len;
84
};
85
86
87
static const unsigned char *aidAuthentIC_V5 =
88
    (const unsigned char *)"\xA0\x00\x00\x00\x77\x01\x03\x03\x00\x00\x00\xF1\x00\x00\x00\x02";
89
static const int lenAidAuthentIC_V5 = 16;
90
static const char *nameAidAuthentIC_V5 = "AuthentIC v5";
91
92
0
#define OBERTHUR_AUTH_TYPE_PIN    1
93
0
#define OBERTHUR_AUTH_TYPE_PUK    2
94
95
0
#define OBERTHUR_AUTH_MAX_LENGTH_PIN  64
96
0
#define OBERTHUR_AUTH_MAX_LENGTH_PUK  16
97
98
#define SC_OBERTHUR_MAX_ATTR_SIZE 8
99
100
1
#define PUBKEY_512_ASN1_SIZE  0x4A
101
1
#define PUBKEY_1024_ASN1_SIZE 0x8C
102
0
#define PUBKEY_2048_ASN1_SIZE 0x10E
103
104
static unsigned char rsa_der[PUBKEY_2048_ASN1_SIZE];
105
static size_t rsa_der_len = 0;
106
107
static struct sc_file *auth_current_ef = NULL,  *auth_current_df = NULL;
108
static struct sc_card_operations auth_ops;
109
static struct sc_card_operations *iso_ops;
110
static struct sc_card_driver auth_drv = {
111
  "Oberthur AuthentIC.v2/CosmopolIC.v4",
112
  "oberthur",
113
  &auth_ops,
114
  NULL, 0, NULL
115
};
116
117
static int auth_get_pin_reference (struct sc_card *card,
118
    int type, int reference, int cmd, int *out_ref);
119
static int auth_read_component(struct sc_card *card,
120
    enum SC_CARDCTL_OBERTHUR_KEY_TYPE type, int num,
121
    unsigned char *out, size_t outlen);
122
static int auth_pin_is_verified(struct sc_card *card, int pin_reference,
123
    int *tries_left);
124
static int auth_pin_verify(struct sc_card *card, unsigned int type,
125
    struct sc_pin_cmd_data *data);
126
static int auth_pin_reset(struct sc_card *card, unsigned int type,
127
    struct sc_pin_cmd_data *data);
128
static int auth_create_reference_data (struct sc_card *card,
129
    struct sc_cardctl_oberthur_createpin_info *args);
130
static int auth_get_serialnr(struct sc_card *card, struct sc_serial_number *serial);
131
static int auth_select_file(struct sc_card *card, const struct sc_path *in_path,
132
    struct sc_file **file_out);
133
static int acl_to_ac_byte(struct sc_card *card, const struct sc_acl_entry *e);
134
135
static int
136
auth_finish(struct sc_card *card)
137
98
{
138
98
  free(card->drv_data);
139
98
  return SC_SUCCESS;
140
98
}
141
142
143
static int
144
auth_select_aid(struct sc_card *card)
145
135
{
146
135
  struct sc_apdu apdu;
147
135
  unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE];
148
135
  struct auth_private_data *data = (struct auth_private_data *)card->drv_data;
149
135
  int rv, ii;
150
135
  struct sc_path tmp_path;
151
152
  /* Select Card Manager (to deselect previously selected application) */
153
135
  rv = gp_select_card_manager(card);
154
135
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
155
156
  /* Get smart card serial number */
157
108
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, 0x9F, 0x7F);
158
108
  apdu.cla = 0x80;
159
108
  apdu.le = 0x2D;
160
108
  apdu.resplen = 0x30;
161
108
  apdu.resp = apdu_resp;
162
163
108
  rv = sc_transmit_apdu(card, &apdu);
164
108
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
165
107
  if (apdu.resplen < 20) {
166
2
    LOG_TEST_RET(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Serial number has incorrect length");
167
2
  }
168
105
  card->serialnr.len = 4;
169
105
  memcpy(card->serialnr.value, apdu.resp+15, 4);
170
171
525
  for (ii=0, data->sn = 0; ii < 4; ii++)
172
420
    data->sn += (long int)(*(apdu.resp + 15 + ii)) << (3-ii)*8;
173
174
105
  sc_log(card->ctx, "serial number %li/0x%lX", data->sn, data->sn);
175
176
105
  memset(&tmp_path, 0, sizeof(struct sc_path));
177
105
  tmp_path.type = SC_PATH_TYPE_DF_NAME;
178
105
  memcpy(tmp_path.value, aidAuthentIC_V5, lenAidAuthentIC_V5);
179
105
  tmp_path.len = lenAidAuthentIC_V5;
180
181
105
  rv = iso_ops->select_file(card, &tmp_path, NULL);
182
105
  LOG_TEST_RET(card->ctx, rv, "select parent failed");
183
184
100
  sc_format_path("3F00", &tmp_path);
185
100
  sc_file_free(auth_current_df);
186
100
  auth_current_df = NULL;
187
100
  rv = iso_ops->select_file(card, &tmp_path, &auth_current_df);
188
100
  LOG_TEST_RET(card->ctx, rv, "select parent failed");
189
190
98
  sc_file_free(auth_current_ef);
191
98
  auth_current_ef = NULL;
192
98
  sc_file_dup(&auth_current_ef, auth_current_df);
193
194
98
  memcpy(data->aid, aidAuthentIC_V5, lenAidAuthentIC_V5);
195
98
  data->aid_len = lenAidAuthentIC_V5;
196
98
  card->name = nameAidAuthentIC_V5;
197
198
98
  LOG_FUNC_RETURN(card->ctx, rv);
199
98
}
200
201
202
static int
203
auth_match_card(struct sc_card *card)
204
8.07k
{
205
8.07k
  if (_sc_match_atr(card, oberthur_atrs, &card->type) < 0)
206
7.94k
    return 0;
207
135
  else
208
135
    return 1;
209
8.07k
}
210
211
212
static int
213
auth_init(struct sc_card *card)
214
135
{
215
135
  struct auth_private_data *data;
216
135
  struct sc_path path;
217
135
  unsigned long flags;
218
135
  int rv = 0;
219
220
135
  data = calloc(1, sizeof(struct auth_private_data));
221
135
  if (!data)
222
135
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
223
224
135
  card->cla = 0x00;
225
135
  card->drv_data = data;
226
227
135
  card->caps |= SC_CARD_CAP_RNG;
228
135
  card->caps |= SC_CARD_CAP_USE_FCI_AC;
229
230
135
  if (auth_select_aid(card)) {
231
37
    sc_log(card->ctx, "Failed to initialize %s", card->name);
232
37
    rv = SC_ERROR_INVALID_CARD;
233
37
    LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_CARD, "Failed to initialize");
234
37
  }
235
236
98
  sc_format_path("3F00", &path);
237
98
  rv = auth_select_file(card, &path, NULL);
238
239
135
err:
240
135
  if (rv == SC_SUCCESS) {
241
98
    flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_PAD_ISO9796;
242
98
    flags |= SC_ALGORITHM_RSA_HASH_NONE;
243
98
    flags |= SC_ALGORITHM_ONBOARD_KEY_GEN;
244
245
98
    _sc_card_add_rsa_alg(card, 512, flags, 0);
246
98
    _sc_card_add_rsa_alg(card, 1024, flags, 0);
247
98
    _sc_card_add_rsa_alg(card, 2048, flags, 0);
248
98
  } else {
249
37
    free(card->drv_data);
250
37
    card->drv_data = NULL;
251
37
  }
252
253
135
  LOG_FUNC_RETURN(card->ctx, rv);
254
135
}
255
256
257
static void
258
add_acl_entry(struct sc_card *card, struct sc_file *file, unsigned int op,
259
    unsigned char acl_byte)
260
138
{
261
138
  if ((acl_byte & 0xE0) == 0x60) {
262
19
    sc_log(card->ctx, "called; op 0x%X; SC_AC_PRO; ref 0x%X", op, acl_byte);
263
19
    sc_file_add_acl_entry(file, op, SC_AC_PRO, acl_byte);
264
19
    return;
265
19
  }
266
267
119
  switch (acl_byte) {
268
13
  case 0x00:
269
13
    sc_file_add_acl_entry(file, op, SC_AC_NONE, SC_AC_KEY_REF_NONE);
270
13
    break;
271
  /* User and OneTime PINs are locals */
272
10
  case 0x21:
273
23
  case 0x22:
274
23
    sc_file_add_acl_entry(file, op, SC_AC_CHV, (acl_byte & 0x0F) | OBERTHUR_PIN_LOCAL);
275
23
    break;
276
  /* Local SOPIN is only for the unblocking. */
277
19
  case 0x24:
278
35
  case 0x25:
279
35
    if (op == SC_AC_OP_PIN_RESET)
280
2
      sc_file_add_acl_entry(file, op, SC_AC_CHV, 0x84);
281
33
    else
282
33
      sc_file_add_acl_entry(file, op, SC_AC_CHV, 0x04);
283
35
    break;
284
15
  case 0xFF:
285
15
    sc_file_add_acl_entry(file, op, SC_AC_NEVER, SC_AC_KEY_REF_NONE);
286
15
    break;
287
33
  default:
288
33
    sc_file_add_acl_entry(file, op, SC_AC_UNKNOWN, SC_AC_KEY_REF_NONE);
289
33
    break;
290
119
  }
291
119
}
292
293
294
static int
295
auth_process_fci(struct sc_card *card, struct sc_file *file,
296
            const unsigned char *buf, size_t buflen)
297
78
{
298
78
  unsigned char type;
299
78
  const unsigned char *attr;
300
78
  size_t attr_len = 0;
301
302
78
  LOG_FUNC_CALLED(card->ctx);
303
78
  attr = sc_asn1_find_tag(card->ctx, buf, buflen, 0x82, &attr_len);
304
78
  if (!attr || attr_len < 1)
305
78
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
306
68
  type = attr[0];
307
308
68
  attr = sc_asn1_find_tag(card->ctx, buf, buflen, 0x83, &attr_len);
309
68
  if (!attr || attr_len < 2)
310
68
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
311
65
  file->id = attr[0]*0x100 + attr[1];
312
313
65
  attr = sc_asn1_find_tag(card->ctx, buf, buflen, type==0x01 ? 0x80 : 0x85, &attr_len);
314
65
  switch (type) {
315
5
  case 0x01:
316
5
    if (!attr || attr_len < 2)
317
5
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
318
3
    file->type = SC_FILE_TYPE_WORKING_EF;
319
3
    file->ef_structure = SC_FILE_EF_TRANSPARENT;
320
3
    file->size = attr[0]*0x100 + attr[1];
321
3
    break;
322
4
  case 0x04:
323
4
    if (!attr || attr_len < 1)
324
4
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
325
1
    file->type = SC_FILE_TYPE_WORKING_EF;
326
1
    file->ef_structure = SC_FILE_EF_LINEAR_VARIABLE;
327
1
    file->size = attr[0];
328
1
    attr = sc_asn1_find_tag(card->ctx, buf, buflen, 0x82, &attr_len);
329
1
    if (!attr || attr_len < 5)
330
1
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
331
0
    file->record_length = attr[2]*0x100+attr[3];
332
0
    file->record_count = attr[4];
333
0
    break;
334
8
  case 0x11:
335
8
    if (!attr || attr_len < 2)
336
8
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
337
6
    file->type = SC_FILE_TYPE_INTERNAL_EF;
338
6
    file->ef_structure = SC_CARDCTL_OBERTHUR_KEY_DES;
339
6
    file->size = attr[0]*0x100 + attr[1];
340
6
    file->size /= 8;
341
6
    break;
342
26
  case 0x12:
343
26
    if (!attr || attr_len < 2)
344
26
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
345
24
    file->type = SC_FILE_TYPE_INTERNAL_EF;
346
24
    file->ef_structure = SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC;
347
348
24
    file->size = attr[0]*0x100 + attr[1];
349
24
    if (file->size==512)
350
1
      file->size = PUBKEY_512_ASN1_SIZE;
351
23
    else if (file->size==1024)
352
1
      file->size = PUBKEY_1024_ASN1_SIZE;
353
22
    else if (file->size==2048)
354
0
      file->size = PUBKEY_2048_ASN1_SIZE;
355
22
    else {
356
22
      sc_log(card->ctx,
357
22
             "Not supported public key size: %"SC_FORMAT_LEN_SIZE_T"u",
358
22
             file->size);
359
22
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
360
22
    }
361
2
    break;
362
4
  case 0x14:
363
4
    if (!attr || attr_len < 2)
364
4
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
365
2
    file->type = SC_FILE_TYPE_INTERNAL_EF;
366
2
    file->ef_structure = SC_CARDCTL_OBERTHUR_KEY_RSA_CRT;
367
2
    file->size = attr[0]*0x100 + attr[1];
368
2
    break;
369
17
  case 0x38:
370
17
    if (!attr || attr_len < 1)
371
17
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
372
15
    file->type = SC_FILE_TYPE_DF;
373
15
    file->size = attr[0];
374
15
    if (SC_SUCCESS != sc_file_set_type_attr(file,attr,attr_len))
375
15
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
376
15
    break;
377
15
  default:
378
1
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
379
65
  }
380
381
28
  attr = sc_asn1_find_tag(card->ctx, buf, buflen, 0x86, &attr_len);
382
28
  if (!attr || attr_len < 8)
383
28
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
384
385
21
  if (file->type == SC_FILE_TYPE_DF) {
386
12
    add_acl_entry(card, file, SC_AC_OP_CREATE, attr[0]);
387
12
    add_acl_entry(card, file, SC_AC_OP_CRYPTO, attr[1]);
388
12
    add_acl_entry(card, file, SC_AC_OP_LIST_FILES, attr[2]);
389
12
    add_acl_entry(card, file, SC_AC_OP_DELETE, attr[3]);
390
12
    add_acl_entry(card, file, SC_AC_OP_PIN_DEFINE, attr[4]);
391
12
    add_acl_entry(card, file, SC_AC_OP_PIN_CHANGE, attr[5]);
392
12
    add_acl_entry(card, file, SC_AC_OP_PIN_RESET, attr[6]);
393
12
    sc_log(card->ctx, "SC_FILE_TYPE_DF:CRYPTO %X", attr[1]);
394
12
  } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { /* EF */
395
7
    switch (file->ef_structure) {
396
6
    case SC_CARDCTL_OBERTHUR_KEY_DES:
397
6
      add_acl_entry(card, file, SC_AC_OP_UPDATE, attr[0]);
398
6
      add_acl_entry(card, file, SC_AC_OP_PSO_DECRYPT, attr[1]);
399
6
      add_acl_entry(card, file, SC_AC_OP_PSO_ENCRYPT, attr[2]);
400
6
      add_acl_entry(card, file, SC_AC_OP_PSO_COMPUTE_CHECKSUM, attr[3]);
401
6
      add_acl_entry(card, file, SC_AC_OP_PSO_VERIFY_CHECKSUM, attr[4]);
402
6
      add_acl_entry(card, file, SC_AC_OP_INTERNAL_AUTHENTICATE, attr[5]);
403
6
      add_acl_entry(card, file, SC_AC_OP_EXTERNAL_AUTHENTICATE, attr[6]);
404
6
      break;
405
0
    case SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC:
406
0
      add_acl_entry(card, file, SC_AC_OP_UPDATE, attr[0]);
407
0
      add_acl_entry(card, file, SC_AC_OP_PSO_ENCRYPT, attr[2]);
408
0
      add_acl_entry(card, file, SC_AC_OP_PSO_VERIFY_SIGNATURE, attr[4]);
409
0
      add_acl_entry(card, file, SC_AC_OP_EXTERNAL_AUTHENTICATE, attr[6]);
410
0
      break;
411
1
    case SC_CARDCTL_OBERTHUR_KEY_RSA_CRT:
412
1
      add_acl_entry(card, file, SC_AC_OP_UPDATE, attr[0]);
413
1
      add_acl_entry(card, file, SC_AC_OP_PSO_DECRYPT, attr[1]);
414
1
      add_acl_entry(card, file, SC_AC_OP_PSO_COMPUTE_SIGNATURE, attr[3]);
415
1
      add_acl_entry(card, file, SC_AC_OP_INTERNAL_AUTHENTICATE, attr[5]);
416
1
      break;
417
7
    }
418
7
  } else {
419
2
    switch (file->ef_structure) {
420
2
    case SC_FILE_EF_TRANSPARENT:
421
2
      add_acl_entry(card, file, SC_AC_OP_WRITE, attr[0]);
422
2
      add_acl_entry(card, file, SC_AC_OP_UPDATE, attr[1]);
423
2
      add_acl_entry(card, file, SC_AC_OP_READ, attr[2]);
424
2
      add_acl_entry(card, file, SC_AC_OP_ERASE, attr[3]);
425
2
      break;
426
0
    case SC_FILE_EF_LINEAR_VARIABLE:
427
0
      add_acl_entry(card, file, SC_AC_OP_WRITE, attr[0]);
428
0
      add_acl_entry(card, file, SC_AC_OP_UPDATE, attr[1]);
429
0
      add_acl_entry(card, file, SC_AC_OP_READ, attr[2]);
430
0
      add_acl_entry(card, file, SC_AC_OP_ERASE, attr[3]);
431
0
      break;
432
2
    }
433
2
  }
434
435
21
  file->status = SC_FILE_STATUS_ACTIVATED;
436
21
  file->magic = SC_FILE_MAGIC;
437
438
21
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
439
21
}
440
441
442
static int
443
auth_select_file(struct sc_card *card, const struct sc_path *in_path,
444
         struct sc_file **file_out)
445
98
{
446
98
  struct sc_path path;
447
98
  struct sc_file *tmp_file = NULL;
448
98
  size_t offs, ii;
449
98
  int rv;
450
451
98
  if (card == NULL || in_path == NULL)
452
0
    return SC_ERROR_INTERNAL;
453
454
98
  LOG_FUNC_CALLED(card->ctx);
455
456
98
  memcpy(&path, in_path, sizeof(struct sc_path));
457
458
98
  if (!auth_current_df)
459
0
    return SC_ERROR_OBJECT_NOT_FOUND;
460
461
98
  sc_log(card->ctx, "in_path; type=%d, path=%s, out %p",
462
98
      in_path->type, sc_print_path(in_path), file_out);
463
98
  sc_log(card->ctx, "current path; type=%d, path=%s",
464
98
      auth_current_df->path.type, sc_print_path(&auth_current_df->path));
465
98
  if (auth_current_ef)
466
98
    sc_log(card->ctx, "current file; type=%d, path=%s",
467
98
        auth_current_ef->path.type, sc_print_path(&auth_current_ef->path));
468
469
98
  if (path.type == SC_PATH_TYPE_PARENT || path.type == SC_PATH_TYPE_FILE_ID) {
470
0
    sc_file_free(auth_current_ef);
471
0
    auth_current_ef = NULL;
472
473
0
    rv = iso_ops->select_file(card, &path, &tmp_file);
474
0
    LOG_TEST_RET(card->ctx, rv, "select file failed");
475
0
    if (!tmp_file)
476
0
      return SC_ERROR_OBJECT_NOT_FOUND;
477
478
0
    if (path.type == SC_PATH_TYPE_PARENT) {
479
0
      memcpy(&tmp_file->path, &auth_current_df->path, sizeof(struct sc_path));
480
0
      if (tmp_file->path.len > 2)
481
0
        tmp_file->path.len -= 2;
482
483
0
      sc_file_free(auth_current_df);
484
0
      auth_current_df = NULL;
485
0
      sc_file_dup(&auth_current_df, tmp_file);
486
0
    } else {
487
0
      if (tmp_file->type == SC_FILE_TYPE_DF) {
488
0
        sc_concatenate_path(&tmp_file->path, &auth_current_df->path, &path);
489
490
0
        sc_file_free(auth_current_df);
491
0
        auth_current_df = NULL;
492
0
        sc_file_dup(&auth_current_df, tmp_file);
493
0
      } else {
494
0
        sc_file_free(auth_current_ef);
495
0
        auth_current_ef = NULL;
496
497
0
        sc_file_dup(&auth_current_ef, tmp_file);
498
0
        sc_concatenate_path(&auth_current_ef->path, &auth_current_df->path, &path);
499
0
      }
500
0
    }
501
0
    if (file_out) {
502
0
      sc_file_free(*file_out);
503
0
      sc_file_dup(file_out, tmp_file);
504
0
    }
505
506
0
    sc_file_free(tmp_file);
507
98
  } else if (path.type == SC_PATH_TYPE_DF_NAME) {
508
0
    rv = iso_ops->select_file(card, &path, NULL);
509
0
    if (rv) {
510
0
      sc_file_free(auth_current_ef);
511
0
      auth_current_ef = NULL;
512
0
    }
513
0
    LOG_TEST_RET(card->ctx, rv, "select file failed");
514
98
  } else {
515
196
    for (offs = 0; offs < path.len && offs < auth_current_df->path.len; offs += 2)
516
98
      if (path.value[offs] != auth_current_df->path.value[offs] ||
517
98
          path.value[offs + 1] != auth_current_df->path.value[offs + 1])
518
0
        break;
519
520
98
    sc_log(card->ctx, "offs %"SC_FORMAT_LEN_SIZE_T"u", offs);
521
98
    if (offs && offs < auth_current_df->path.len) {
522
0
      size_t deep = auth_current_df->path.len - offs;
523
524
0
      sc_log(card->ctx, "deep %"SC_FORMAT_LEN_SIZE_T"u",
525
0
             deep);
526
0
      for (ii = 0; ii < deep; ii += 2) {
527
0
        struct sc_path tmp_path;
528
529
0
        memcpy(&tmp_path, &auth_current_df->path,  sizeof(struct sc_path));
530
0
        tmp_path.type = SC_PATH_TYPE_PARENT;
531
532
0
        if (file_out) {
533
0
          sc_file_free(*file_out);
534
0
          *file_out = NULL;
535
0
        }
536
537
0
        rv = auth_select_file (card, &tmp_path, file_out);
538
0
        LOG_TEST_RET(card->ctx, rv, "select file failed");
539
0
      }
540
0
    }
541
542
98
    if (path.len > offs) {
543
0
      struct sc_path tmp_path;
544
545
0
      memset(&tmp_path, 0, sizeof(struct sc_path));
546
0
      tmp_path.type = SC_PATH_TYPE_FILE_ID;
547
0
      tmp_path.len = 2;
548
549
0
      for (ii = 0; ii < path.len - offs; ii += 2) {
550
0
        memcpy(tmp_path.value, path.value + offs + ii, 2);
551
552
0
        if (file_out) {
553
0
          sc_file_free(*file_out);
554
0
          *file_out = NULL;
555
0
        }
556
557
0
        rv = auth_select_file(card, &tmp_path, file_out);
558
0
        LOG_TEST_RET(card->ctx, rv, "select file failed");
559
0
      }
560
98
    } else if (path.len - offs == 0 && file_out) {
561
0
      if (sc_compare_path(&path, &auth_current_df->path) && file_out) {
562
0
        sc_file_free(*file_out);
563
0
        sc_file_dup(file_out, auth_current_df);
564
0
      } else  if (auth_current_ef && file_out) {
565
0
        sc_file_free(*file_out);
566
0
        sc_file_dup(file_out, auth_current_ef);
567
0
      } else {
568
0
        LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "No current EF");
569
0
      }
570
0
    }
571
98
  }
572
573
98
  LOG_FUNC_RETURN(card->ctx, 0);
574
98
}
575
576
577
static int
578
auth_list_files(struct sc_card *card, unsigned char *buf, size_t buflen)
579
98
{
580
98
  struct sc_apdu apdu;
581
98
  unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE];
582
98
  int rv;
583
584
98
  LOG_FUNC_CALLED(card->ctx);
585
98
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x34, 0, 0);
586
98
  apdu.cla = 0x80;
587
98
  apdu.le = 0x40;
588
98
  apdu.resplen = sizeof(rbuf);
589
98
  apdu.resp = rbuf;
590
591
98
  rv = sc_transmit_apdu(card, &apdu);
592
98
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
593
594
93
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
595
93
  LOG_TEST_RET(card->ctx, rv, "Card returned error");
596
597
20
  if (apdu.resplen == 0x100 && rbuf[0]==0 && rbuf[1]==0)
598
20
    LOG_FUNC_RETURN(card->ctx, 0);
599
600
19
  buflen = MIN(buflen, apdu.resplen);
601
19
  memcpy(buf, rbuf, buflen);
602
603
19
  LOG_FUNC_RETURN(card->ctx, (int)buflen);
604
19
}
605
606
607
static int
608
auth_delete_file(struct sc_card *card, const struct sc_path *path)
609
0
{
610
0
  struct sc_apdu apdu;
611
0
  unsigned char sbuf[2];
612
0
  int rv;
613
0
  char pbuf[SC_MAX_PATH_STRING_SIZE];
614
615
0
  LOG_FUNC_CALLED(card->ctx);
616
617
0
  rv = sc_path_print(pbuf, sizeof(pbuf), path);
618
0
  if (rv != SC_SUCCESS)
619
0
    pbuf[0] = '\0';
620
621
0
  sc_log(card->ctx, "path; type=%d, path=%s", path->type, pbuf);
622
623
0
  if (path->len < 2) {
624
0
    sc_log(card->ctx, "Invalid path length");
625
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
626
0
  }
627
628
0
  if (path->len > 2) {
629
0
    struct sc_path parent = *path;
630
631
0
    parent.len -= 2;
632
0
    parent.type = SC_PATH_TYPE_PATH;
633
0
    rv = auth_select_file(card, &parent, NULL);
634
0
    LOG_TEST_RET(card->ctx, rv, "select parent failed ");
635
0
  }
636
637
0
  sbuf[0] = path->value[path->len - 2];
638
0
  sbuf[1] = path->value[path->len - 1];
639
640
0
  if (memcmp(sbuf,"\x00\x00",2)==0 || (memcmp(sbuf,"\xFF\xFF",2)==0) ||
641
0
      memcmp(sbuf,"\x3F\xFF",2)==0)
642
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS);
643
644
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x02, 0x00);
645
0
  apdu.lc = 2;
646
0
  apdu.datalen = 2;
647
0
  apdu.data = sbuf;
648
649
0
  rv = sc_transmit_apdu(card, &apdu);
650
0
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
651
0
  if (apdu.sw1 == 0x6A && apdu.sw2 == 0x82) {
652
    /* Clean up tDF contents.*/
653
0
    struct sc_path tmp_path;
654
0
    int ii, len;
655
0
    unsigned char lbuf[SC_MAX_APDU_BUFFER_SIZE];
656
657
0
    memset(&tmp_path, 0, sizeof(struct sc_path));
658
0
    tmp_path.type = SC_PATH_TYPE_FILE_ID;
659
0
    memcpy(tmp_path.value, sbuf, 2);
660
0
    tmp_path.len = 2;
661
0
    rv = auth_select_file(card, &tmp_path, NULL);
662
0
    LOG_TEST_RET(card->ctx, rv, "select DF failed");
663
664
0
    len = auth_list_files(card, lbuf, sizeof(lbuf));
665
0
    LOG_TEST_RET(card->ctx, len, "list DF failed");
666
667
0
    for (ii = 0; ii < len / 2; ii++) {
668
0
      struct sc_path tmp_path_x;
669
670
0
      memset(&tmp_path_x, 0, sizeof(struct sc_path));
671
0
      tmp_path_x.type = SC_PATH_TYPE_FILE_ID;
672
0
      tmp_path_x.value[0] = *(lbuf + ii*2);
673
0
      tmp_path_x.value[1] = *(lbuf + ii*2 + 1);
674
0
      tmp_path_x.len = 2;
675
676
0
      rv = auth_delete_file(card, &tmp_path_x);
677
0
      LOG_TEST_RET(card->ctx, rv, "delete failed");
678
0
    }
679
680
0
    tmp_path.type = SC_PATH_TYPE_PARENT;
681
0
    rv = auth_select_file(card, &tmp_path, NULL);
682
0
    LOG_TEST_RET(card->ctx, rv, "select parent failed");
683
684
0
    apdu.p1 = 1;
685
0
    rv = sc_transmit_apdu(card, &apdu);
686
0
  }
687
688
0
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
689
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
690
691
0
  LOG_FUNC_RETURN(card->ctx, rv);
692
0
}
693
694
695
static int
696
acl_to_ac_byte(struct sc_card *card, const struct sc_acl_entry *e)
697
0
{
698
0
  unsigned key_ref;
699
700
0
  if (e == NULL)
701
0
    return SC_ERROR_OBJECT_NOT_FOUND;
702
703
0
  key_ref = e->key_ref & ~OBERTHUR_PIN_LOCAL;
704
705
0
  switch (e->method) {
706
0
  case SC_AC_NONE:
707
0
    LOG_FUNC_RETURN(card->ctx, 0);
708
709
0
  case SC_AC_CHV:
710
0
    if (key_ref > 0 && key_ref < 6)
711
0
      LOG_FUNC_RETURN(card->ctx, (0x20 | key_ref));
712
0
    else
713
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS);
714
715
0
  case SC_AC_PRO:
716
0
    if (((key_ref & 0xE0) != 0x60) || ((key_ref & 0x18) == 0))
717
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS);
718
0
    else
719
0
      LOG_FUNC_RETURN(card->ctx, key_ref);
720
721
0
  case SC_AC_NEVER:
722
0
    return 0xff;
723
0
  }
724
725
0
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS);
726
0
}
727
728
729
static int
730
encode_file_structure_V5(struct sc_card *card, const struct sc_file *file,
731
         unsigned char *buf, size_t *buflen)
732
0
{
733
0
  size_t ii;
734
0
  int rv = 0;
735
0
  size_t size;
736
0
  unsigned char *p = buf;
737
0
  unsigned char  ops[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
738
739
0
  LOG_FUNC_CALLED(card->ctx);
740
0
  sc_log(card->ctx,
741
0
         "id %04X; size %"SC_FORMAT_LEN_SIZE_T"u; type 0x%X/0x%X",
742
0
         file->id, file->size, file->type, file->ef_structure);
743
744
0
  if (*buflen < 0x18)
745
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS);
746
747
0
  p[0] = 0x62, p[1] = 0x16;
748
0
  p[2] = 0x82, p[3] = 0x02;
749
750
0
  rv = 0;
751
0
  if (file->type == SC_FILE_TYPE_DF) {
752
0
    p[4] = 0x38;
753
0
    p[5] = 0x00;
754
0
  } else if (file->type == SC_FILE_TYPE_WORKING_EF) {
755
0
    switch (file->ef_structure) {
756
0
    case SC_FILE_EF_TRANSPARENT:
757
0
      p[4] = 0x01;
758
0
      p[5] = 0x01;
759
0
      break;
760
0
    case SC_FILE_EF_LINEAR_VARIABLE:
761
0
      p[4] = 0x04;
762
0
      p[5] = 0x01;
763
0
      break;
764
0
    default:
765
0
      rv = SC_ERROR_INVALID_ARGUMENTS;
766
0
      break;
767
0
    }
768
0
  } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) {
769
0
    switch (file->ef_structure) {
770
0
    case SC_CARDCTL_OBERTHUR_KEY_DES:
771
0
      p[4] = 0x11;
772
0
      p[5] = 0x00;
773
0
      break;
774
0
    case SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC:
775
0
      p[4] = 0x12;
776
0
      p[5] = 0x00;
777
0
      break;
778
0
    case SC_CARDCTL_OBERTHUR_KEY_RSA_CRT:
779
0
      p[4] = 0x14;
780
0
      p[5] = 0x00;
781
0
      break;
782
0
    default:
783
0
      rv = -1;
784
0
      break;
785
0
    }
786
0
  } else
787
0
    rv = SC_ERROR_INVALID_ARGUMENTS;
788
789
0
  if (rv) {
790
0
    sc_log(card->ctx, "Invalid EF structure 0x%X/0x%X", file->type, file->ef_structure);
791
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS);
792
0
  }
793
794
0
  p[6] = 0x83;
795
0
  p[7] = 0x02;
796
0
  p[8] = file->id >> 8;
797
0
  p[9] = file->id & 0xFF;
798
799
0
  p[10] = 0x85;
800
0
  p[11] = 0x02;
801
802
0
  size = file->size;
803
804
0
  if (file->type == SC_FILE_TYPE_DF) {
805
0
    size &= 0xFF;
806
0
  } else if (file->type == SC_FILE_TYPE_INTERNAL_EF &&
807
0
      file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) {
808
0
    sc_log(card->ctx, "ef %s","SC_FILE_EF_RSA_PUBLIC");
809
0
    if (file->size == PUBKEY_512_ASN1_SIZE || file->size == 512)
810
0
      size = 512;
811
0
    else if (file->size == PUBKEY_1024_ASN1_SIZE || file->size == 1024)
812
0
      size = 1024;
813
0
    else if (file->size == PUBKEY_2048_ASN1_SIZE || file->size == 2048)
814
0
      size = 2048;
815
0
    else {
816
0
      sc_log(card->ctx,
817
0
             "incorrect RSA size %"SC_FORMAT_LEN_SIZE_T"X",
818
0
             file->size);
819
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS);
820
0
    }
821
0
  } else if (file->type == SC_FILE_TYPE_INTERNAL_EF &&
822
0
      file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) {
823
0
    if (file->size == 8 || file->size == 64)
824
0
      size = 64;
825
0
    else if (file->size == 16 || file->size == 128)
826
0
      size = 128;
827
0
    else if (file->size == 24 || file->size == 192)
828
0
      size = 192;
829
0
    else {
830
0
      sc_log(card->ctx,
831
0
             "incorrect DES size %"SC_FORMAT_LEN_SIZE_T"u",
832
0
             file->size);
833
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS);
834
0
    }
835
0
  }
836
837
0
  p[12] = (size >> 8) & 0xFF;
838
0
  p[13] = size & 0xFF;
839
840
0
  p[14] = 0x86;
841
0
  p[15] = 0x08;
842
843
0
  if (file->type == SC_FILE_TYPE_DF) {
844
0
    ops[0] = SC_AC_OP_CREATE;
845
0
    ops[1] = SC_AC_OP_CRYPTO;
846
0
    ops[2] = SC_AC_OP_LIST_FILES;
847
0
    ops[3] = SC_AC_OP_DELETE;
848
0
    ops[4] = SC_AC_OP_PIN_DEFINE;
849
0
    ops[5] = SC_AC_OP_PIN_CHANGE;
850
0
    ops[6] = SC_AC_OP_PIN_RESET;
851
0
  } else if (file->type == SC_FILE_TYPE_WORKING_EF) {
852
0
    if (file->ef_structure == SC_FILE_EF_TRANSPARENT) {
853
0
      sc_log(card->ctx, "SC_FILE_EF_TRANSPARENT");
854
0
      ops[0] = SC_AC_OP_WRITE;
855
0
      ops[1] = SC_AC_OP_UPDATE;
856
0
      ops[2] = SC_AC_OP_READ;
857
0
      ops[3] = SC_AC_OP_ERASE;
858
0
    } else if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) {
859
0
      sc_log(card->ctx, "SC_FILE_EF_LINEAR_VARIABLE");
860
0
      ops[0] = SC_AC_OP_WRITE;
861
0
      ops[1] = SC_AC_OP_UPDATE;
862
0
      ops[2] = SC_AC_OP_READ;
863
0
      ops[3] = SC_AC_OP_ERASE;
864
0
    }
865
0
  } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) {
866
0
    if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) {
867
0
      sc_log(card->ctx, "EF_DES");
868
0
      ops[0] = SC_AC_OP_UPDATE;
869
0
      ops[1] = SC_AC_OP_PSO_DECRYPT;
870
0
      ops[2] = SC_AC_OP_PSO_ENCRYPT;
871
0
      ops[3] = SC_AC_OP_PSO_COMPUTE_CHECKSUM;
872
0
      ops[4] = SC_AC_OP_PSO_VERIFY_CHECKSUM;
873
0
      ops[5] = SC_AC_OP_INTERNAL_AUTHENTICATE;
874
0
      ops[6] = SC_AC_OP_EXTERNAL_AUTHENTICATE;
875
0
    } else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) {
876
0
      sc_log(card->ctx, "EF_RSA_PUBLIC");
877
0
      ops[0] = SC_AC_OP_UPDATE;
878
0
      ops[2] = SC_AC_OP_PSO_ENCRYPT;
879
0
      ops[4] = SC_AC_OP_PSO_VERIFY_SIGNATURE;
880
0
      ops[6] = SC_AC_OP_EXTERNAL_AUTHENTICATE;
881
0
    } else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) {
882
0
      sc_log(card->ctx, "EF_RSA_PRIVATE");
883
0
      ops[0] = SC_AC_OP_UPDATE;
884
0
      ops[1] = SC_AC_OP_PSO_DECRYPT;
885
0
      ops[3] = SC_AC_OP_PSO_COMPUTE_SIGNATURE;
886
0
      ops[5] = SC_AC_OP_INTERNAL_AUTHENTICATE;
887
0
    }
888
0
  }
889
890
0
  for (ii = 0; ii < sizeof(ops); ii++) {
891
0
    const struct sc_acl_entry *entry;
892
893
0
    p[16+ii] = 0xFF;
894
0
    if (ops[ii]==0xFF)
895
0
      continue;
896
0
    entry = sc_file_get_acl_entry(file, ops[ii]);
897
0
    rv = acl_to_ac_byte(card,entry);
898
0
    LOG_TEST_RET(card->ctx, rv, "Invalid ACL");
899
0
    p[16+ii] = rv;
900
0
  }
901
902
0
  *buflen = 0x18;
903
904
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
905
0
}
906
907
908
static int
909
auth_create_file(struct sc_card *card, struct sc_file *file)
910
0
{
911
0
  struct sc_apdu apdu;
912
0
  struct sc_path path;
913
0
  int rv, rec_nr;
914
0
  unsigned char sbuf[0x18];
915
0
  size_t sendlen = sizeof(sbuf);
916
0
  char pbuf[SC_MAX_PATH_STRING_SIZE];
917
918
0
  LOG_FUNC_CALLED(card->ctx);
919
920
0
  rv = sc_path_print(pbuf, sizeof(pbuf), &file->path);
921
0
  if (rv != SC_SUCCESS)
922
0
    pbuf[0] = '\0';
923
0
  sc_log(card->ctx, " create path=%s", pbuf);
924
925
0
  sc_log(card->ctx,
926
0
         "id %04X; size %"SC_FORMAT_LEN_SIZE_T"u; type 0x%X; ef 0x%X",
927
0
         file->id, file->size, file->type, file->ef_structure);
928
929
0
  if (file->id==0x0000 || file->id==0xFFFF || file->id==0x3FFF)
930
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
931
932
0
  if (file->path.len) {
933
0
    memcpy(&path, &file->path, sizeof(path));
934
0
    if (path.len>2)
935
0
      path.len -= 2;
936
937
0
    if (auth_select_file(card, &path, NULL)) {
938
0
      sc_log(card->ctx, "Cannot select parent DF.");
939
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
940
0
    }
941
0
  }
942
943
0
  rv = encode_file_structure_V5(card, file, sbuf, &sendlen);
944
0
  LOG_TEST_RET(card->ctx, rv, "File structure encoding failed");
945
946
0
  if (file->type != SC_FILE_TYPE_DF && file->ef_structure != SC_FILE_EF_TRANSPARENT)
947
0
    rec_nr = (int)file->record_count;
948
0
  else
949
0
    rec_nr = 0;
950
951
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, rec_nr);
952
0
  apdu.data = sbuf;
953
0
  apdu.datalen = sendlen;
954
0
  apdu.lc = sendlen;
955
956
0
  rv = sc_transmit_apdu(card, &apdu);
957
0
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
958
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
959
0
  LOG_TEST_RET(card->ctx, rv, "Card returned error");
960
961
  /* select created DF. */
962
0
  if (file->type == SC_FILE_TYPE_DF) {
963
0
    struct sc_path tmp_path;
964
0
    struct sc_file *df_file = NULL;
965
966
0
    memset(&tmp_path, 0, sizeof(struct sc_path));
967
0
    tmp_path.type = SC_PATH_TYPE_FILE_ID;
968
0
    tmp_path.value[0] = file->id >> 8;
969
0
    tmp_path.value[1] = file->id & 0xFF;
970
0
    tmp_path.len = 2;
971
0
    rv = auth_select_file(card, &tmp_path, &df_file);
972
0
    sc_log(card->ctx, "rv %i", rv);
973
0
    sc_file_free(df_file);
974
0
  }
975
976
0
  sc_file_free(auth_current_ef);
977
0
  auth_current_ef = NULL;
978
0
  sc_file_dup(&auth_current_ef, file);
979
980
0
  LOG_FUNC_RETURN(card->ctx, rv);
981
0
}
982
983
984
static int
985
auth_set_security_env(struct sc_card *card,
986
    const struct sc_security_env *env, int se_num)
987
0
{
988
0
  struct auth_senv *auth_senv = &((struct auth_private_data *) card->drv_data)->senv;
989
0
  struct sc_apdu apdu;
990
0
  long unsigned pads = env->algorithm_flags & SC_ALGORITHM_RSA_PADS;
991
0
  long unsigned supported_pads = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_PAD_ISO9796;
992
0
  int rv;
993
0
  unsigned char rsa_sbuf[3] = {
994
0
    0x80, 0x01, 0xFF
995
0
  };
996
0
  unsigned char des_sbuf[13] = {
997
0
    0x80, 0x01, 0x01,
998
0
    0x87, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
999
0
  };
1000
1001
0
  LOG_FUNC_CALLED(card->ctx);
1002
0
  sc_log(card->ctx,
1003
0
         "op %i; path %s; key_ref 0x%X; algos 0x%lX; flags 0x%lX",
1004
0
         env->operation, sc_print_path(&env->file_ref), env->key_ref[0],
1005
0
         env->algorithm_flags, env->flags);
1006
1007
0
  memset(auth_senv, 0, sizeof(struct auth_senv));
1008
1009
0
  if (!(env->flags & SC_SEC_ENV_FILE_REF_PRESENT))
1010
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "Key file is not selected.");
1011
1012
0
  switch (env->algorithm) {
1013
0
  case SC_ALGORITHM_DES:
1014
0
  case SC_ALGORITHM_3DES:
1015
0
    sc_log(card->ctx,
1016
0
           "algo SC_ALGORITHM_xDES: ref %lX, flags %lX",
1017
0
           env->algorithm_ref, env->flags);
1018
1019
0
    if (env->operation == SC_SEC_OPERATION_DECIPHER) {
1020
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB8);
1021
0
      apdu.lc = 3;
1022
0
      apdu.data = des_sbuf;
1023
0
      apdu.datalen = 3;
1024
0
    } else {
1025
0
      sc_log(card->ctx, "Invalid crypto operation: %X", env->operation);
1026
0
      LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Invalid crypto operation");
1027
0
    }
1028
1029
0
    break;
1030
0
  case SC_ALGORITHM_RSA:
1031
0
    sc_log(card->ctx, "algo SC_ALGORITHM_RSA");
1032
0
    if (env->algorithm_flags & SC_ALGORITHM_RSA_HASHES) {
1033
0
      LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "No support for hashes.");
1034
0
    }
1035
1036
0
    if (pads & (~supported_pads)) {
1037
0
      sc_log(card->ctx, "No support for PAD %lX", pads);
1038
0
      LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "No padding support.");
1039
0
    }
1040
1041
0
    if (env->operation == SC_SEC_OPERATION_SIGN) {
1042
0
      rsa_sbuf[2] = 0x11;
1043
1044
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB6);
1045
0
      apdu.lc = sizeof(rsa_sbuf);
1046
0
      apdu.datalen = sizeof(rsa_sbuf);
1047
0
      apdu.data = rsa_sbuf;
1048
0
    } else if (env->operation == SC_SEC_OPERATION_DECIPHER) {
1049
0
      rsa_sbuf[2] = 0x11;
1050
1051
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB8);
1052
0
      apdu.lc = sizeof(rsa_sbuf);
1053
0
      apdu.datalen = sizeof(rsa_sbuf);
1054
0
      apdu.data = rsa_sbuf;
1055
0
    } else {
1056
0
      sc_log(card->ctx, "Invalid crypto operation: %X", env->operation);
1057
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1058
0
    }
1059
1060
0
    break;
1061
0
  default:
1062
0
    LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Invalid crypto algorithm supplied");
1063
0
  }
1064
1065
0
  rv = sc_transmit_apdu(card, &apdu);
1066
0
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
1067
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1068
0
  LOG_TEST_RET(card->ctx, rv, "Card returned error");
1069
1070
0
  auth_senv->algorithm = env->algorithm;
1071
1072
0
  LOG_FUNC_RETURN(card->ctx, rv);
1073
0
}
1074
1075
1076
static int
1077
auth_restore_security_env(struct sc_card *card, int se_num)
1078
0
{
1079
0
  return SC_SUCCESS;
1080
0
}
1081
1082
1083
static int
1084
auth_compute_signature(struct sc_card *card, const unsigned char *in, size_t ilen,
1085
    unsigned char * out, size_t olen)
1086
0
{
1087
0
  struct sc_apdu apdu;
1088
0
  unsigned char resp[SC_MAX_APDU_BUFFER_SIZE];
1089
0
  int rv;
1090
1091
0
  if (!card || !in || !out) {
1092
0
    return SC_ERROR_INVALID_ARGUMENTS;
1093
0
  } else if (ilen > 96) {
1094
0
    sc_log(card->ctx,
1095
0
           "Illegal input length %"SC_FORMAT_LEN_SIZE_T"u",
1096
0
           ilen);
1097
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Illegal input length");
1098
0
  }
1099
1100
0
  LOG_FUNC_CALLED(card->ctx);
1101
0
  sc_log(card->ctx,
1102
0
         "inlen %"SC_FORMAT_LEN_SIZE_T"u, outlen %"SC_FORMAT_LEN_SIZE_T"u",
1103
0
         ilen, olen);
1104
1105
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A);
1106
0
  apdu.datalen = ilen;
1107
0
  apdu.data = in;
1108
0
  apdu.lc = ilen;
1109
0
  apdu.le = MIN(olen, SC_MAX_APDU_RESP_SIZE);
1110
0
  apdu.resp = resp;
1111
0
  apdu.resplen = SC_MAX_APDU_BUFFER_SIZE;
1112
1113
0
  rv = sc_transmit_apdu(card, &apdu);
1114
0
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
1115
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1116
0
  LOG_TEST_RET(card->ctx, rv, "Compute signature failed");
1117
1118
0
  if (apdu.resplen > olen) {
1119
0
    sc_log(card->ctx,
1120
0
           "Compute signature failed: invalid response length %"SC_FORMAT_LEN_SIZE_T"u",
1121
0
           apdu.resplen);
1122
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED);
1123
0
  }
1124
1125
0
  memcpy(out, apdu.resp, apdu.resplen);
1126
1127
0
  LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen);
1128
0
}
1129
1130
1131
static int
1132
auth_decipher(struct sc_card *card, const unsigned char *in, size_t inlen,
1133
        unsigned char *out, size_t outlen)
1134
0
{
1135
0
  struct sc_apdu apdu;
1136
0
  unsigned char resp[SC_MAX_APDU_BUFFER_SIZE];
1137
0
  int rv;
1138
0
  size_t _inlen = inlen;
1139
1140
0
  LOG_FUNC_CALLED(card->ctx);
1141
0
  sc_log(card->ctx,
1142
0
         "crgram_len %"SC_FORMAT_LEN_SIZE_T"u;  outlen %"SC_FORMAT_LEN_SIZE_T"u",
1143
0
         inlen, outlen);
1144
0
  if (!out || !outlen || inlen > SC_MAX_APDU_BUFFER_SIZE)
1145
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1146
1147
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x86);
1148
1149
0
  sc_log(card->ctx, "algorithm SC_ALGORITHM_RSA");
1150
0
  if (inlen % 64) {
1151
0
    rv = SC_ERROR_INVALID_ARGUMENTS;
1152
0
    goto done;
1153
0
  }
1154
1155
0
  _inlen = inlen;
1156
0
  if (_inlen == SC_MAX_APDU_RESP_SIZE) {
1157
0
    apdu.cla |= 0x10;
1158
0
    apdu.data = in;
1159
0
    apdu.datalen = 8;
1160
0
    apdu.resp = resp;
1161
0
    apdu.resplen = SC_MAX_APDU_BUFFER_SIZE;
1162
0
    apdu.lc = 8;
1163
0
    apdu.le = SC_MAX_APDU_RESP_SIZE;
1164
1165
0
    rv = sc_transmit_apdu(card, &apdu);
1166
0
    sc_log(card->ctx, "rv %i", rv);
1167
0
    LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
1168
0
    rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1169
0
    LOG_TEST_RET(card->ctx, rv, "Card returned error");
1170
1171
0
    _inlen -= 8;
1172
0
    in += 8;
1173
1174
0
    apdu.cla &= ~0x10;
1175
0
  }
1176
1177
0
  apdu.data = in;
1178
0
  apdu.datalen = _inlen;
1179
0
  apdu.resp = resp;
1180
0
  apdu.resplen = SC_MAX_APDU_BUFFER_SIZE;
1181
0
  apdu.lc = _inlen;
1182
0
  apdu.le = _inlen;
1183
1184
0
  rv = sc_transmit_apdu(card, &apdu);
1185
0
  sc_log(card->ctx, "rv %i", rv);
1186
0
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
1187
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1188
0
  sc_log(card->ctx, "rv %i", rv);
1189
0
  LOG_TEST_RET(card->ctx, rv, "Card returned error");
1190
1191
0
  if (outlen > apdu.resplen)
1192
0
    outlen = apdu.resplen;
1193
1194
0
  memcpy(out, apdu.resp, outlen);
1195
0
  rv = (int)outlen;
1196
1197
0
done:
1198
0
  LOG_FUNC_RETURN(card->ctx, rv);
1199
0
}
1200
1201
1202
/* Return the default AAK for this type of card */
1203
static int
1204
auth_get_default_key(struct sc_card *card, struct sc_cardctl_default_key *data)
1205
0
{
1206
0
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_NO_DEFAULT_KEY);
1207
0
}
1208
1209
1210
static int
1211
auth_encode_exponent(unsigned long exponent, unsigned char *buff, size_t buff_len)
1212
0
{
1213
0
  int    shift;
1214
0
  size_t ii;
1215
1216
0
  for (shift=0; exponent >> (shift+8); shift += 8)
1217
0
    ;
1218
1219
0
  for (ii = 0; ii<buff_len && shift>=0 ; ii++, shift-=8)
1220
0
    *(buff + ii) = (exponent >> shift) & 0xFF;
1221
1222
0
  if (ii==buff_len)
1223
0
    return 0;
1224
0
  else
1225
0
    return (int)ii;
1226
0
}
1227
1228
1229
/* Generate key on-card */
1230
static int
1231
auth_generate_key(struct sc_card *card, int use_sm,
1232
    struct sc_cardctl_oberthur_genkey_info *data)
1233
0
{
1234
0
  struct sc_apdu apdu;
1235
0
  unsigned char sbuf[SC_MAX_APDU_BUFFER_SIZE];
1236
0
  struct sc_path tmp_path;
1237
0
  int rv = 0;
1238
1239
0
  LOG_FUNC_CALLED(card->ctx);
1240
0
  if (data->key_bits < 512 || data->key_bits > 2048 ||
1241
0
      (data->key_bits % 0x20) != 0) {
1242
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Illegal key length");
1243
0
  }
1244
1245
0
  sbuf[0] = (data->id_pub >> 8) & 0xFF;
1246
0
  sbuf[1] = data->id_pub & 0xFF;
1247
0
  sbuf[2] = (data->id_prv >> 8) & 0xFF;
1248
0
  sbuf[3] = data->id_prv & 0xFF;
1249
0
  if (data->exponent != 0x10001) {
1250
0
    rv = auth_encode_exponent(data->exponent, &sbuf[5],SC_MAX_APDU_BUFFER_SIZE-6);
1251
0
    LOG_TEST_RET(card->ctx, rv, "Cannot encode exponent");
1252
1253
0
    sbuf[4] = rv;
1254
0
    rv++;
1255
0
  }
1256
1257
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x46, 0x00, 0x00);
1258
0
  apdu.resp = calloc(1, data->key_bits/8+8);
1259
0
  if (!apdu.resp)
1260
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1261
1262
0
  apdu.resplen = data->key_bits/8+8;
1263
0
  apdu.lc = rv + 4;
1264
0
  apdu.le = data->key_bits/8;
1265
0
  apdu.data = sbuf;
1266
0
  apdu.datalen = rv + 4;
1267
1268
0
  rv = sc_transmit_apdu(card, &apdu);
1269
0
  LOG_TEST_GOTO_ERR(card->ctx, rv, "APDU transmit failed");
1270
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1271
0
  LOG_TEST_GOTO_ERR(card->ctx, rv, "Card returned error");
1272
1273
0
  memset(&tmp_path, 0, sizeof(struct sc_path));
1274
0
  tmp_path.type = SC_PATH_TYPE_FILE_ID;
1275
0
  tmp_path.len = 2;
1276
0
  memcpy(tmp_path.value, sbuf, 2);
1277
1278
0
  rv = auth_select_file(card, &tmp_path, NULL);
1279
0
  LOG_TEST_GOTO_ERR(card->ctx, rv, "cannot select public key");
1280
1281
0
  rv = auth_read_component(card, SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC,
1282
0
      1, apdu.resp, data->key_bits/8);
1283
0
  LOG_TEST_GOTO_ERR(card->ctx, rv, "auth_read_component() returned error");
1284
1285
0
  apdu.resplen = rv;
1286
1287
0
  if (data->pubkey) {
1288
0
    if (data->pubkey_len < apdu.resplen) {
1289
0
      rv = SC_ERROR_INVALID_ARGUMENTS;
1290
0
      LOG_TEST_GOTO_ERR(card->ctx, rv, "invalid length received");
1291
0
    }
1292
1293
0
    memcpy(data->pubkey,apdu.resp,apdu.resplen);
1294
0
  }
1295
1296
0
  data->pubkey_len = apdu.resplen;
1297
0
  free(apdu.resp);
1298
1299
0
  sc_log(card->ctx, "resulted public key len %"SC_FORMAT_LEN_SIZE_T"u",
1300
0
         apdu.resplen);
1301
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1302
0
err:
1303
0
  free(apdu.resp);
1304
0
  return rv;
1305
0
}
1306
1307
1308
static int
1309
auth_update_component(struct sc_card *card, struct auth_update_component_info *args)
1310
0
{
1311
0
  struct sc_apdu apdu;
1312
0
  unsigned char sbuf[SC_MAX_APDU_BUFFER_SIZE + 0x10];
1313
0
  unsigned char ins, p1, p2;
1314
0
  int rv, len;
1315
1316
0
  LOG_FUNC_CALLED(card->ctx);
1317
0
  if (args->len > sizeof(sbuf) || args->len > 0x100)
1318
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1319
1320
0
  sc_log(card->ctx, "nn %i; len %zu", args->component, args->len);
1321
0
  ins = 0xD8;
1322
0
  p1 = args->component;
1323
0
  p2 = 0x04;
1324
0
  len = 0;
1325
1326
0
  sbuf[len++] = args->type;
1327
0
  sbuf[len++] = args->len;
1328
0
  memcpy(sbuf + len, args->data, args->len);
1329
0
  len += args->len;
1330
1331
0
  if (args->type == SC_CARDCTL_OBERTHUR_KEY_DES) {
1332
0
    int outl;
1333
0
    const unsigned char in[8] = {0,0,0,0,0,0,0,0};
1334
0
    unsigned char out[8];
1335
0
    EVP_CIPHER_CTX  * ctx = NULL;
1336
0
    EVP_CIPHER *alg = NULL;
1337
1338
0
    if (args->len!=8 && args->len!=24)
1339
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1340
1341
0
    ctx = EVP_CIPHER_CTX_new();
1342
0
    if (ctx == NULL)
1343
0
        LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1344
1345
0
    p2 = 0;
1346
0
    if (args->len == 24)
1347
0
      alg = sc_evp_cipher(card->ctx, "DES-EDE");
1348
0
    else
1349
0
      alg = sc_evp_cipher(card->ctx, "DES-ECB");
1350
0
    rv = EVP_EncryptInit_ex(ctx, alg, NULL, args->data, NULL);
1351
0
    if (rv == 0) {
1352
0
      sc_evp_cipher_free(alg);
1353
0
      sc_log_openssl(card->ctx);
1354
0
      sc_log(card->ctx, "OpenSSL encryption error.");
1355
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
1356
0
    }
1357
0
    rv = EVP_EncryptUpdate(ctx, out, &outl, in, 8);
1358
0
    EVP_CIPHER_CTX_free(ctx);
1359
0
    sc_evp_cipher_free(alg);
1360
0
    if (rv == 0) {
1361
0
      sc_log_openssl(card->ctx);
1362
0
      sc_log(card->ctx, "OpenSSL encryption error.");
1363
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
1364
0
    }
1365
1366
0
    sbuf[len++] = 0x03;
1367
0
    memcpy(sbuf + len, out, 3);
1368
0
    len += 3;
1369
0
  } else {
1370
0
    sbuf[len++] = 0;
1371
0
  }
1372
1373
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, ins,  p1, p2);
1374
0
  apdu.cla |= 0x80;
1375
0
  apdu.data = sbuf;
1376
0
  apdu.datalen = len;
1377
0
  apdu.lc = len;
1378
0
  if (args->len == 0x100) {
1379
0
    sbuf[0] = args->type;
1380
0
    sbuf[1] = 0x20;
1381
0
    memcpy(sbuf + 2, args->data, 0x20);
1382
0
    sbuf[0x22] = 0;
1383
0
    apdu.cla |= 0x10;
1384
0
    apdu.data = sbuf;
1385
0
    apdu.datalen = 0x23;
1386
0
    apdu.lc = 0x23;
1387
0
    rv = sc_transmit_apdu(card, &apdu);
1388
0
    apdu.cla &= ~0x10;
1389
0
    LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
1390
1391
0
    sbuf[0] = args->type;
1392
0
    sbuf[1] = 0xE0;
1393
0
    memcpy(sbuf + 2, args->data + 0x20, 0xE0);
1394
0
    sbuf[0xE2] = 0;
1395
0
    apdu.data = sbuf;
1396
0
    apdu.datalen = 0xE3;
1397
0
    apdu.lc = 0xE3;
1398
0
  }
1399
1400
0
  rv = sc_transmit_apdu(card, &apdu);
1401
0
  sc_mem_clear(sbuf, sizeof(sbuf));
1402
0
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
1403
1404
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1405
0
  LOG_FUNC_RETURN(card->ctx, rv);
1406
0
}
1407
1408
1409
static int
1410
auth_update_key(struct sc_card *card, struct sc_cardctl_oberthur_updatekey_info *info)
1411
0
{
1412
0
  int rv, ii;
1413
1414
0
  LOG_FUNC_CALLED(card->ctx);
1415
1416
0
  if (info->data_len != sizeof(void *) || !info->data)
1417
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1418
1419
0
  if (info->type == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) {
1420
0
    struct sc_pkcs15_prkey_rsa  *rsa = (struct sc_pkcs15_prkey_rsa *)info->data;
1421
0
    struct sc_pkcs15_bignum bn[5];
1422
1423
0
    sc_log(card->ctx, "Import RSA CRT");
1424
0
    bn[0] = rsa->p;
1425
0
    bn[1] = rsa->q;
1426
0
    bn[2] = rsa->iqmp;
1427
0
    bn[3] = rsa->dmp1;
1428
0
    bn[4] = rsa->dmq1;
1429
0
    for (ii = 0; ii < 5; ii++) {
1430
0
      struct auth_update_component_info args;
1431
1432
0
      memset(&args, 0, sizeof(args));
1433
0
      args.type = SC_CARDCTL_OBERTHUR_KEY_RSA_CRT;
1434
0
      args.component = ii+1;
1435
0
      args.data = bn[ii].data;
1436
0
      args.len = bn[ii].len;
1437
1438
0
      rv = auth_update_component(card, &args);
1439
0
      LOG_TEST_RET(card->ctx, rv, "Update RSA component failed");
1440
0
    }
1441
0
  } else if (info->type == SC_CARDCTL_OBERTHUR_KEY_DES) {
1442
0
    rv = SC_ERROR_NOT_SUPPORTED;
1443
0
  } else {
1444
0
    rv = SC_ERROR_INVALID_DATA;
1445
0
  }
1446
1447
0
  LOG_FUNC_RETURN(card->ctx, rv);
1448
0
}
1449
1450
1451
static int
1452
auth_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
1453
0
{
1454
0
  switch (cmd) {
1455
0
  case SC_CARDCTL_GET_DEFAULT_KEY:
1456
0
    return auth_get_default_key(card,
1457
0
        (struct sc_cardctl_default_key *) ptr);
1458
0
  case SC_CARDCTL_OBERTHUR_GENERATE_KEY:
1459
0
    return auth_generate_key(card, 0,
1460
0
        (struct sc_cardctl_oberthur_genkey_info *) ptr);
1461
0
  case SC_CARDCTL_OBERTHUR_UPDATE_KEY:
1462
0
    return auth_update_key(card,
1463
0
        (struct sc_cardctl_oberthur_updatekey_info *) ptr);
1464
0
  case SC_CARDCTL_OBERTHUR_CREATE_PIN:
1465
0
    return auth_create_reference_data(card,
1466
0
        (struct sc_cardctl_oberthur_createpin_info *) ptr);
1467
0
  case SC_CARDCTL_GET_SERIALNR:
1468
0
    return auth_get_serialnr(card, (struct sc_serial_number *)ptr);
1469
0
  case SC_CARDCTL_LIFECYCLE_GET:
1470
0
  case SC_CARDCTL_LIFECYCLE_SET:
1471
0
    return SC_ERROR_NOT_SUPPORTED;
1472
0
  default:
1473
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1474
0
  }
1475
0
}
1476
1477
1478
static int
1479
auth_read_component(struct sc_card *card, enum SC_CARDCTL_OBERTHUR_KEY_TYPE type,
1480
    int num, unsigned char *out, size_t outlen)
1481
0
{
1482
0
  struct sc_apdu apdu;
1483
0
  int rv;
1484
0
  unsigned char resp[SC_MAX_APDU_RESP_SIZE];
1485
1486
0
  LOG_FUNC_CALLED(card->ctx);
1487
0
  sc_log(card->ctx, "num %i, outlen %"SC_FORMAT_LEN_SIZE_T"u, type %i",
1488
0
         num, outlen, type);
1489
1490
0
  if (!outlen || type!=SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC)
1491
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS);
1492
1493
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB4, num, 0x00);
1494
0
  apdu.cla |= 0x80;
1495
0
  apdu.le = outlen;
1496
0
  apdu.resp = resp;
1497
0
  apdu.resplen = sizeof(resp);
1498
0
  rv = sc_transmit_apdu(card, &apdu);
1499
0
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
1500
1501
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1502
0
  LOG_TEST_RET(card->ctx, rv, "Card returned error");
1503
1504
0
  if (outlen < apdu.resplen)
1505
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH);
1506
1507
0
  memcpy(out, apdu.resp, apdu.resplen);
1508
0
  LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen);
1509
0
}
1510
1511
1512
static int
1513
auth_get_pin_reference (struct sc_card *card, int type, int reference, int cmd, int *out_ref)
1514
0
{
1515
0
  if (!out_ref)
1516
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1517
1518
0
  switch (type) {
1519
0
  case SC_AC_CHV:
1520
0
    if (reference != 1 && reference != 2 && reference != 4)
1521
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_PIN_REFERENCE);
1522
1523
0
    *out_ref = reference;
1524
0
    if (reference == 1 || reference == 4)
1525
0
      if (cmd == SC_PIN_CMD_VERIFY)
1526
0
        *out_ref |= 0x80;
1527
0
    break;
1528
1529
0
  default:
1530
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1531
0
  }
1532
1533
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1534
0
}
1535
1536
1537
static void
1538
auth_init_pin_info(struct sc_card *card, struct sc_pin_cmd_pin *pin,
1539
    unsigned int type)
1540
0
{
1541
0
  pin->offset = 0;
1542
0
  pin->pad_char   = 0xFF;
1543
0
  pin->encoding   = SC_PIN_ENCODING_ASCII;
1544
1545
0
  if (type == OBERTHUR_AUTH_TYPE_PIN) {
1546
0
    pin->max_length = OBERTHUR_AUTH_MAX_LENGTH_PIN;
1547
0
    pin->pad_length = OBERTHUR_AUTH_MAX_LENGTH_PIN;
1548
0
  } else {
1549
0
    pin->max_length = OBERTHUR_AUTH_MAX_LENGTH_PUK;
1550
0
    pin->pad_length = OBERTHUR_AUTH_MAX_LENGTH_PUK;
1551
0
  }
1552
0
}
1553
1554
1555
static int
1556
auth_pin_verify_pinpad(struct sc_card *card, int pin_reference, int *tries_left)
1557
0
{
1558
0
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
1559
0
  struct sc_pin_cmd_data pin_cmd;
1560
0
  struct sc_apdu apdu;
1561
0
  unsigned char ffs1[0x100];
1562
0
  int rv;
1563
1564
0
  LOG_FUNC_CALLED(card->ctx);
1565
1566
0
  memset(ffs1, 0xFF, sizeof(ffs1));
1567
0
  memset(&pin_cmd, 0, sizeof(pin_cmd));
1568
1569
0
  rv = auth_pin_is_verified(card, pin_reference, tries_left);
1570
0
  sc_log(card->ctx, "auth_pin_is_verified returned rv %i", rv);
1571
1572
  /* Return SUCCESS without verifying if
1573
   * PIN has been already verified and PIN pad has to be used. */
1574
0
  if (!rv)
1575
0
    LOG_FUNC_RETURN(card->ctx, rv);
1576
1577
0
  pin_cmd.flags |= SC_PIN_CMD_NEED_PADDING;
1578
1579
  /* For Oberthur card, PIN command data length has to be 0x40.
1580
   * In PCSC10 v2.06 the upper limit of pin.max_length is 8.
1581
   *
1582
   * The standard sc_build_pin() throws an error when 'pin.len > pin.max_length' .
1583
   * So, let's build our own APDU.
1584
   */
1585
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, pin_reference);
1586
0
  apdu.lc = OBERTHUR_AUTH_MAX_LENGTH_PIN;
1587
0
  apdu.datalen = OBERTHUR_AUTH_MAX_LENGTH_PIN;
1588
0
  apdu.data = ffs1;
1589
1590
0
  pin_cmd.apdu = &apdu;
1591
0
  pin_cmd.pin_type = SC_AC_CHV;
1592
0
  pin_cmd.cmd = SC_PIN_CMD_VERIFY;
1593
0
  pin_cmd.flags |= SC_PIN_CMD_USE_PINPAD;
1594
0
  pin_cmd.pin_reference = pin_reference;
1595
0
  if (pin_cmd.pin1.min_length < 4)
1596
0
    pin_cmd.pin1.min_length = 4;
1597
0
  pin_cmd.pin1.max_length = 8;
1598
0
  pin_cmd.pin1.encoding = SC_PIN_ENCODING_ASCII;
1599
0
  pin_cmd.pin1.offset = 5;
1600
0
  pin_cmd.pin1.data = ffs1;
1601
0
  pin_cmd.pin1.len = OBERTHUR_AUTH_MAX_LENGTH_PIN;
1602
0
  pin_cmd.pin1.pad_length = OBERTHUR_AUTH_MAX_LENGTH_PIN;
1603
1604
0
  rv = iso_drv->ops->pin_cmd(card, &pin_cmd);
1605
0
  LOG_TEST_RET(card->ctx, rv, "PIN CMD 'VERIFY' with pinpad failed");
1606
1607
0
  LOG_FUNC_RETURN(card->ctx, rv);
1608
0
}
1609
1610
1611
static int
1612
auth_pin_verify(struct sc_card *card, unsigned int type,
1613
    struct sc_pin_cmd_data *data)
1614
0
{
1615
0
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
1616
0
  int rv;
1617
1618
0
  LOG_FUNC_CALLED(card->ctx);
1619
1620
0
  if (type != SC_AC_CHV)
1621
0
    LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "PIN type other then SC_AC_CHV is not supported");
1622
1623
0
  data->flags |= SC_PIN_CMD_NEED_PADDING;
1624
1625
0
  auth_init_pin_info(card, &data->pin1, OBERTHUR_AUTH_TYPE_PIN);
1626
1627
  /* User PIN is always local. */
1628
0
  if (data->pin_reference == OBERTHUR_PIN_REFERENCE_USER
1629
0
      || data->pin_reference == OBERTHUR_PIN_REFERENCE_ONETIME)
1630
0
    data->pin_reference  |= OBERTHUR_PIN_LOCAL;
1631
1632
0
        rv = auth_pin_is_verified(card, data->pin_reference, &data->pin1.tries_left);
1633
0
      sc_log(card->ctx, "auth_pin_is_verified returned rv %i", rv);
1634
1635
  /* Return if only PIN status has been asked. */
1636
0
  if (data->pin1.data && !data->pin1.len)
1637
0
    LOG_FUNC_RETURN(card->ctx, rv);
1638
1639
  /* Return SUCCESS without verifying if
1640
   * PIN has been already verified and PIN pad has to be used. */
1641
0
  if (!rv && !data->pin1.data && !data->pin1.len)
1642
0
    LOG_FUNC_RETURN(card->ctx, rv);
1643
1644
0
  if (!data->pin1.data && !data->pin1.len)
1645
0
    rv = auth_pin_verify_pinpad(card, data->pin_reference, &data->pin1.tries_left);
1646
0
  else
1647
0
    rv = iso_drv->ops->pin_cmd(card, data);
1648
1649
0
  LOG_FUNC_RETURN(card->ctx, rv);
1650
0
}
1651
1652
1653
static int
1654
auth_pin_is_verified(struct sc_card *card, int pin_reference, int *tries_left)
1655
0
{
1656
0
  struct sc_apdu apdu;
1657
0
  int rv;
1658
1659
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0, pin_reference);
1660
1661
0
  rv = sc_transmit_apdu(card, &apdu);
1662
0
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
1663
1664
0
  if (tries_left && apdu.sw1 == 0x63 && (apdu.sw2 & 0xF0) == 0xC0)
1665
0
    *tries_left = apdu.sw2 & 0x0F;
1666
1667
  /* Replace 'no tries left' with 'auth method blocked' */
1668
0
  if (apdu.sw1 == 0x63 && apdu.sw2 == 0xC0) {
1669
0
    apdu.sw1 = 0x69;
1670
0
    apdu.sw2 = 0x83;
1671
0
  }
1672
1673
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1674
1675
0
  return rv;
1676
0
}
1677
1678
1679
static int
1680
auth_pin_change_pinpad(struct sc_card *card, struct sc_pin_cmd_data *data)
1681
0
{
1682
0
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
1683
0
  struct sc_pin_cmd_data pin_cmd;
1684
0
  struct sc_apdu apdu;
1685
0
  unsigned char ffs1[0x100];
1686
0
  unsigned char ffs2[0x100];
1687
0
  int rv, pin_reference;
1688
1689
0
  LOG_FUNC_CALLED(card->ctx);
1690
1691
0
  pin_reference = data->pin_reference & ~OBERTHUR_PIN_LOCAL;
1692
1693
0
  memset(ffs1, 0xFF, sizeof(ffs1));
1694
0
  memset(ffs2, 0xFF, sizeof(ffs2));
1695
0
  memset(&pin_cmd, 0, sizeof(pin_cmd));
1696
1697
0
  if (data->pin1.len > OBERTHUR_AUTH_MAX_LENGTH_PIN)
1698
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "'PIN CHANGE' failed");
1699
1700
0
  if (data->pin1.data && data->pin1.len)
1701
0
    memcpy(ffs1, data->pin1.data, data->pin1.len);
1702
1703
0
  pin_cmd.flags |= SC_PIN_CMD_NEED_PADDING;
1704
1705
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x00, pin_reference);
1706
0
  apdu.lc = OBERTHUR_AUTH_MAX_LENGTH_PIN * 2;
1707
0
  apdu.datalen = OBERTHUR_AUTH_MAX_LENGTH_PIN * 2;
1708
0
  apdu.data = ffs1;
1709
1710
0
  pin_cmd.apdu = &apdu;
1711
0
  pin_cmd.pin_type = SC_AC_CHV;
1712
0
  pin_cmd.cmd = SC_PIN_CMD_CHANGE;
1713
0
  pin_cmd.flags |= SC_PIN_CMD_USE_PINPAD;
1714
0
  pin_cmd.pin_reference = pin_reference;
1715
0
  if (pin_cmd.pin1.min_length < 4)
1716
0
    pin_cmd.pin1.min_length = 4;
1717
0
  pin_cmd.pin1.max_length = 8;
1718
0
  pin_cmd.pin1.encoding = SC_PIN_ENCODING_ASCII;
1719
0
  pin_cmd.pin1.offset = 5 + OBERTHUR_AUTH_MAX_LENGTH_PIN;
1720
0
  pin_cmd.pin1.data = ffs1;
1721
0
  pin_cmd.pin1.len = OBERTHUR_AUTH_MAX_LENGTH_PIN;
1722
0
  pin_cmd.pin1.pad_length = 0;
1723
1724
0
  memcpy(&pin_cmd.pin2, &pin_cmd.pin1, sizeof(pin_cmd.pin2));
1725
0
  pin_cmd.pin1.offset = 5;
1726
0
  pin_cmd.pin2.data = ffs2;
1727
1728
0
  rv = iso_drv->ops->pin_cmd(card, &pin_cmd);
1729
0
  LOG_TEST_RET(card->ctx, rv, "PIN CMD 'VERIFY' with pinpad failed");
1730
1731
0
  LOG_FUNC_RETURN(card->ctx, rv);
1732
0
}
1733
1734
1735
static int
1736
auth_pin_change(struct sc_card *card, unsigned int type,
1737
    struct sc_pin_cmd_data *data)
1738
0
{
1739
0
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
1740
0
  int rv = SC_ERROR_INTERNAL;
1741
1742
0
  LOG_FUNC_CALLED(card->ctx);
1743
1744
0
  if (data->pin1.len && data->pin2.len) {
1745
    /* Direct unblock style */
1746
0
    data->flags |= SC_PIN_CMD_NEED_PADDING;
1747
0
    data->flags &= ~SC_PIN_CMD_USE_PINPAD;
1748
0
    data->apdu = NULL;
1749
1750
0
    data->pin_reference &= ~OBERTHUR_PIN_LOCAL;
1751
1752
0
    auth_init_pin_info(card, &data->pin1, OBERTHUR_AUTH_TYPE_PIN);
1753
0
    auth_init_pin_info(card, &data->pin2, OBERTHUR_AUTH_TYPE_PIN);
1754
1755
0
    rv = iso_drv->ops->pin_cmd(card, data);
1756
0
    LOG_TEST_RET(card->ctx, rv, "CMD 'PIN CHANGE' failed");
1757
0
  } else if (!data->pin1.len && !data->pin2.len) {
1758
    /* Oberthur unblock style with PIN pad. */
1759
0
    rv = auth_pin_change_pinpad(card, data);
1760
0
    LOG_TEST_RET(card->ctx, rv, "'PIN CHANGE' failed: SOPIN verify with pinpad failed");
1761
0
  } else {
1762
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "'PIN CHANGE' failed");
1763
0
  }
1764
1765
0
  LOG_FUNC_RETURN(card->ctx, rv);
1766
0
}
1767
1768
1769
static int
1770
auth_pin_reset_oberthur_style(struct sc_card *card, unsigned int type,
1771
    struct sc_pin_cmd_data *data)
1772
0
{
1773
0
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
1774
0
  struct sc_pin_cmd_data pin_cmd;
1775
0
  struct sc_path tmp_path;
1776
0
  struct sc_file *tmp_file = NULL;
1777
0
  struct sc_apdu apdu;
1778
0
  unsigned char puk[OBERTHUR_AUTH_MAX_LENGTH_PUK];
1779
0
  unsigned char ffs1[0x100];
1780
0
  int rv, rvv, local_pin_reference;
1781
1782
0
  LOG_FUNC_CALLED(card->ctx);
1783
1784
0
  local_pin_reference = data->pin_reference & ~OBERTHUR_PIN_LOCAL;
1785
1786
0
  if (data->pin_reference !=  OBERTHUR_PIN_REFERENCE_USER)
1787
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Oberthur style 'PIN RESET' failed: invalid PIN reference");
1788
1789
0
  memset(&pin_cmd, 0, sizeof(pin_cmd));
1790
0
  memset(&tmp_path, 0, sizeof(struct sc_path));
1791
1792
0
  pin_cmd.pin_type = SC_AC_CHV;
1793
0
  pin_cmd.cmd = SC_PIN_CMD_VERIFY;
1794
0
  pin_cmd.pin_reference = OBERTHUR_PIN_REFERENCE_PUK;
1795
0
  memcpy(&pin_cmd.pin1, &data->pin1, sizeof(pin_cmd.pin1));
1796
1797
0
  rv = auth_pin_verify(card, SC_AC_CHV, &pin_cmd);
1798
0
  LOG_TEST_RET(card->ctx, rv, "Oberthur style 'PIN RESET' failed: SOPIN verify error");
1799
1800
0
  sc_format_path("2000", &tmp_path);
1801
0
  tmp_path.type = SC_PATH_TYPE_FILE_ID;
1802
0
  rv = iso_ops->select_file(card, &tmp_path, &tmp_file);
1803
0
  LOG_TEST_RET(card->ctx, rv, "select PUK file");
1804
1805
0
  if (!tmp_file || tmp_file->size < OBERTHUR_AUTH_MAX_LENGTH_PUK) {
1806
0
    sc_file_free(tmp_file);
1807
0
    LOG_TEST_RET(card->ctx, SC_ERROR_FILE_TOO_SMALL, "Oberthur style 'PIN RESET' failed");
1808
0
  }
1809
0
  sc_file_free(tmp_file);
1810
1811
0
  rv = iso_ops->read_binary(card, 0, puk, OBERTHUR_AUTH_MAX_LENGTH_PUK, 0);
1812
0
  LOG_TEST_RET(card->ctx, rv, "read PUK file error");
1813
0
  if (rv != OBERTHUR_AUTH_MAX_LENGTH_PUK)
1814
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_DATA, "Oberthur style 'PIN RESET' failed");
1815
1816
0
  memset(ffs1, 0xFF, sizeof(ffs1));
1817
0
  memcpy(ffs1, puk, rv);
1818
1819
0
  memset(&pin_cmd, 0, sizeof(pin_cmd));
1820
0
  pin_cmd.pin_type = SC_AC_CHV;
1821
0
        pin_cmd.cmd = SC_PIN_CMD_UNBLOCK;
1822
0
  pin_cmd.pin_reference = local_pin_reference;
1823
0
  auth_init_pin_info(card, &pin_cmd.pin1, OBERTHUR_AUTH_TYPE_PUK);
1824
0
  pin_cmd.pin1.data = ffs1;
1825
0
  pin_cmd.pin1.len = OBERTHUR_AUTH_MAX_LENGTH_PUK;
1826
1827
0
  if (data->pin2.data) {
1828
0
    memcpy(&pin_cmd.pin2, &data->pin2, sizeof(pin_cmd.pin2));
1829
0
    rv = auth_pin_reset(card, SC_AC_CHV, &pin_cmd);
1830
0
    LOG_FUNC_RETURN(card->ctx, rv);
1831
0
  }
1832
1833
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2C, 0x00, local_pin_reference);
1834
0
  apdu.lc = OBERTHUR_AUTH_MAX_LENGTH_PIN  + OBERTHUR_AUTH_MAX_LENGTH_PUK;
1835
0
  apdu.datalen = OBERTHUR_AUTH_MAX_LENGTH_PIN  + OBERTHUR_AUTH_MAX_LENGTH_PUK;
1836
0
  apdu.data = ffs1;
1837
1838
0
  pin_cmd.apdu = &apdu;
1839
0
  pin_cmd.flags |= SC_PIN_CMD_USE_PINPAD | SC_PIN_CMD_IMPLICIT_CHANGE;
1840
1841
0
  pin_cmd.pin1.min_length = 4;
1842
0
  pin_cmd.pin1.max_length = 8;
1843
0
  pin_cmd.pin1.encoding = SC_PIN_ENCODING_ASCII;
1844
0
  pin_cmd.pin1.offset = 5;
1845
1846
0
  pin_cmd.pin2.data = &ffs1[OBERTHUR_AUTH_MAX_LENGTH_PUK];
1847
0
  pin_cmd.pin2.len = OBERTHUR_AUTH_MAX_LENGTH_PIN;
1848
0
  pin_cmd.pin2.offset = 5 + OBERTHUR_AUTH_MAX_LENGTH_PUK;
1849
0
  pin_cmd.pin2.min_length = 4;
1850
0
  pin_cmd.pin2.max_length = 8;
1851
0
  pin_cmd.pin2.encoding = SC_PIN_ENCODING_ASCII;
1852
1853
0
  rvv = iso_drv->ops->pin_cmd(card, &pin_cmd);
1854
0
  if (rvv)
1855
0
    sc_log(card->ctx,
1856
0
        "%s: PIN CMD 'VERIFY' with pinpad failed",
1857
0
        sc_strerror(rvv));
1858
1859
0
  if (auth_current_ef) {
1860
0
    struct sc_file *ef = NULL;
1861
0
    rv = iso_ops->select_file(card, &auth_current_ef->path, &ef);
1862
0
    if (rv == SC_SUCCESS) {
1863
0
      sc_file_free(auth_current_ef);
1864
0
      auth_current_ef = ef;
1865
0
    } else
1866
0
      sc_file_free(ef);
1867
0
  }
1868
1869
0
  if (rv > 0)
1870
0
    rv = 0;
1871
1872
0
  LOG_FUNC_RETURN(card->ctx, rv ? rv: rvv);
1873
0
}
1874
1875
1876
static int
1877
auth_pin_reset(struct sc_card *card, unsigned int type,
1878
    struct sc_pin_cmd_data *data)
1879
0
{
1880
0
  int rv;
1881
1882
0
  LOG_FUNC_CALLED(card->ctx);
1883
1884
  /* Oberthur unblock style: PUK value is a SOPIN */
1885
0
  rv = auth_pin_reset_oberthur_style(card, SC_AC_CHV, data);
1886
0
  LOG_TEST_RET(card->ctx, rv, "Oberthur style 'PIN RESET' failed");
1887
1888
0
  LOG_FUNC_RETURN(card->ctx, rv);
1889
0
}
1890
1891
1892
static int
1893
auth_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data)
1894
0
{
1895
0
  int rv = SC_ERROR_INTERNAL;
1896
1897
0
  LOG_FUNC_CALLED(card->ctx);
1898
0
  if (data->pin_type != SC_AC_CHV)
1899
0
    LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "auth_pin_cmd() unsupported PIN type");
1900
1901
0
  sc_log(card->ctx, "PIN CMD:%i; reference:%i; pin1:%p/%zu, pin2:%p/%zu", data->cmd,
1902
0
      data->pin_reference, data->pin1.data, data->pin1.len,
1903
0
      data->pin2.data, data->pin2.len);
1904
0
  switch (data->cmd) {
1905
0
  case SC_PIN_CMD_VERIFY:
1906
0
    rv = auth_pin_verify(card, SC_AC_CHV, data);
1907
0
    LOG_TEST_RET(card->ctx, rv, "CMD 'PIN VERIFY' failed");
1908
0
    break;
1909
0
  case SC_PIN_CMD_CHANGE:
1910
0
    rv = auth_pin_change(card, SC_AC_CHV, data);
1911
0
    LOG_TEST_RET(card->ctx, rv, "CMD 'PIN VERIFY' failed");
1912
0
    break;
1913
0
  case SC_PIN_CMD_UNBLOCK:
1914
0
    rv = auth_pin_reset(card, SC_AC_CHV, data);
1915
0
    LOG_TEST_RET(card->ctx, rv, "CMD 'PIN VERIFY' failed");
1916
0
    break;
1917
0
  default:
1918
0
    LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported PIN operation");
1919
0
  }
1920
1921
0
  LOG_FUNC_RETURN(card->ctx, rv);
1922
0
}
1923
1924
1925
static int
1926
auth_create_reference_data (struct sc_card *card,
1927
    struct sc_cardctl_oberthur_createpin_info *args)
1928
0
{
1929
0
  struct sc_apdu apdu;
1930
0
  struct sc_pin_cmd_pin pin_info, puk_info;
1931
0
  int rv, len;
1932
0
  unsigned char sbuf[SC_MAX_APDU_BUFFER_SIZE];
1933
1934
0
  LOG_FUNC_CALLED(card->ctx);
1935
0
  sc_log(card->ctx, "PIN reference %i", args->ref);
1936
1937
0
  if (args->type != SC_AC_CHV)
1938
0
    LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported PIN type");
1939
1940
0
  if (args->pin_tries < 1 || !args->pin || !args->pin_len)
1941
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid PIN options");
1942
1943
0
  if (args->ref != OBERTHUR_PIN_REFERENCE_USER && args->ref != OBERTHUR_PIN_REFERENCE_PUK)
1944
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_PIN_REFERENCE, "Invalid PIN reference");
1945
1946
0
  auth_init_pin_info(card, &puk_info, OBERTHUR_AUTH_TYPE_PUK);
1947
0
  auth_init_pin_info(card, &pin_info, OBERTHUR_AUTH_TYPE_PIN);
1948
1949
0
  if (args->puk && args->puk_len && (args->puk_len%puk_info.pad_length))
1950
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid PUK options");
1951
1952
0
  len = 0;
1953
0
  sc_log(card->ctx, "len %i", len);
1954
0
  sbuf[len++] = args->pin_tries;
1955
0
  sbuf[len++] = pin_info.pad_length;
1956
0
  sc_log(card->ctx, "len %i", len);
1957
0
  memset(sbuf + len, pin_info.pad_char, pin_info.pad_length);
1958
0
  memcpy(sbuf + len, args->pin, args->pin_len);
1959
0
  len += pin_info.pad_length;
1960
0
  sc_log(card->ctx, "len %i", len);
1961
1962
0
  if (args->puk && args->puk_len) {
1963
0
    sbuf[len++] = args->puk_tries;
1964
0
    sbuf[len++] = args->puk_len / puk_info.pad_length;
1965
0
    sc_log(card->ctx, "len %i", len);
1966
0
    memcpy(sbuf + len, args->puk, args->puk_len);
1967
0
    len += args->puk_len;
1968
0
  }
1969
1970
0
  sc_log(card->ctx, "len %i", len);
1971
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 1, args->ref & ~OBERTHUR_PIN_LOCAL);
1972
0
  apdu.data = sbuf;
1973
0
  apdu.datalen = len;
1974
0
  apdu.lc = len;
1975
1976
0
  rv = sc_transmit_apdu(card, &apdu);
1977
0
  sc_mem_clear(sbuf, sizeof(sbuf));
1978
0
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
1979
1980
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1981
1982
0
  LOG_FUNC_RETURN(card->ctx, rv);
1983
0
}
1984
1985
1986
static int
1987
auth_logout(struct sc_card *card)
1988
0
{
1989
0
  struct sc_apdu apdu;
1990
0
  int ii, rv = 0, pin_ref;
1991
0
  int reset_flag = 0x20;
1992
1993
0
  for (ii = 0; ii < 4; ii++) {
1994
0
    rv = auth_get_pin_reference (card, SC_AC_CHV, ii+1, SC_PIN_CMD_UNBLOCK, &pin_ref);
1995
0
    LOG_TEST_RET(card->ctx, rv, "Cannot get PIN reference");
1996
1997
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2E, 0x00, 0x00);
1998
0
    apdu.cla = 0x80;
1999
0
    apdu.p2 = pin_ref | reset_flag;
2000
0
    rv = sc_transmit_apdu(card, &apdu);
2001
0
    LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
2002
0
  }
2003
2004
0
  LOG_FUNC_RETURN(card->ctx, rv);
2005
0
}
2006
2007
2008
static int
2009
write_publickey (struct sc_card *card, unsigned int offset,
2010
        const unsigned char *buf, size_t count)
2011
0
{
2012
0
  struct auth_update_component_info args;
2013
0
  struct sc_pkcs15_pubkey_rsa key;
2014
0
  int ii, rv;
2015
0
  size_t len = 0, der_size = 0;
2016
2017
0
  LOG_FUNC_CALLED(card->ctx);
2018
2019
0
  sc_log_hex(card->ctx, "write_publickey", buf, count);
2020
2021
0
  if (1+offset > sizeof(rsa_der))
2022
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid offset value");
2023
2024
0
  len = offset+count > sizeof(rsa_der) ? sizeof(rsa_der) - offset : count;
2025
2026
0
  memcpy(rsa_der + offset, buf, len);
2027
0
  rsa_der_len = offset + len;
2028
2029
0
  if (rsa_der[0] == 0x30) {
2030
0
    if (rsa_der[1] & 0x80)
2031
0
      for (ii=0; ii < (rsa_der[1]&0x0F); ii++)
2032
0
        der_size = der_size*0x100 + rsa_der[2+ii];
2033
0
    else
2034
0
      der_size = rsa_der[1];
2035
0
  }
2036
2037
0
  sc_log(card->ctx, "der_size %"SC_FORMAT_LEN_SIZE_T"u", der_size);
2038
0
  if (offset + len < der_size + 2)
2039
0
    LOG_FUNC_RETURN(card->ctx, (int)len);
2040
2041
0
  rv = sc_pkcs15_decode_pubkey_rsa(card->ctx, &key, rsa_der, rsa_der_len);
2042
0
  rsa_der_len = 0;
2043
0
  memset(rsa_der, 0, sizeof(rsa_der));
2044
0
  LOG_TEST_RET(card->ctx, rv, "cannot decode public key");
2045
0
  if (key.modulus.len == 0 || key.exponent.len == 0) {
2046
0
    if (key.modulus.len > 0) {
2047
0
      free(key.modulus.data);
2048
0
    }
2049
0
    if (key.exponent.len > 0) {
2050
0
      free(key.exponent.data);
2051
0
    }
2052
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key decoded from DER");
2053
0
  }
2054
2055
0
  memset(&args, 0, sizeof(args));
2056
0
  args.type = SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC;
2057
0
  args.component = 1;
2058
0
  args.data = key.modulus.data;
2059
0
  args.len = key.modulus.len;
2060
0
  rv = auth_update_component(card, &args);
2061
0
  free(args.data);
2062
0
  if (rv != SC_SUCCESS) {
2063
0
    free(key.exponent.data);
2064
0
    LOG_TEST_RET(card->ctx, rv, "Update component failed");
2065
0
  }
2066
2067
0
  memset(&args, 0, sizeof(args));
2068
0
  args.type = SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC;
2069
0
  args.component = 2;
2070
0
  args.data = key.exponent.data;
2071
0
  args.len = key.exponent.len;
2072
0
  rv = auth_update_component(card, &args);
2073
0
  free(args.data);
2074
0
  LOG_TEST_RET(card->ctx, rv, "Update component failed");
2075
2076
0
  LOG_FUNC_RETURN(card->ctx, (int)len);
2077
0
}
2078
2079
2080
static int
2081
auth_update_binary(struct sc_card *card, unsigned int offset,
2082
    const unsigned char *buf, size_t count, unsigned long flags)
2083
0
{
2084
0
  int rv = 0;
2085
2086
0
  LOG_FUNC_CALLED(card->ctx);
2087
2088
0
  if (!auth_current_ef)
2089
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid auth_current_ef");
2090
2091
0
  sc_log(card->ctx, "offset %i; count %"SC_FORMAT_LEN_SIZE_T"u", offset,
2092
0
         count);
2093
0
  sc_log(card->ctx, "last selected : magic %X; ef %X",
2094
0
      auth_current_ef->magic, auth_current_ef->ef_structure);
2095
2096
0
  if (offset & ~0x7FFF)
2097
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid file offset");
2098
2099
0
  if (auth_current_ef->magic == SC_FILE_MAGIC &&
2100
0
      auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) {
2101
0
    rv = write_publickey(card, offset, buf, count);
2102
0
  } else if (auth_current_ef->magic == SC_FILE_MAGIC &&
2103
0
      auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_DES) {
2104
0
    struct auth_update_component_info args;
2105
2106
0
    memset(&args, 0, sizeof(args));
2107
0
    args.type = SC_CARDCTL_OBERTHUR_KEY_DES;
2108
0
    args.data = (unsigned char *)buf;
2109
0
    args.len = count;
2110
0
    rv = auth_update_component(card, &args);
2111
0
  } else {
2112
0
    rv = iso_ops->update_binary(card, offset, buf, count, 0);
2113
0
  }
2114
2115
0
  LOG_FUNC_RETURN(card->ctx, rv);
2116
0
}
2117
2118
2119
static int
2120
auth_read_binary(struct sc_card *card, unsigned int offset,
2121
    unsigned char *buf, size_t count, unsigned long *flags)
2122
0
{
2123
0
  int rv;
2124
0
  size_t sz;
2125
0
  struct sc_pkcs15_bignum bn[2];
2126
0
  unsigned char *out = NULL;
2127
0
  bn[0].data = NULL;
2128
0
  bn[1].data = NULL;
2129
2130
0
  LOG_FUNC_CALLED(card->ctx);
2131
2132
0
  if (!auth_current_ef)
2133
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid auth_current_ef");
2134
2135
0
  sc_log(card->ctx,
2136
0
         "offset %i; size %"SC_FORMAT_LEN_SIZE_T"u; flags 0x%lX",
2137
0
         offset, count, flags ? *flags : 0);
2138
0
  sc_log(card->ctx,"last selected : magic %X; ef %X",
2139
0
      auth_current_ef->magic, auth_current_ef->ef_structure);
2140
2141
0
  if (offset & ~0x7FFF)
2142
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid file offset");
2143
2144
0
  if (auth_current_ef->magic == SC_FILE_MAGIC &&
2145
0
      auth_current_ef->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC) {
2146
0
    int jj;
2147
0
    unsigned char resp[SC_MAX_APDU_RESP_SIZE];
2148
0
    size_t resp_len, out_len;
2149
0
    struct sc_pkcs15_pubkey_rsa key;
2150
2151
0
    resp_len = sizeof(resp);
2152
0
    rv = auth_read_component(card, SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC,
2153
0
        2, resp, resp_len);
2154
0
    LOG_TEST_RET(card->ctx, rv, "read component failed");
2155
2156
0
    for (jj=0; jj<rv && *(resp+jj)==0; jj++)
2157
0
      ;
2158
2159
0
    if (rv - jj == 0)
2160
0
      return SC_ERROR_INVALID_DATA;
2161
0
    bn[0].data = calloc(1, rv - jj);
2162
0
    if (!bn[0].data) {
2163
0
      rv = SC_ERROR_OUT_OF_MEMORY;
2164
0
      goto err;
2165
0
    }
2166
0
    bn[0].len = rv - jj;
2167
0
    memcpy(bn[0].data, resp + jj, rv - jj);
2168
2169
0
    rv = auth_read_component(card, SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC,
2170
0
        1, resp, resp_len);
2171
0
    LOG_TEST_GOTO_ERR(card->ctx, rv, "Cannot read RSA public key component");
2172
2173
0
    bn[1].data = calloc(1, rv);
2174
0
    if (!bn[1].data) {
2175
0
      rv = SC_ERROR_OUT_OF_MEMORY;
2176
0
      goto err;
2177
0
    }
2178
0
    bn[1].len = rv;
2179
0
    memcpy(bn[1].data, resp, rv);
2180
2181
0
    key.exponent = bn[0];
2182
0
    key.modulus = bn[1];
2183
2184
0
    if (sc_pkcs15_encode_pubkey_rsa(card->ctx, &key, &out, &out_len) != SC_SUCCESS) {
2185
0
      rv = SC_ERROR_INVALID_ASN1_OBJECT;
2186
0
      LOG_TEST_GOTO_ERR(card->ctx, rv, "cannot encode RSA public key");
2187
0
    }
2188
0
    else {
2189
0
      if (out_len < offset) {
2190
0
        rv = SC_ERROR_UNKNOWN_DATA_RECEIVED;
2191
0
        goto err;
2192
0
      }
2193
0
      sz = MIN(out_len - offset, count);
2194
0
      memcpy(buf, out + offset, sz);
2195
2196
0
      sc_log_hex(card->ctx, "write_publickey", buf, sz);
2197
0
      rv = (int)sz;
2198
0
    }
2199
0
  } else {
2200
0
    rv = iso_ops->read_binary(card, offset, buf, count, 0);
2201
0
  }
2202
2203
0
err:
2204
0
  free(bn[0].data);
2205
0
  free(bn[1].data);
2206
0
  free(out);
2207
2208
0
  LOG_FUNC_RETURN(card->ctx, rv);
2209
0
}
2210
2211
2212
static int
2213
auth_read_record(struct sc_card *card, unsigned int nr_rec, unsigned int idx,
2214
    unsigned char *buf, size_t count, unsigned long flags)
2215
0
{
2216
0
  struct sc_apdu apdu;
2217
0
  int rv = 0;
2218
0
  unsigned char recvbuf[SC_MAX_APDU_BUFFER_SIZE];
2219
2220
0
  sc_log(card->ctx,
2221
0
         "auth_read_record(): nr_rec %i; count %"SC_FORMAT_LEN_SIZE_T"u",
2222
0
         nr_rec, count);
2223
2224
0
  if (nr_rec > 0xFF || idx != 0)
2225
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
2226
2227
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB2, nr_rec, 0);
2228
0
  apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
2229
0
  if (flags & SC_RECORD_BY_REC_NR)
2230
0
    apdu.p2 |= 0x04;
2231
2232
0
  apdu.le = MIN(count, SC_MAX_APDU_BUFFER_SIZE);
2233
0
  apdu.resplen = SC_MAX_APDU_BUFFER_SIZE;
2234
0
  apdu.resp = recvbuf;
2235
2236
0
  rv = sc_transmit_apdu(card, &apdu);
2237
0
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
2238
0
  if (apdu.resplen == 0)
2239
0
    LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
2240
0
  if (count < apdu.resplen)
2241
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH);
2242
0
  memcpy(buf, recvbuf, apdu.resplen);
2243
2244
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
2245
0
  LOG_TEST_RET(card->ctx, rv, "Card returned error");
2246
2247
0
  LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen);
2248
0
}
2249
2250
2251
static int
2252
auth_delete_record(struct sc_card *card, unsigned int nr_rec)
2253
0
{
2254
0
  struct sc_apdu apdu;
2255
0
  int rv = 0;
2256
2257
0
  LOG_FUNC_CALLED(card->ctx);
2258
0
  sc_log(card->ctx, "auth_delete_record(): nr_rec %i", nr_rec);
2259
2260
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x32, nr_rec, 0x04);
2261
0
  apdu.cla = 0x80;
2262
2263
0
  rv = sc_transmit_apdu(card, &apdu);
2264
0
  LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
2265
2266
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
2267
0
  LOG_FUNC_RETURN(card->ctx, rv);
2268
0
}
2269
2270
2271
static int
2272
auth_get_serialnr(struct sc_card *card, struct sc_serial_number *serial)
2273
0
{
2274
0
  if (!serial)
2275
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
2276
2277
0
  if (card->serialnr.len==0)
2278
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
2279
2280
0
  memcpy(serial, &card->serialnr, sizeof(*serial));
2281
2282
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2283
0
}
2284
2285
2286
static const struct sc_card_error
2287
auth_warnings[] = {
2288
  { 0x6282, SC_SUCCESS,
2289
    "ignore warning 'End of file or record reached before reading Ne bytes'" },
2290
  {0, 0, NULL},
2291
};
2292
2293
2294
static int
2295
auth_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2)
2296
742
{
2297
742
  int ii;
2298
2299
1.41k
  for (ii = 0; auth_warnings[ii].SWs; ii++) {
2300
742
    if (auth_warnings[ii].SWs == ((sw1 << 8) | sw2)) {
2301
70
      sc_log(card->ctx, "%s", auth_warnings[ii].errorstr);
2302
70
      return auth_warnings[ii].errorno;
2303
70
    }
2304
742
  }
2305
2306
672
  return iso_ops->check_sw(card, sw1, sw2);
2307
742
}
2308
2309
2310
static struct sc_card_driver *
2311
sc_get_driver(void)
2312
9.33k
{
2313
9.33k
  if (iso_ops == NULL)
2314
1
    iso_ops = sc_get_iso7816_driver()->ops;
2315
2316
9.33k
  auth_ops = *iso_ops;
2317
9.33k
  auth_ops.match_card = auth_match_card;
2318
9.33k
  auth_ops.init = auth_init;
2319
9.33k
  auth_ops.finish = auth_finish;
2320
9.33k
  auth_ops.select_file = auth_select_file;
2321
9.33k
  auth_ops.list_files = auth_list_files;
2322
9.33k
  auth_ops.delete_file = auth_delete_file;
2323
9.33k
  auth_ops.create_file = auth_create_file;
2324
9.33k
  auth_ops.read_binary = auth_read_binary;
2325
9.33k
  auth_ops.update_binary = auth_update_binary;
2326
9.33k
  auth_ops.read_record = auth_read_record;
2327
9.33k
  auth_ops.delete_record = auth_delete_record;
2328
9.33k
  auth_ops.card_ctl = auth_card_ctl;
2329
9.33k
  auth_ops.set_security_env = auth_set_security_env;
2330
9.33k
  auth_ops.restore_security_env = auth_restore_security_env;
2331
9.33k
  auth_ops.compute_signature = auth_compute_signature;
2332
9.33k
  auth_ops.decipher = auth_decipher;
2333
9.33k
  auth_ops.process_fci = auth_process_fci;
2334
9.33k
  auth_ops.pin_cmd = auth_pin_cmd;
2335
9.33k
  auth_ops.logout = auth_logout;
2336
9.33k
  auth_ops.check_sw = auth_check_sw;
2337
9.33k
  return &auth_drv;
2338
9.33k
}
2339
2340
2341
struct sc_card_driver *
2342
sc_get_oberthur_driver(void)
2343
9.33k
{
2344
9.33k
  return sc_get_driver();
2345
9.33k
}
2346
2347
#endif /* ENABLE_OPENSSL */