Coverage Report

Created: 2025-08-29 06:26

/src/opensc/src/libopensc/card-npa.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * card-npa.c: Recognize known German identity cards
3
 *
4
 * Copyright (C) 2011-2018 Frank Morgner <frankmorgner@gmail.com>
5
 *
6
 * This file is part of OpenSC.
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
#ifdef HAVE_CONFIG_H
23
#include "config.h"
24
#endif
25
26
#include "card-npa.h"
27
#include "libopensc/internal.h"
28
#include "libopensc/opensc.h"
29
#include "libopensc/pace.h"
30
#include "libopensc/sm.h"
31
#include "sm/sm-eac.h"
32
#include <string.h>
33
34
#ifdef ENABLE_OPENSSL
35
#include <openssl/evp.h>
36
#endif
37
38
static int fread_to_eof(const char *file, unsigned char **buf, size_t *buflen);
39
#include "../tools/fread_to_eof.c"
40
41
struct npa_drv_data {
42
  const char *can;
43
  unsigned char *st_dv_certificate;
44
  size_t st_dv_certificate_len;
45
  unsigned char *st_certificate;
46
  size_t st_certificate_len;
47
  unsigned char *st_key;
48
  size_t st_key_len;
49
  unsigned char *ef_cardaccess;
50
  size_t ef_cardaccess_length;
51
  unsigned char *ef_cardsecurity;
52
  size_t ef_cardsecurity_length;
53
};
54
55
static struct npa_drv_data *npa_drv_data_create(void)
56
0
{
57
0
  struct npa_drv_data *drv_data = calloc(1, sizeof *drv_data);
58
0
  return drv_data;
59
0
}
60
61
static void npa_drv_data_free(struct npa_drv_data *drv_data)
62
0
{
63
0
  if (drv_data) {
64
0
    free(drv_data->ef_cardaccess);
65
0
    free(drv_data->ef_cardsecurity);
66
0
    free(drv_data->st_certificate);
67
0
    free(drv_data->st_dv_certificate);
68
0
    free(drv_data->st_key);
69
0
    free(drv_data);
70
0
  }
71
0
}
72
73
static struct sc_card_operations npa_ops;
74
static struct sc_card_driver npa_drv = {
75
  "German ID card (neuer Personalausweis, nPA)",
76
  "npa",
77
  &npa_ops,
78
  NULL, 0, NULL
79
};
80
81
static int npa_load_options(sc_context_t *ctx, struct npa_drv_data *drv_data)
82
0
{
83
0
  int r;
84
0
  size_t i, j;
85
0
  scconf_block **found_blocks, *block;
86
0
  const char *file;
87
88
0
  if (!ctx || !drv_data) {
89
0
    r = SC_ERROR_INTERNAL;
90
0
    goto err;
91
0
  }
92
93
0
  for (i = 0; ctx->conf_blocks[i]; i++) {
94
0
    found_blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
95
0
          "card_driver", "npa");
96
0
    if (!found_blocks)
97
0
      continue;
98
99
0
    for (j = 0, block = found_blocks[j]; block; j++, block = found_blocks[j]) {
100
0
      if (!drv_data->can)
101
0
        drv_data->can = scconf_get_str(block, "can", NULL);
102
103
0
      if (!drv_data->st_dv_certificate
104
0
          || !drv_data->st_dv_certificate_len) {
105
0
        file = scconf_get_str(block, "st_dv_certificate", NULL);
106
0
        if (!fread_to_eof(file,
107
0
              (unsigned char **) &drv_data->st_dv_certificate,
108
0
              &drv_data->st_dv_certificate_len))
109
0
          sc_log(ctx, "Warning: Could not read %s.\n", file);
110
0
      }
111
112
0
      if (!drv_data->st_certificate
113
0
          || !drv_data->st_certificate_len) {
114
0
        file = scconf_get_str(block, "st_certificate", NULL);
115
0
        if (!fread_to_eof(file,
116
0
              (unsigned char **) &drv_data->st_certificate,
117
0
              &drv_data->st_certificate_len))
118
0
          sc_log(ctx, "Warning: Could not read %s.\n", file);
119
0
      }
120
121
0
      if (!drv_data->st_key
122
0
          || !drv_data->st_key_len) {
123
0
        file = scconf_get_str(block, "st_key", NULL);
124
0
        if (!fread_to_eof(file,
125
0
              (unsigned char **) &drv_data->st_key,
126
0
              &drv_data->st_key_len))
127
0
          sc_log(ctx, "Warning: Could not read %s.\n", file);
128
0
      }
129
0
    }
130
    
131
0
    free(found_blocks);
132
0
  }
