Coverage Report

Created: 2026-10-17 06:29

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