Coverage Report

Created: 2025-07-01 06:08

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