133
0
  r = SC_SUCCESS;
134
135
0
err:
136
0
  return r;
137
0
}
138
139
// clang-format off
140
unsigned char dir_content_ref[] = {
141
  0x61, 0x32, 0x4F, 0x0F, 0xE8, 0x28, 0xBD, 0x08, 0x0F, 0xA0, 0x00, 0x00,
142
  0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E, 0x50, 0x0F, 0x43, 0x49, 0x41,
143
  0x20, 0x7A, 0x75, 0x20, 0x44, 0x46, 0x2E, 0x65, 0x53, 0x69, 0x67, 0x6E,
144
  0x51, 0x00, 0x73, 0x0C, 0x4F, 0x0A, 0xA0, 0x00, 0x00, 0x01, 0x67, 0x45,
145
  0x53, 0x49, 0x47, 0x4E, 0x61, 0x09, 0x4F, 0x07, 0xA0, 0x00, 0x00, 0x02,
146
  0x47, 0x10, 0x01, 0x61, 0x0B, 0x4F, 0x09, 0xE8, 0x07, 0x04, 0x00, 0x7F,
147
  0x00, 0x07, 0x03, 0x02, 0x61, 0x0C, 0x4F, 0x0A, 0xA0, 0x00, 0x00, 0x01,
148
  0x67, 0x45, 0x53, 0x49, 0x47, 0x4E,
149
};
150
// clang-format on
151
152
static int npa_match_card(sc_card_t * card)
153
90
{
154
90
  unsigned char dir_content[sizeof dir_content_ref];
155
90
  unsigned char id[] = {0x2F, 0x00};
156
90
  sc_apdu_t select_ef_dir;
157
158
90
  sc_format_apdu_ex(&select_ef_dir, 0x00, 0xA4, 0x02, 0x0C, id, sizeof id, NULL, 0);
159
160
90
  if (SC_SUCCESS == sc_select_file(card, sc_get_mf_path(), NULL)
161
90
      && SC_SUCCESS == sc_transmit_apdu(card, &select_ef_dir)
162
90
      && select_ef_dir.sw1 == 0x90 && select_ef_dir.sw2 == 0x00
163
90
      && sizeof dir_content == sc_read_binary(card, 0, dir_content, sizeof dir_content, 0)
164
90
      && 0 == memcmp(dir_content_ref, dir_content, sizeof dir_content))
165
0
    return 1;
166
167
90
  return 0;
168
90
}
169
170
static void npa_get_cached_pace_params(sc_card_t *card,
171
    struct establish_pace_channel_input *pace_input,
172
    struct establish_pace_channel_output *pace_output)
173
0
{
174
0
  struct npa_drv_data *drv_data;
175
176
0
  if (card->drv_data) {
177
0
    drv_data = card->drv_data;
178
    
179
0
    if (pace_output) {
180
0
      pace_output->ef_cardaccess = drv_data->ef_cardaccess;
181
0
      pace_output->ef_cardaccess_length = drv_data->ef_cardaccess_length;
182
0
    }
183
184
0
    if (pace_input && pace_input->pin_id == PACE_PIN_ID_CAN) {
185
0
      pace_input->pin = (const unsigned char *) drv_data->can;
186
0
      pace_input->pin_length = drv_data->can ? strlen(drv_data->can) : 0;
187
0
    }
188
0
  }
189
0
}
190
191
static void npa_get_cached_ta_params(sc_card_t *card,
192
  const unsigned char *certs[2], size_t certs_lens[2],
193
  const unsigned char **st_key, size_t *st_key_len)
194
0
{
195
0
  struct npa_drv_data *drv_data;
196
0
  size_t i;
197
198
0
  if (card->drv_data) {
199
0
    drv_data = card->drv_data;
200
201
0
    if (certs && certs_lens) {
202
0
      i = 0;
203
0
      if (drv_data->st_dv_certificate) {
204
0
        certs[i] = drv_data->st_dv_certificate;
205
0
        certs_lens[i] = drv_data->st_dv_certificate_len;
206
0
        i++;
207
0
      }
208
0
      if (drv_data->st_certificate) {
209
0
        certs[i] = drv_data->st_certificate;
210
0
        certs_lens[i] = drv_data->st_certificate_len;
211
0
      }
212
0
    }
213
0
    if (st_key && st_key_len) {
214
0
      *st_key = drv_data->st_key;
215
0
      *st_key_len = drv_data->st_key_len;
216
0
    }
217
0
  }
218
0
}
219
220
static void npa_get_cached_ca_params(sc_card_t *card,
221
  unsigned char **ef_cardsecurity, size_t *ef_cardsecurity_length)
222
0
{
223
0
  struct npa_drv_data *drv_data;
224
225
0
  if (card->drv_data) {
226
0
    drv_data = card->drv_data;
227
228
0
    if (ef_cardsecurity && ef_cardsecurity_length) {
229
0
      *ef_cardsecurity = drv_data->ef_cardsecurity;
230
0
      *ef_cardsecurity_length = drv_data->ef_cardsecurity_length;
231
0
    }
232
0
  }
233
0
}
234
235
static void npa_cache_or_free(sc_card_t *card,
236
    unsigned char **ef_cardaccess, size_t *ef_cardaccess_length,
237
    unsigned char **ef_cardsecurity, size_t *ef_cardsecurity_length)
238
0
{
239
0
  struct npa_drv_data *drv_data;
240
241
0
  if (card && card->drv_data) {
242
0
    drv_data = card->drv_data;
243
244
0
    if (ef_cardaccess && ef_cardaccess_length
245
0
        && *ef_cardaccess && *ef_cardaccess_length) {
246
0
      drv_data->ef_cardaccess = *ef_cardaccess;
247
0
      drv_data->ef_cardaccess_length = *ef_cardaccess_length;
248
0
      *ef_cardaccess = NULL;
249
0
      *ef_cardaccess_length = 0;
250
0
    }
251
0
    if (ef_cardsecurity && ef_cardsecurity_length
252
0
        && *ef_cardsecurity && *ef_cardsecurity_length) {
253
0
      drv_data->ef_cardsecurity = *ef_cardsecurity;
254
0
      drv_data->ef_cardsecurity_length = *ef_cardsecurity_length;
255
0
      *ef_cardsecurity = NULL;
256
0
      *ef_cardsecurity_length = 0;
257
0
    }
258
0
  } else {
259
0
    if (ef_cardaccess && ef_cardaccess_length) {
260
0
      free(*ef_cardaccess);
261
0
      *ef_cardaccess = NULL;
262
0
      *ef_cardaccess_length = 0;
263
0
    }
264
0
    if (ef_cardsecurity && ef_cardsecurity_length) {
265
0
      free(*ef_cardsecurity);
266
0
      *ef_cardsecurity = NULL;
267
0
      *ef_cardsecurity_length = 0;
268
0
    }
269
0
  }
270
0
}
271
272
static int npa_unlock_esign(sc_card_t *card)
273
0
{
274
0
  int r = SC_ERROR_INTERNAL;
275
0
  struct establish_pace_channel_input pace_input;
276
0
  struct establish_pace_channel_output pace_output;
277
0
  const unsigned char *certs[] = { NULL, NULL };
278
0
  size_t certs_lens[] = { 0, 0};
279
0
  const unsigned char *st_key = NULL;
280
0
  size_t st_key_len = 0;
281
0
  unsigned char *ef_cardsecurity = NULL;
282
0
  size_t ef_cardsecurity_len = 0;
283
0
  memset(&pace_input, 0, sizeof pace_input);
284
0
  memset(&pace_output, 0, sizeof pace_output);
285
286
0
  if (!card) {
287
0
    r = SC_ERROR_INVALID_CARD;
288
0
    goto err;
289
0
  }
290
291
0
  sc_log(card->ctx, "Will verify CAN first for unlocking eSign application.\n");
292
0
  pace_input.chat = esign_chat;
293
0
  pace_input.chat_length = sizeof esign_chat;
294
0
  pace_input.pin_id = PACE_PIN_ID_CAN;
295
0
  npa_get_cached_pace_params(card, &pace_input, &pace_output);
296
0
  npa_get_cached_ta_params(card, certs, certs_lens, &st_key, &st_key_len);
297
0
  npa_get_cached_ca_params(card, &ef_cardsecurity, &ef_cardsecurity_len);
298
299
0
  if (!(card->reader && (card->reader->capabilities & SC_READER_CAP_PACE_ESIGN))
300
0
      && (!st_key || !st_key_len)) {
301
0
    sc_log(card->ctx, "QES requires a comfort reader (CAT-K) or a ST certificate.\n");
302
0
    r = SC_ERROR_NOT_SUPPORTED;
303
0
    goto err;
304
0
  }
305
306
  /* FIXME set flags with opensc.conf */
307
0
  eac_default_flags |= EAC_FLAG_DISABLE_CHECK_TA;
308
0
  eac_default_flags |= EAC_FLAG_DISABLE_CHECK_CA;
309
310
  /* FIXME show an alert to the user if CAN is NULL */
311
0
  r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02);
312
0
  if (SC_SUCCESS != r) {
313
0
    sc_log(card->ctx, "Error verifying CAN.\n");
314
0
    goto err;
315
0
  }
316
317
0
  if (card->reader->capabilities & SC_READER_CAP_PACE_ESIGN) {
318
0
    sc_log(card->ctx, "Proved Access rights to eSign application with comfort reader (CAT-K).\n");
319
0
  } else {
320
0
    r = perform_terminal_authentication(card, certs, certs_lens, st_key,
321
0
        st_key_len, NULL, 0);
322
0
    if (r != SC_SUCCESS) {
323
0
      sc_log(card->ctx, "Error authenticating as signature terminal.\n");
324
0
      goto err;
325
0
    }
326
0
    r = perform_chip_authentication(card, &ef_cardsecurity, &ef_cardsecurity_len);
327
0
    if ( SC_SUCCESS != r) {
328
0
      sc_log(card->ctx, "Error verifying the chip's authenticity.\n");
329
0
    }
330
331
0
    sc_log(card->ctx, "Proved Access rights to eSign application with configured key as ST.\n");
332
0
  }
333
334
0
err:
335
0
  npa_cache_or_free(card, &pace_output.ef_cardaccess,
336
0
      &pace_output.ef_cardaccess_length,
337
0
      &ef_cardsecurity, &ef_cardsecurity_len);
338
0
  free(pace_output.recent_car);
339
0
  free(pace_output.previous_car);
340
0
  free(pace_output.id_icc);
341
0
  free(pace_output.id_pcd);
342
343
0
  return r;
344
0
}
345
346
static int npa_finish(sc_card_t * card)
347
0
{
348
0
  sc_sm_stop(card);
349
0
  npa_drv_data_free(card->drv_data);
350
0
  card->drv_data = NULL;
351
352
0
  return SC_SUCCESS;
353
0
}
354
355
static void npa_init_apps(sc_card_t * card)
356
0
{
357
  /* this initializes the internal structures with the data from
358
   * `dir_content_ref` */
359
0
  const u8 *aids[] = {
360
0
    (const u8 *) "\xa0\x00\x00\x02\x47\x10\x01",
361
0
    (const u8 *) "\xe8\x07\x04\x00\x7f\x00\x07\x03\x02",
362
0
    (const u8 *) "\xa0\x00\x00\x01\x67\x45\x53\x49\x47\x4e",
363
0
  };
364
0
  const size_t lens[] = {7, 9, 10};
365
0
  size_t i;
366
367
0
  sc_free_apps(card);
368
0
  card->app_count = 0;
369
370
0
  for (i = 0; i < 3; i++) {
371
0
    const u8 *aid = aids[i];
372
0
    size_t aid_len = lens[i];
373
0
    struct sc_app_info *app = calloc(1, sizeof *app);
374
0
    if (NULL == app)
375
0
      continue;
376
377
0
    app->aid.len = aid_len;
378
0
    memcpy(app->aid.value, aid, aid_len);
379
380
0
    app->path.len = aid_len;
381
0
    memcpy(app->path.value, aid, aid_len);
382
0
    app->path.type = SC_PATH_TYPE_DF_NAME;
383
384
0
    app->rec_nr = -1;
385
386
0
    card->app[card->app_count] = app;
387
0
    card->app_count++;
388
0
  }
389
0
}
390
391
static int npa_init(sc_card_t * card)
392
0
{
393
0
  int flags = SC_ALGORITHM_ECDSA_RAW;
394
0
  int ext_flags = 0;
395
0
  int r;
396
397
0
  if (!card) {
398
0
    r = SC_ERROR_INVALID_CARD;
399
0
    goto err;
400
0
  }
401
402
0
  card->caps |= SC_CARD_CAP_APDU_EXT | SC_CARD_CAP_RNG;
403
  /* 1520 bytes is the minimum length of the communication buffer in all
404
   * Chip/OS variants */
405
0
  card->max_recv_size = 1520;
406
0
  card->max_send_size = 1520;
407
0
#ifdef ENABLE_SM
408
0
  memset(&card->sm_ctx, 0, sizeof card->sm_ctx);
409
0
#endif
410
411
0
  r = _sc_card_add_ec_alg(card, 192, flags, ext_flags, NULL);
412
0
  if (r != SC_SUCCESS)
413
0
    goto err;
414
0
  r = _sc_card_add_ec_alg(card, 224, flags, ext_flags, NULL);
415
0
  if (r != SC_SUCCESS)
416
0
    goto err;
417
0
  r = _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL);
418
0
  if (r != SC_SUCCESS)
419
0
    goto err;
420
  /* nPA does not encode the proprietary fieldSize in PrivateECKeyAttributes,
421
   * which leaves it at 0 for OpenSC, so we need to add 0x00 as supported
422
   * field_length */
423
0
  r = _sc_card_add_ec_alg(card, 0, flags, ext_flags, NULL);
424
0
  if (r != SC_SUCCESS)
425
0
    goto err;
426
427
0
  card->drv_data = npa_drv_data_create();
428
0
  if (!card->drv_data) {
429
0
    npa_finish(card);
430
0
    r = SC_ERROR_OUT_OF_MEMORY;
431
0
    goto err;
432
0
  }
433
0
  r = npa_load_options(card->ctx, card->drv_data);
434
0
  if (r != SC_SUCCESS)
435
0
    goto err;
436
437
0
  npa_init_apps(card);
438
439
  /* unlock the eSign application for reading the certificates
440
   * by the PKCS#15 layer (i.e. sc_pkcs15_bind_internal) */
441
0
  if (SC_SUCCESS != npa_unlock_esign(card)) {
442
0
    sc_log(card->ctx, "Probably not all functionality will be available.\n");
443
0
  }
444
445
0
err:
446
0
  return r;
447
0
}
448
449
static int npa_set_security_env(struct sc_card *card,
450
    const struct sc_security_env *env, int se_num)
451
0
{
452
0
  int r;
453
0
  struct sc_card_driver *iso_drv;
454
0
  struct sc_security_env fixed_env;
455
456
0
  iso_drv = sc_get_iso7816_driver();
457
458
0
  if (!env || !iso_drv || !iso_drv->ops || !iso_drv->ops->set_security_env) {
459
0
    r = SC_ERROR_INTERNAL;
460
0
  } else {
461
0
    memcpy(&fixed_env, env, sizeof fixed_env);
462
0
    if (env->operation == SC_SEC_OPERATION_SIGN) {
463
      /* The pkcs#15 layer assumes that the field_size of the private key
464
       * object is correctly initialized and wants to include it as
465
       * algorithm reference. We disable it here */
466
0
      fixed_env.flags &= ~SC_SEC_ENV_ALG_REF_PRESENT;
467
0
    }
468
0
    r = iso_drv->ops->set_security_env(card, &fixed_env, se_num);
469
0
  }
470
471
0
  return r;
472
0
}
473
474
static int npa_pin_cmd_get_info(struct sc_card *card,
475
    struct sc_pin_cmd_data *data, int *tries_left)
476
0
{
477
0
  int r;
478
0
  u8 pin_reference;
479
480
0
  if (!data || data->pin_type != SC_AC_CHV || !tries_left) {
481
0
    r = SC_ERROR_INVALID_ARGUMENTS;
482
0
    goto err;
483
0
  }
484
485
0
  pin_reference = data->pin_reference;
486
0
  switch (data->pin_reference) {
487
0
    case PACE_PIN_ID_CAN:
488
0
    case PACE_PIN_ID_MRZ:
489
      /* usually unlimited number of retries */
490
0
      *tries_left = -1;
491
0
      data->pin1.max_tries = -1;
492
0
      data->pin1.tries_left = -1;
493
0
      r = SC_SUCCESS;
494
0
      break;
495
496
0
    case PACE_PIN_ID_PUK:
497
      /* usually 10 tries */
498
0
      *tries_left = 10;
499
0
      data->pin1.max_tries = 10;
500
0
      r = eac_pace_get_tries_left(card,
501
0
          pin_reference, tries_left);
502
0
      data->pin1.tries_left = *tries_left;
503
0
      break;
504
505
0
    case PACE_PIN_ID_PIN:
506
      /* usually 3 tries */
507
0
      *tries_left = 3;
508
0
      data->pin1.max_tries = 3;
509
0
      r = eac_pace_get_tries_left(card,
510
0
          pin_reference, tries_left);
511
0
      data->pin1.tries_left = *tries_left;
512
0
      break;
513
514
0
    default:
515
0
      r = SC_ERROR_OBJECT_NOT_FOUND;
516
0
      goto err;
517
0
  }
518
519
0
err:
520
0
  return r;
521
0
}
522
523
static int npa_pace_verify(struct sc_card *card,
524
    unsigned char pin_reference, struct sc_pin_cmd_pin *pin,
525
    const unsigned char *chat, size_t chat_length, int *tries_left)
526
0
{
527
0
  int r;
528
0
  struct establish_pace_channel_input pace_input;
529
0
  struct establish_pace_channel_output pace_output;
530
531
0
  memset(&pace_input, 0, sizeof pace_input);
532
0
  memset(&pace_output, 0, sizeof pace_output);
533
0
  if (chat) {
534
0
    pace_input.chat = chat;
535
0
    pace_input.chat_length = chat_length;
536
0
  }
537
0
  pace_input.pin_id = pin_reference;
538
0
  if (pin) {
539
0
    pace_input.pin = pin->data;
540
0
    pace_input.pin_length = pin->len;
541
0
  }
542
0
  npa_get_cached_pace_params(card, &pace_input, &pace_output);
543
544
0
  r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02);
545
546
0
  if (tries_left) {
547
0
    if (pace_output.mse_set_at_sw1 == 0x63
548
0
        && (pace_output.mse_set_at_sw2 & 0xc0) == 0xc0) {
549
0
      *tries_left = pace_output.mse_set_at_sw2 & 0x0f;
550
0
    } else {
551
0
      *tries_left = -1;
552
0
    }
553
0
  }
554
555
  /* resume the PIN if needed */
556
0
  if (pin_reference == PACE_PIN_ID_PIN
557
0
      && r != SC_SUCCESS
558
0
      && pace_output.mse_set_at_sw1 == 0x63
559
0
      && (pace_output.mse_set_at_sw2 & 0xc0) == 0xc0
560
0
      && (pace_output.mse_set_at_sw2 & 0x0f) <= EAC_UC_PIN_SUSPENDED) {
561
    /* TODO ask for user consent when automatically resuming the PIN */
562
0
    sc_log(card->ctx, "%s is suspended. Will try to resume it with %s.\n",
563
0
        eac_secret_name(pin_reference), eac_secret_name(PACE_PIN_ID_CAN));
564
565
0
    pace_input.pin_id = PACE_PIN_ID_CAN;
566
0
    pace_input.pin = NULL;
567
0
    pace_input.pin_length = 0;
568
569
0
    r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02);
570
571
0
    if (r == SC_SUCCESS) {
572
0
      pace_input.pin_id = pin_reference;
573
0
      if (pin) {
574
0
        pace_input.pin = pin->data;
575
0
        pace_input.pin_length = pin->len;
576
0
      }
577
578
0
      r = perform_pace(card, pace_input, &pace_output, EAC_TR_VERSION_2_02);
579
580
0
      if (r == SC_SUCCESS) {
581
0
        sc_log(card->ctx, "%s resumed.\n", eac_secret_name(pin_reference));
582
0
        if (tries_left) {
583
0
          *tries_left = EAC_MAX_PIN_TRIES;
584
0
        }
585
0
      } else {
586
0
        if (tries_left) {
587
0
          if (pace_output.mse_set_at_sw1 == 0x63
588
0
              && (pace_output.mse_set_at_sw2 & 0xc0) == 0xc0) {
589
0
            *tries_left = pace_output.mse_set_at_sw2 & 0x0f;
590
0
          } else {
591
0
            *tries_left = -1;
592
0
          }
593
0
        }
594
0
      }
595
0
    }
596
0
  }
597
598
0
  if (pin_reference == PACE_PIN_ID_PIN && tries_left) {
599
0
     if (*tries_left == 0) {
600
0
       sc_log(card->ctx, "%s is suspended and must be resumed.\n",
601
0
           eac_secret_name(pin_reference));
602
0
     } else if (*tries_left == 1) {
603
0
       sc_log(card->ctx, "%s is blocked and must be unblocked.\n",
604
0
           eac_secret_name(pin_reference));
605
0
     }
606
0
  }
607
608
0
  npa_cache_or_free(card, &pace_output.ef_cardaccess,
609
0
      &pace_output.ef_cardaccess_length, NULL, NULL);
610
0
  free(pace_output.recent_car);
611
0
  free(pace_output.previous_car);
612
0
  free(pace_output.id_icc);
613
0
  free(pace_output.id_pcd);
614
615
0
  return r;
616
0
}
617
618
static int npa_standard_pin_cmd(struct sc_card *card,
619
    struct sc_pin_cmd_data *data, int *tries_left)
620
0
{
621
0
  int r;
622
0
  struct sc_card_driver *iso_drv;
623
624
0
  iso_drv = sc_get_iso7816_driver();
625
626
0
  if (!iso_drv || !iso_drv->ops || !iso_drv->ops->pin_cmd) {
627
0
    r = SC_ERROR_INTERNAL;
628
0
  } else {
629
0
    r = iso_drv->ops->pin_cmd(card, data, tries_left);
630
0
  }
631
632
0
  return r;
633
0
}
634
635
int
636
npa_reset_retry_counter(sc_card_t *card, enum s_type pin_id,
637
    int ask_for_secret, const char *new, size_t new_len)
638
0
{
639
0
  sc_apdu_t apdu;
640
0
  char *p = NULL;
641
0
  int r;
642
643
0
  if (ask_for_secret && (!new || !new_len)) {
644
0
    if (!(SC_READER_CAP_PIN_PAD & card->reader->capabilities)) {
645
0
#ifdef ENABLE_OPENSSL
646
0
      p = malloc(EAC_MAX_PIN_LEN+1);
647
0
      if (!p) {
648
0
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Not enough memory for new PIN.\n");
649
0
        return SC_ERROR_OUT_OF_MEMORY;
650
0
      }
651
0
      if (0 > EVP_read_pw_string_min(p,
652
0
            EAC_MIN_PIN_LEN, EAC_MAX_PIN_LEN+1,
653
0
            "Please enter your new PIN: ", 0)) {
654
0
        sc_log_openssl(card->ctx);
655
0
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read new PIN.\n");
656
0
        free(p);
657
0
        return SC_ERROR_INTERNAL;
658
0
      }
659
0
      new_len = strlen(p);
660
0
      if (new_len > EAC_MAX_PIN_LEN) {
661
0
        free(p);
662
0
        return SC_ERROR_INVALID_PIN_LENGTH;
663
0
      }
664
0
      new = p;
665
#else
666
      return SC_ERROR_NOT_SUPPORTED;
667
#endif
668
0
    }
669
0
  }
670
671
0
  sc_format_apdu(card, &apdu, 0, 0x2C, 0, pin_id);
672
0
  apdu.data = (u8 *) new;
673
0
  apdu.datalen = new_len;
674
0
  apdu.lc = apdu.datalen;
675
676
0
  if (new_len || ask_for_secret) {
677
0
    apdu.p1 = 0x02;
678
0
    apdu.cse = SC_APDU_CASE_3_SHORT;
679
0
  } else {
680
0
    apdu.p1 = 0x03;
681
0
    apdu.cse = SC_APDU_CASE_1;
682
0
  }
683
684
0
  if (ask_for_secret && !new_len) {
685
0
    struct sc_pin_cmd_data data;
686
0
    data.apdu = &apdu;
687
0
    data.cmd = SC_PIN_CMD_CHANGE;
688
0
    data.flags = SC_PIN_CMD_IMPLICIT_CHANGE;
689
0
    data.pin2.encoding = SC_PIN_ENCODING_ASCII;
690
0
    data.pin2.offset = 5;
691
0
    data.pin2.max_length = EAC_MAX_PIN_LEN;
692
0
    data.pin2.min_length = EAC_MIN_PIN_LEN;
693
0
    data.pin2.pad_length = 0;
694
0
    r = card->reader->ops->perform_verify(card->reader, &data);
695
0
  } else
696
0
    r = sc_transmit_apdu(card, &apdu);
697
698
0
  if (p) {
699
0
    sc_mem_clear(p, new_len);
700
0
    free(p);
701
0
  }
702
703
0
  return r;
704
0
}
705
706
static int npa_pin_cmd(struct sc_card *card,
707
    struct sc_pin_cmd_data *data, int *tries_left)
708
0
{
709
0
  int r;
710
711
0
  if (!data) {
712
0
    r = SC_ERROR_INVALID_ARGUMENTS;
713
0
    goto err;
714
0
  }
715
716
0
  if (data->pin_type != SC_AC_CHV) {
717
0
    r = SC_ERROR_NOT_SUPPORTED;
718
0
    goto err;
719
0
  }
720
721
0
  switch (data->cmd) {
722
0
    case SC_PIN_CMD_GET_INFO:
723
0
      r = npa_pin_cmd_get_info(card, data, tries_left);
724
0
      if (r != SC_SUCCESS)
725
0
        goto err;
726
0
      break;
727
728
0
    case SC_PIN_CMD_UNBLOCK:
729
0
#ifdef ENABLE_SM
730
      /* opensc-explorer unblocks the PIN by only sending
731
       * SC_PIN_CMD_UNBLOCK whereas the PKCS#15 framework first verifies
732
       * the PUK with SC_PIN_CMD_VERIFY and then calls with
733
       * SC_PIN_CMD_UNBLOCK.
734
       *
735
       * Here we determine whether the PUK has been verified or not by
736
       * checking if an SM channel has been established. */
737
0
      if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) {
738
        /* PUK has not yet been verified */
739
0
        r = npa_pace_verify(card, PACE_PIN_ID_PUK, &(data->pin1), NULL,
740
0
            0, NULL);
741
0
        if (r != SC_SUCCESS)
742
0
          goto err;
743
0
      }
744
0
#endif
745
0
      r = npa_reset_retry_counter(card, data->pin_reference, 0,
746
0
          NULL, 0);
747
0
      if (r != SC_SUCCESS)
748
0
        goto err;
749
0
      break;
750
751
0
    case SC_PIN_CMD_CHANGE:
752
0
    case SC_PIN_CMD_VERIFY:
753
0
      switch (data->pin_reference) {
754
0
        case PACE_PIN_ID_CAN:
755
0
        case PACE_PIN_ID_PUK:
756
0
        case PACE_PIN_ID_MRZ:
757
0
        case PACE_PIN_ID_PIN:
758
0
          r = npa_pace_verify(card, data->pin_reference,
759
0
              &(data->pin1), NULL, 0, tries_left);
760
0
          if (r != SC_SUCCESS)
761
0
            goto err;
762
0
          break;
763
764
0
        default:
765
          /* assuming QES PIN */
766
767
          /* We assume that the eSign application has already been
768
           * unlocked, see npa_init().
769
           *
770
           * Now, verify the QES PIN. */
771
0
          r = npa_standard_pin_cmd(card, data, tries_left);
772
0
          if (r != SC_SUCCESS)
773
0
            goto err;
774
0
          break;
775
0
      }
776
777
0
      if (data->cmd == SC_PIN_CMD_CHANGE) {
778
0
        r = npa_reset_retry_counter(card, data->pin_reference, 1,
779
0
            (const char *) data->pin2.data, data->pin2.len);
780
0
        if (r != SC_SUCCESS)
781
0
          goto err;
782
0
      }
783
0
      break;
784
785
0
    default:
786
0
      r = SC_ERROR_INTERNAL;
787
0
      goto err;
788
0
      break;
789
790
0
  }
791
792
0
err:
793
0
  LOG_FUNC_RETURN(card->ctx, r);
794
0
}
795
796
static int npa_logout(sc_card_t *card)
797
0
{
798
0
  struct sc_apdu apdu;
799
800
0
  sc_sm_stop(card);
801
802
0
  if (card->reader->capabilities & SC_READER_CAP_PACE_GENERIC) {
803
    /* If PACE is done between reader and card, SM is transparent to us as
804
     * it ends at the reader. With CLA=0x0C we provoke a SM error to
805
     * disable SM on the reader. */
806
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xA4, 0x00, 0x00);
807
0
    apdu.cla = 0x0C;
808
0
    if (SC_SUCCESS != sc_transmit_apdu(card, &apdu))
809
0
      sc_log(card->ctx, "Warning: Could not logout.");
810
0
  }
811
0
  return sc_select_file(card, sc_get_mf_path(), NULL);
812
0
}
813
814
struct sc_card_driver *sc_get_npa_driver(void)
815
313
{
816
313
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
817
818
313
  npa_ops = *iso_drv->ops;
819
313
  npa_ops.match_card = npa_match_card;
820
313
  npa_ops.init = npa_init;
821
313
  npa_ops.finish = npa_finish;
822
313
  npa_ops.set_security_env = npa_set_security_env;
823
313
  npa_ops.pin_cmd = npa_pin_cmd;
824
313
  npa_ops.logout = npa_logout;
825
826
313
  return &npa_drv;
827
313
}