Coverage Report

Created: 2026-03-08 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/card-dnie.c
Line
Count
Source
1
/**
2
 * card-dnie.c: Support for Spanish DNI electronico (DNIe card).
3
 *
4
 * Copyright (C) 2010 Juan Antonio Martinez <jonsito@terra.es>
5
 *
6
 * This work is derived from many sources at OpenSC Project site,
7
 * (see references) and the information made public for Spanish
8
 * Direccion General de la Policia y de la Guardia Civil
9
 *
10
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2.1 of the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with this library; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
 */
24
25
#define __CARD_DNIE_C__
26
27
#ifdef HAVE_CONFIG_H
28
#include "config.h"
29
#endif
30
31
#if defined(ENABLE_OPENSSL) && defined(ENABLE_SM) /* empty file without openssl or sm */
32
33
#include <stdlib.h>
34
#include <string.h>
35
#include <stdarg.h>
36
#include <sys/stat.h>
37
38
#include "opensc.h"
39
#include "cardctl.h"
40
#include "internal.h"
41
#include "cwa14890.h"
42
#include "cwa-dnie.h"
43
44
#ifdef _WIN32
45
46
#ifndef UNICODE
47
#define UNICODE
48
#endif
49
50
#include <windows.h>
51
#endif
52
#ifdef __APPLE__
53
#include <Carbon/Carbon.h>
54
#endif
55
56
0
#define MAX_RESP_BUFFER_SIZE 2048
57
58
/* default titles */
59
#define USER_CONSENT_TITLE "Confirm"
60
61
extern int dnie_read_file(
62
  sc_card_t * card,
63
  const sc_path_t * path,
64
  sc_file_t ** file,
65
  u8 ** buffer, size_t * length);
66
67
#define DNIE_CHIP_NAME "DNIe: Spanish eID card"
68
45
#define DNIE_CHIP_SHORTNAME "dnie"
69
224
#define DNIE_MF_NAME "Master.File"
70
71
/* default user consent program (if required) */
72
#define USER_CONSENT_CMD "/usr/bin/pinentry"
73
74
/**
75
 * SW internal apdu response table.
76
 *
77
 * Override APDU response error codes from iso7816.c to allow
78
 * handling of SM specific error
79
 */
80
static const struct sc_card_error dnie_errors[] = {
81
  {0x6688, SC_ERROR_SM, "Cryptographic checksum invalid"},
82
  {0x6987, SC_ERROR_SM, "Expected SM Data Object missing"},
83
  {0x6988, SC_ERROR_SM, "SM Data Object incorrect"},
84
  {0, 0, NULL}
85
};
86
87
/*
88
 * DNIe ATR info from DGP web page
89
 *
90
Tag Value Meaning
91
TS  0x3B  Direct Convention
92
T0  0x7F  Y1=0x07=0111; TA1,TB1 y TC1 present.
93
          K=0x0F=1111; 15 historical bytes
94
TA1 0x38  FI (Factor de conversión de la tasa de reloj) = 744
95
          DI (Factor de ajuste de la tasa de bits) = 12
96
          Máximo 8 Mhz.
97
TB1 0x00  Vpp (voltaje de programación) no requerido.
98
TC1 0x00  No se requiere tiempo de espera adicional.
99
H1  0x00  No usado
100
H2  0x6A  Datos de preexpedición. Diez bytes con identificación del expedidor.
101
H3  0x44  'D'
102
H4  0x4E  'N'
103
H5  0x49  'I'
104
H6  0x65  'e'
105
H7  Fabricante de la tecnología Match-on-Card incorporada.
106
    0x10  SAGEM
107
    0x20  SIEMENS
108
H8  0x02  Fabricante del CI: STMicroelectronics.
109
H9  0x4C
110
H10 0x34  Tipo de CI: 19WL34
111
H11 0x01  MSB de la version del SO: 1
112
H12 0x1v  LSB de la version del SO: 1v
113
H13 Fase del ciclo de vida .
114
    0x00  prepersonalización.
115
    0x01  personalización.
116
    0x03  usuario.
117
    0x0F  final.
118
H14 0xss
119
H15 0xss  Bytes de estado
120
121
H13-H15: 0x03 0x90 0x00 user phase: tarjeta operativa
122
H13-H15: 0x0F 0x65 0x81 final phase: tarjeta no operativa
123
*/
124
125
/**
126
 * ATR Table list.
127
 * OpenDNIe defines two ATR's for user and finalized card state
128
 */
129
static struct sc_atr_table dnie_atrs[] = {
130
  /* TODO: get ATR for uninitialized DNIe */
131
  {   /** card activated; normal operation state */
132
   "3B:7F:00:00:00:00:6A:44:4E:49:65:00:00:00:00:00:00:03:90:00",
133
   "FF:FF:00:FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:FF:FF:FF",
134
   DNIE_CHIP_SHORTNAME,
135
   SC_CARD_TYPE_DNIE_USER,
136
   0,
137
   NULL},
138
  {   /** card finalized, unusable */
139
   "3B:7F:00:00:00:00:6A:44:4E:49:65:00:00:00:00:00:00:0F:65:81",
140
   "FF:FF:00:FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:FF:FF:FF",
141
   DNIE_CHIP_SHORTNAME,
142
   SC_CARD_TYPE_DNIE_TERMINATED,
143
   0,
144
   NULL},
145
  {NULL, NULL, NULL, 0, 0, NULL}
146
};
147
148
/**
149
 * Messages used on user consent procedures
150
 */
151
const char *user_consent_title="Signature Requested";
152
153
#ifdef linux
154
const char *user_consent_message="Está a punto de realizar una firma electrónica con su clave de FIRMA del DNI electrónico. ¿Desea permitir esta operación?";
155
#else
156
const char *user_consent_message="Esta a punto de realizar una firma digital\ncon su clave de FIRMA del DNI electronico.\nDesea permitir esta operacion?";
157
#endif
158
159
#ifdef ENABLE_DNIE_UI
160
/**
161
 * Messages used on pinentry protocol
162
 */
163
char *user_consent_msgs[] = { "SETTITLE", "SETDESC", "CONFIRM", "BYE" };
164
165
#if !defined(__APPLE__) && !defined(_WIN32)
166
/**
167
 * Do fgets() without interruptions.
168
 *
169
 * Retry the operation if it is interrupted, such as with receiving an alarm.
170
 *
171
 * @param s Buffer receiving the data
172
 * @param size Size of the buffer
173
 * @param stream Stream to read
174
 * @return s on success, NULL on error
175
 */
176
static char *nointr_fgets(char *s, int size, FILE *stream)
177
{
178
  while (fgets(s, size, stream) == NULL) {
179
    if (feof(stream) || errno != EINTR)
180
      return NULL;
181
  }
182
  return s;
183
}
184
#endif
185
186
/**
187
 * Ask for user consent.
188
 *
189
 * Check for user consent configuration,
190
 * Invoke proper gui app and check result
191
 *
192
 * @param card pointer to sc_card structure
193
 * @param title Text to appear in the window header
194
 * @param text Message to show to the user
195
 * @return SC_SUCCESS on user consent OK , else error code
196
 */
197
int dnie_ask_user_consent(struct sc_card * card, const char *title, const char *message)
198
{
199
#ifdef __APPLE__
200
  CFOptionFlags result;  /* result code from the message box */
201
  /* convert the strings from char* to CFStringRef */
202
  CFStringRef header_ref; /* to store title */
203
  CFStringRef message_ref; /* to store message */
204
#endif
205
#if !defined(__APPLE__) && !defined(_WIN32)
206
  pid_t pid;
207
  FILE *fin=NULL;
208
  FILE *fout=NULL;  /* to handle pipes as streams */
209
  struct stat st_file;  /* to verify that executable exists */
210
  int srv_send[2];  /* to send data from server to client */
211
  int srv_recv[2];  /* to receive data from client to server */
212
  char outbuf[1024];  /* to compose and send messages */
213
  char buf[1024];   /* to store client responses */
214
  int n = 0;    /* to iterate on to-be-sent messages */
215
#endif
216
  int res = SC_ERROR_INTERNAL;  /* by default error :-( */
217
  char *msg = NULL; /* to mark errors */
218
219
  if ((card == NULL) || (card->ctx == NULL))
220
    return SC_ERROR_INVALID_ARGUMENTS;
221
  LOG_FUNC_CALLED(card->ctx);
222
223
  if ((title==NULL) || (message==NULL))
224
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
225
226
  if (GET_DNIE_UI_CTX(card).user_consent_enabled == 0
227
      || card->ctx->flags & SC_CTX_FLAG_DISABLE_POPUPS) {
228
    sc_log(card->ctx,
229
           "User Consent or popups are disabled in configuration file");
230
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
231
  }
232
#ifdef _WIN32
233
  /* in Windows, do not use pinentry, but MessageBox system call */
234
  res = MessageBox (
235
    NULL,
236
    TEXT(message),
237
    TEXT(title),
238
    MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2 | MB_APPLMODAL
239
    );
240
  if ( res == IDOK )
241
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
242
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ALLOWED);
243
#elif __APPLE__
244
  /* Also in Mac OSX use native functions */
245
246
  /* convert the strings from char* to CFStringRef */
247
  header_ref = CFStringCreateWithCString( NULL, title, strlen(title) );
248
  message_ref = CFStringCreateWithCString( NULL,message, strlen(message) );
249
250
  /* Display user notification alert */
251
  CFUserNotificationDisplayAlert(
252
    0, /* no timeout */
253
    kCFUserNotificationNoteAlertLevel,  /* Alert level */
254
    NULL, /* IconURL, use default, you can change */
255
      /* it depending message_type flags */
256
    NULL, /* SoundURL (not used) */
257
    NULL, /* localization of strings */
258
    header_ref, /* header. Cannot be null */
259
    message_ref,  /* message text */
260
    CFSTR("Cancel"), /* default ( "OK" if null) button text */
261
    CFSTR("OK"), /* second button title */
262
                NULL, /* third button title, null--> no other button */
263
    &result /* response flags */
264
  );
265
266
  /* Clean up the strings */
267
  CFRelease( header_ref );
268
        CFRelease( message_ref );
269
  /* Return 0 only if "OK" is selected */
270
  if( result == kCFUserNotificationAlternateResponse )
271
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
272
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ALLOWED);
273
#else
274
  /* just a simple bidirectional pipe+fork+exec implementation */
275
  /* In a pipe, xx[0] is for reading, xx[1] is for writing */
276
  if (pipe(srv_send) < 0) {
277
    msg = "pipe(srv_send)";
278
    goto do_error;
279
  }
280
  if (pipe(srv_recv) < 0) {
281
    msg = "pipe(srv_recv)";
282
    goto do_error;
283
  }
284
  pid = fork();
285
  switch (pid) {
286
  case -1:    /* error  */
287
    msg = "fork()";
288
    goto do_error;
289
  case 0:   /* child  */
290
    /* make our pipes, our new stdin & stderr, closing older ones */
291
    dup2(srv_send[0], STDIN_FILENO);  /* map srv send for input */
292
    dup2(srv_recv[1], STDOUT_FILENO); /* map srv_recv for output */
293
    /* once dup2'd pipes are no longer needed on client; so close */
294
    close(srv_send[0]);
295
    close(srv_send[1]);
296
    close(srv_recv[0]);
297
    close(srv_recv[1]);
298
    /* check that user_consent_app exists. TODO: check if executable */
299
    res = stat(GET_DNIE_UI_CTX(card).user_consent_app, &st_file);
300
    if (res != 0) {
301
      sc_log(card->ctx, "Invalid pinentry application: %s\n",
302
          GET_DNIE_UI_CTX(card).user_consent_app);
303
    } else {
304
      /* call exec() with proper user_consent_app from configuration */
305
      /* if ok should never return */
306
      execlp(GET_DNIE_UI_CTX(card).user_consent_app, GET_DNIE_UI_CTX(card).user_consent_app, (char *)NULL);
307
      sc_log(card->ctx, "execlp() error");
308
    }
309
    abort();
310
  default:    /* parent */
311
    /* Close the pipe ends that the child uses to read from / write to
312
     * so when we close the others, an EOF will be transmitted properly.
313
     */
314
    close(srv_send[0]);
315
    close(srv_recv[1]);
316
    /* use iostreams to take care on newlines and text based data */
317
    fin = fdopen(srv_recv[0], "r");
318
    if (fin == NULL) {
319
      msg = "fdopen(in)";
320
      goto do_error;
321
    }
322
    fout = fdopen(srv_send[1], "w");
323
    if (fout == NULL) {
324
      msg = "fdopen(out)";
325
      goto do_error;
326
    }
327
    /* read and ignore first line */
328
    if (nointr_fgets(buf, sizeof(buf), fin) == NULL) {
329
      res = SC_ERROR_INTERNAL;
330
      msg = "nointr_fgets() Unexpected IOError/EOF";
331
      goto do_error;
332
    }
333
    for (n = 0; n<4; n++) {
334
      char *pt;
335
      if (n==0) snprintf(outbuf, sizeof outbuf,"%s %s\n",user_consent_msgs[0],title);
336
      else if (n==1) snprintf(outbuf, sizeof outbuf,"%s %s\n",user_consent_msgs[1],message);
337
      else snprintf(outbuf, sizeof outbuf,"%s\n",user_consent_msgs[n]);
338
      /* send message */
339
      fputs(outbuf, fout);
340
      fflush(fout);
341
      /* get response */
342
      pt=nointr_fgets(buf, sizeof(buf), fin);
343
      if (pt==NULL) {
344
        res = SC_ERROR_INTERNAL;
345
        msg = "nointr_fgets() Unexpected IOError/EOF";
346
        goto do_error;
347
      }
348
      if (strstr(buf, "OK") == NULL) {
349
        res = SC_ERROR_NOT_ALLOWED;
350
        msg = "fail/cancel";
351
        goto do_error;
352
      }
353
    }
354
  }     /* switch */
355
  /* arriving here means signature has been accepted by user */
356
  res = SC_SUCCESS;
357
  msg = NULL;
358
do_error:
359
  /* close out channel to force client receive EOF and also die */
360
  if (fout != NULL) fclose(fout);
361
  if (fin != NULL) fclose(fin);
362
#endif
363
  if (msg != NULL)
364
    sc_log(card->ctx, "%s", msg);
365
  LOG_FUNC_RETURN(card->ctx, res);
366
}
367
368
#endif        /* ENABLE_DNIE_UI */
369
370
/**
371
 * DNIe specific card driver operations
372
 */
373
static struct sc_card_operations dnie_ops;
374
375
/**
376
 * Local copy of iso7816 card driver operations
377
 */
378
static struct sc_card_operations *iso_ops = NULL;
379
380
/**
381
 * Module definition for OpenDNIe card driver
382
 */
383
static sc_card_driver_t dnie_driver = {
384
  DNIE_CHIP_NAME, /**< Full name for DNIe card driver */
385
  DNIE_CHIP_SHORTNAME, /**< Short name for DNIe card driver */
386
  &dnie_ops,  /**< pointer to dnie_ops (DNIe card driver operations) */
387
  dnie_atrs,  /**< List of card ATR's handled by this driver */
388
  0,    /**< (natrs) number of atr's to check for this driver */
389
  NULL    /**< (dll) Card driver module (on DNIe is null) */
390
};
391
392
/************************** card-dnie.c internal functions ****************/
393
394
/**
395
 * Parse configuration file for dnie parameters.
396
 *
397
 * DNIe card driver has two main parameters:
398
 * - The name of the user consent Application to be used in Linux. This application should be any of pinentry-xxx family
399
 * - A flag to indicate if user consent is to be used in this driver. If false, the user won't be prompted for confirmation on signature operations
400
 *
401
 * @See ../../etc/opensc.conf for details
402
 * @param card Pointer to card structure
403
 * @param ui_context Pointer to ui_context structure to store data into
404
 * @return SC_SUCCESS (should return no errors)
405
 *
406
 * TODO: Code should be revised in order to store user consent info
407
 * in a card-independent way at configuration file
408
 */
409
#ifdef ENABLE_DNIE_UI
410
static int dnie_get_environment(
411
  sc_card_t * card,
412
  ui_context_t * ui_context)
413
{
414
  int i;
415
  scconf_block **blocks, *blk;
416
  sc_context_t *ctx;
417
  /* set default values */
418
  ui_context->user_consent_app = USER_CONSENT_CMD;
419
  ui_context->user_consent_enabled = 1;
420
  /* look for sc block in opensc.conf */
421
  ctx = card->ctx;
422
  for (i = 0; ctx->conf_blocks[i]; i++) {
423
    blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
424
        "card_driver", "dnie");
425
    if (!blocks)
426
      continue;
427
    blk = blocks[0];
428
    free(blocks);
429
    if (blk == NULL)
430
      continue;
431
    /* fill private data with configuration parameters */
432
    ui_context->user_consent_app =  /* def user consent app is "pinentry" */
433
        (char *)scconf_get_str(blk, "user_consent_app",
434
             USER_CONSENT_CMD);
435
    ui_context->user_consent_enabled =  /* user consent is enabled by default */
436
        scconf_get_bool(blk, "user_consent_enabled", 1);
437
  }
438
  return SC_SUCCESS;
439
}
440
#endif
441
442
/************************** cardctl defined operations *******************/
443
444
/**
445
 * Generate a public/private key pair.
446
 *
447
 * Manual says that generate_keys() is a reserved operation; that is:
448
 * only can be done at DGP offices. But several authors talk about
449
 * this operation is available also outside. So need to test :-)
450
 * Notice that write operations are not supported, so we can't use
451
 * created keys to generate and store new certificates into the card.
452
 * TODO: copy code from card-jcop.c::jcop_generate_keys()
453
 * @param card pointer to card info data
454
 * @param data where to store function results
455
 * @return SC_SUCCESS if ok, else error code
456
 */
457
static int dnie_generate_key(sc_card_t * card, void *data)
458
0
{
459
0
  int result = SC_ERROR_NOT_SUPPORTED;
460
0
  if ((card == NULL) || (data == NULL))
461
0
    return SC_ERROR_INVALID_ARGUMENTS;
462
0
  LOG_FUNC_CALLED(card->ctx);
463
  /* TODO: write dnie_generate_key() */
464
0
  LOG_FUNC_RETURN(card->ctx, result);
465
0
}
466
467
/**
468
 * Analyze a buffer looking for provided data pattern.
469
 *
470
 * Commodity function for dnie_get_info() that searches a byte array
471
 * in provided buffer
472
 *
473
 * @param card pointer to card info data
474
 * @param pat data pattern to find in buffer
475
 * @param buf where to look for pattern
476
 * @param len buffer length
477
 * @return retrieved value or NULL if pattern not found
478
 * @see dnie_get_info()
479
 */
480
static char *findPattern(u8 *pat, u8 *buf, size_t len)
481
0
{
482
0
  char *res = NULL;
483
0
  u8 *from = buf;
484
0
  int size = 0;
485
  /* Locate pattern. Assume pattern length=6 */
486
0
  for ( from = buf; from < buf+len-6; from++) {
487
0
    if (memcmp(from,pat,6) == 0 ) goto data_found;
488
0
  }
489
  /* arriving here means pattern not found */
490
0
  return NULL;
491
492
0
data_found:
493
  /* assume length is less than 128 bytes, so is coded in 1 byte */
494
0
  size = 0x000000ff & (int) *(from+6);
495
0
  if ( size == 0 ) return NULL; /* empty data */
496
0
  res = calloc( size+1, sizeof(char) );
497
0
  if ( res == NULL) return NULL; /* calloc() error */
498
0
  memcpy(res,from+7,size);
499
0
  return res;
500
0
}
501
502
/**
503
 * Retrieve name, surname, and DNIe number.
504
 *
505
 * This is done by mean of reading and parsing CDF file
506
 * at address 3F0050156004
507
 * No need to enter pin nor use Secure Channel
508
 *
509
 * Notice that this is done by mean of a dirty trick: instead
510
 * of parsing ASN1 data on EF(CDF),
511
 * we look for desired OID patterns in binary array
512
 *
513
 * @param card pointer to card info data
514
 * @param data where to store function results (number,name,surname,idesp,version)
515
 * @return SC_SUCCESS if ok, else error code
516
 */
517
static int dnie_get_info(sc_card_t * card, char *data[])
518
0
{
519
0
  sc_file_t *file = NULL;
520
0
        sc_path_t path;
521
0
        u8 *buffer = NULL;
522
0
  size_t bufferlen = 0;
523
0
  char *msg = NULL;
524
0
  u8 SerialNumber [] = { 0x06, 0x03, 0x55, 0x04, 0x05, 0x13 };
525
0
  u8 Name [] = { 0x06, 0x03, 0x55, 0x04, 0x04, 0x0C };
526
0
  u8 GivenName [] = { 0x06, 0x03, 0x55, 0x04, 0x2A, 0x0C };
527
0
  int res = SC_ERROR_NOT_SUPPORTED;
528
529
0
        if ((card == NULL) || (data == NULL))
530
0
                return SC_ERROR_INVALID_ARGUMENTS;
531
0
        LOG_FUNC_CALLED(card->ctx);
532
533
  /* phase 1: get DNIe number, Name and GivenName */
534
535
  /* read EF(CDF) at 3F0050156004 */
536
0
  sc_format_path("3F0050156004", &path);
537
0
  res = dnie_read_file(card, &path, &file, &buffer, &bufferlen);
538
0
  if (res != SC_SUCCESS) {
539
0
    msg = "Cannot read EF(CDF)";
540
0
    goto get_info_end;
541
0
  }
542
  /* locate OID 2.5.4.5 (SerialNumber) - DNIe number*/
543
0
  data[0]= findPattern(SerialNumber,buffer,bufferlen);
544
  /* locate OID 2.5.4.4 (Name)         - Apellidos */
545
0
  data[1]= findPattern(Name,buffer,bufferlen);
546
  /* locate OID 2.5.4.42 (GivenName)   - Nombre */
547
0
  data[2]= findPattern(GivenName,buffer,bufferlen);
548
0
  if ( ! data[0] || !data[1] || !data[2] ) {
549
0
    res = SC_ERROR_INVALID_DATA;
550
0
    msg = "Cannot retrieve info from EF(CDF)";
551
0
    goto get_info_end;
552
0
        }
553
554
  /* phase 2: get IDESP */
555
0
  sc_format_path("3F000006", &path);
556
0
  sc_file_free(file);
557
0
  file = NULL;
558
0
  if (buffer) {
559
0
    free(buffer);
560
0
    buffer=NULL;
561
0
    bufferlen=0;
562
0
  }
563
0
  res = dnie_read_file(card, &path, &file, &buffer, &bufferlen);
564
0
  if (res != SC_SUCCESS) {
565
0
    data[3]=NULL;
566
0
    goto get_info_ph3;
567
0
  }
568
0
  data[3]=calloc(bufferlen+1,sizeof(char));
569
0
  if ( !data[3] ) {
570
0
    msg = "Cannot allocate memory for IDESP data";
571
0
    res = SC_ERROR_OUT_OF_MEMORY;
572
0
    goto get_info_end;
573
0
  }
574
0
  memcpy(data[3],buffer,bufferlen);
575
576
0
get_info_ph3:
577
  /* phase 3: get DNIe software version */
578
0
  sc_format_path("3F002F03", &path);
579
0
  sc_file_free(file);
580
0
  file = NULL;
581
0
  if (buffer) {
582
0
    free(buffer);
583
0
    buffer=NULL;
584
0
    bufferlen=0;
585
0
  }
586
  /*
587
  * Some old DNIe cards seems not to include SW version file,
588
  * so let this code fail without notice
589
  */
590
0
  res = dnie_read_file(card, &path, &file, &buffer, &bufferlen);
591
0
  if (res != SC_SUCCESS) {
592
0
    msg = "Cannot read DNIe Version EF";
593
0
    data[4]=NULL;
594
0
    res = SC_SUCCESS; /* let function return successfully */
595
0
    goto get_info_end;
596
0
  }
597
0
  data[4]=calloc(bufferlen+1,sizeof(char));
598
0
  if ( !data[4] ) {
599
0
    msg = "Cannot allocate memory for DNIe Version data";
600
0
    res = SC_ERROR_OUT_OF_MEMORY;
601
0
    goto get_info_end;
602
0
  }
603
0
  memcpy(data[4],buffer,bufferlen);
604
605
  /* arriving here means ok */
606
0
  res = SC_SUCCESS;
607
0
  msg = NULL;
608
609
0
get_info_end:
610
0
  sc_file_free(file);
611
0
  file = NULL;
612
0
  if (buffer) {
613
0
    free(buffer);
614
0
    buffer=NULL;
615
0
    bufferlen=0;
616
0
  }
617
0
  if (msg)
618
0
    sc_log(card->ctx, "%s", msg);
619
0
        LOG_FUNC_RETURN(card->ctx, res);
620
0
}
621
622
/**
623
 * Retrieve serial number (7 bytes) from card.
624
 *
625
 * This is done by mean of an special APDU command described
626
 * in the DNIe Reference Manual
627
 *
628
 * @param card pointer to card description
629
 * @param serial where to store data retrieved
630
 * @return SC_SUCCESS if ok; else error code
631
 */
632
static int dnie_get_serialnr(sc_card_t * card, sc_serial_number_t * serial)
633
0
{
634
0
  int result;
635
0
  sc_apdu_t apdu;
636
0
  u8 rbuf[MAX_RESP_BUFFER_SIZE];
637
0
  if ((card == NULL) || (card->ctx == NULL) || (serial == NULL))
638
0
    return SC_ERROR_INVALID_ARGUMENTS;
639
640
0
  LOG_FUNC_CALLED(card->ctx);
641
0
  if (card->type != SC_CARD_TYPE_DNIE_USER)
642
0
    return SC_ERROR_NOT_SUPPORTED;
643
  /* if serial number is cached, use it */
644
0
  if (card->serialnr.len) {
645
0
    memcpy(serial, &card->serialnr, sizeof(*serial));
646
0
    sc_log_hex(card->ctx, "Serial Number (cached)", serial->value, serial->len);
647
0
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
648
0
  }
649
  /* not cached, retrieve it by mean of an APDU */
650
  /* official driver read 0x11 bytes, but only uses 7. Manual says just 7 (for le) */
651
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xb8, 0x00, 0x00, 0x07, 0,
652
0
          rbuf, sizeof(rbuf), NULL, 0);
653
0
  apdu.cla = 0x90;  /* proprietary cmd */
654
  /* send apdu */
655
0
  result = sc_transmit_apdu(card, &apdu);
656
0
  if (result != SC_SUCCESS) {
657
0
    LOG_TEST_RET(card->ctx, result, "APDU transmit failed");
658
0
  }
659
0
  if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00)
660
0
    return SC_ERROR_INTERNAL;
661
  /* cache serial number */
662
0
  memcpy(card->serialnr.value, apdu.resp, 7 * sizeof(u8));
663
0
  card->serialnr.len = 7 * sizeof(u8);
664
  /* TODO: fill Issuer Identification Number data with proper (ATR?) info */
665
  /*
666
     card->serialnr.iin.mii=;
667
     card->serialnr.iin.country=;
668
     card->serialnr.iin.issuer_id=;
669
   */
670
  /* copy and return serial number */
671
0
  memcpy(serial, &card->serialnr, sizeof(*serial));
672
0
  sc_log_hex(card->ctx, "Serial Number (apdu)", serial->value, serial->len);
673
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
674
0
}
675
676
/**
677
 * Remove the binary data in the cache.
678
 *
679
 * It frees memory if allocated and resets pointer and length.
680
 * It only touches the private binary cache variables, not the sc_card information.
681
 *
682
 * @param data pointer to dnie private data
683
 */
684
static void dnie_clear_cache(dnie_private_data_t * data)
685
84
{
686
84
  if (data == NULL) return;
687
46
  if (data->cache != NULL)
688
0
    free(data->cache);
689
46
  data->cache = NULL;
690
46
  data->cachelen = 0;
691
46
}
692
693
/**
694
 * Set sc_card flags according to DNIe requirements.
695
 *
696
 * Used in card initialization.
697
 *
698
 * @param card pointer to card data
699
 */
700
static void init_flags(struct sc_card *card)
701
45
{
702
45
  unsigned long algoflags;
703
  /* set up flags according documentation */
704
45
  card->name = DNIE_CHIP_SHORTNAME;
705
45
  card->cla = 0x00; /* default APDU class (interindustry) */
706
45
  card->caps |= SC_CARD_CAP_RNG; /* we have a random number generator */
707
45
  card->max_send_size = (255 - 12); /* manual says 255, but we need 12 extra bytes when encoding */
708
45
  card->max_recv_size = 255;
709
710
  /* RSA Support with PKCS1.5 padding */
711
45
  algoflags = SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_PAD_PKCS1;
712
45
  _sc_card_add_rsa_alg(card, 1024, algoflags, 0);
713
45
  _sc_card_add_rsa_alg(card, 1920, algoflags, 0);
714
45
  _sc_card_add_rsa_alg(card, 2048, algoflags, 0);
715
45
}
716
717
/**************************** sc_card_operations **********************/
718
719
/* Generic operations */
720
721
/**
722
 * Check if provided card can be handled by OpenDNIe.
723
 *
724
 * Called in sc_connect_card().  Must return 1, if the current
725
 * card can be handled with this driver, or 0 otherwise.  ATR
726
 * field of the sc_card struct is filled in before calling
727
 * this function.
728
 * do not declare static, as used by pkcs15-dnie module
729
 *
730
 * @param card Pointer to card structure
731
 * @return on card matching 0 if not match; negative return means error
732
 */
733
int dnie_match_card(struct sc_card *card)
734
6.26k
{
735
6.26k
  int result = 0;
736
6.26k
  int matched = -1;
737
6.26k
  LOG_FUNC_CALLED(card->ctx);
738
6.26k
  matched = _sc_match_atr(card, dnie_atrs, &card->type);
739
6.26k
  result = (matched >= 0) ? 1 : 0;
740
6.26k
  LOG_FUNC_RETURN(card->ctx, result);
741
6.26k
}
742
743
static int dnie_sm_free_wrapped_apdu(struct sc_card *card,
744
    struct sc_apdu *plain, struct sc_apdu **sm_apdu)
745
0
{
746
0
  struct sc_context *ctx = card->ctx;
747
0
  cwa_provider_t *provider = NULL;
748
0
  int rv = SC_SUCCESS;
749
750
0
  LOG_FUNC_CALLED(ctx);
751
0
  provider = GET_DNIE_PRIV_DATA(card)->cwa_provider;
752
0
  if (!sm_apdu)
753
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
754
0
  if (!(*sm_apdu))
755
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
756
757
0
  if ((*sm_apdu) != plain) {
758
0
    rv = cwa_decode_response(card, provider, *sm_apdu);
759
0
    if (plain && rv == SC_SUCCESS) {
760
0
      if (plain->resp) {
761
        /* copy the response into the original resp buffer */
762
0
        if ((*sm_apdu)->resplen <= plain->resplen) {
763
0
          memcpy(plain->resp, (*sm_apdu)->resp, (*sm_apdu)->resplen);
764
0
          plain->resplen = (*sm_apdu)->resplen;
765
0
        } else {
766
0
          sc_log(card->ctx, "Invalid initial length,"
767
0
              " needed %"SC_FORMAT_LEN_SIZE_T"u bytes"
768
0
              " but has %"SC_FORMAT_LEN_SIZE_T"u",
769
0
              (*sm_apdu)->resplen, plain->resplen);
770
0
          rv = SC_ERROR_BUFFER_TOO_SMALL;
771
0
        }
772
0
      }
773
0
      plain->sw1 = (*sm_apdu)->sw1;
774
0
      plain->sw2 = (*sm_apdu)->sw2;
775
0
    }
776
0
    if (plain == NULL || (*sm_apdu)->data != plain->data)
777
0
      free((unsigned char *) (*sm_apdu)->data);
778
0
    if (plain == NULL || (*sm_apdu)->resp != plain->resp)
779
0
      free((*sm_apdu)->resp);
780
0
    free(*sm_apdu);
781
0
  }
782
0
  *sm_apdu = NULL;
783
784
0
  LOG_FUNC_RETURN(ctx, rv);
785
0
}
786
787
static int dnie_sm_get_wrapped_apdu(struct sc_card *card,
788
    struct sc_apdu *plain, struct sc_apdu **sm_apdu)
789
0
{
790
0
  struct sc_context *ctx = card->ctx;
791
0
  cwa_provider_t *provider = NULL;
792
0
  int rv = SC_SUCCESS;
793
794
0
  LOG_FUNC_CALLED(ctx);
795
0
  if (!plain || !sm_apdu)
796
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
797
798
0
  provider = GET_DNIE_PRIV_DATA(card)->cwa_provider;
799
800
0
  if (((plain->cla & 0x0C) == 0) && (plain->ins != 0xC0)) {
801
0
    *sm_apdu = calloc(1, sizeof(struct sc_apdu));
802
0
    if (!(*sm_apdu))
803
0
      return SC_ERROR_OUT_OF_MEMORY;
804
805
0
    rv = cwa_encode_apdu(card, provider, plain, *sm_apdu);
806
807
0
    if (rv != SC_SUCCESS) {
808
0
      dnie_sm_free_wrapped_apdu(card, plain, sm_apdu);
809
0
    }
810
0
  } else
811
0
    *sm_apdu = plain;
812
813
0
  LOG_FUNC_RETURN(ctx, rv);
814
0
}
815
816
/**
817
 * OpenDNIe card structures initialization.
818
 *
819
 * Called when ATR of the inserted card matches an entry in ATR
820
 * table.  May return SC_ERROR_INVALID_CARD to indicate that
821
 * the card cannot be handled with this driver.
822
 *
823
 * @param card Pointer to card structure
824
 * @return SC_SUCCES if ok; else error code
825
 */
826
static int dnie_init(struct sc_card *card)
827
68
{
828
68
  int res = SC_SUCCESS;
829
68
  sc_context_t *ctx = card->ctx;
830
68
  cwa_provider_t *provider = NULL;
831
832
68
  LOG_FUNC_CALLED(ctx);
833
834
  /* if recognized as terminated DNIe card, return error */
835
68
  if (card->type == SC_CARD_TYPE_DNIE_TERMINATED)
836
68
      LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "DNIe card is terminated.");
837
838
  /* create and initialize cwa-dnie provider*/
839
67
  provider = dnie_get_cwa_provider(card);
840
67
  if (!provider)
841
67
      LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "Error initializing cwa-dnie provider");
842
843
  /** Secure messaging initialization section **/
844
67
  memset(&(card->sm_ctx), 0, sizeof(sm_context_t));
845
67
  card->sm_ctx.ops.get_sm_apdu = dnie_sm_get_wrapped_apdu;
846
67
  card->sm_ctx.ops.free_sm_apdu = dnie_sm_free_wrapped_apdu;
847
67
  card->sm_ctx.sm_mode = SM_MODE_NONE;
848
849
67
  res = cwa_create_secure_channel(card, provider, CWA_SM_OFF);
850
67
  if (res < 0)
851
22
    free(provider);
852
67
  LOG_TEST_RET(card->ctx, res, "Failure resetting CWA secure channel.");
853
854
  /* initialize private data */
855
45
  card->drv_data = calloc(1, sizeof(dnie_private_data_t));
856
45
  if (card->drv_data == NULL) {
857
0
    free(provider);
858
0
      LOG_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "Could not allocate DNIe private data.");
859
0
  }
860
861
#ifdef ENABLE_DNIE_UI
862
  /* read environment from configuration file */
863
  res = dnie_get_environment(card, &(GET_DNIE_UI_CTX(card)));
864
  if (res != SC_SUCCESS) {
865
    free(card->drv_data);
866
    free(provider);
867
    LOG_TEST_RET(card->ctx, res, "Failure reading DNIe environment.");
868
  }
869
#endif
870
871
45
  init_flags(card);
872
873
45
  GET_DNIE_PRIV_DATA(card)->cwa_provider = provider;
874
875
45
  LOG_FUNC_RETURN(card->ctx, res);
876
45
}
877
878
/**
879
 * De-initialization routine.
880
 *
881
 * Called when the card object is being freed.  finish() has to
882
 * deallocate all possible private data.
883
 *
884
 * @param card Pointer to card driver data structure
885
 * @return SC_SUCCESS if ok; else error code
886
 */
887
static int dnie_finish(struct sc_card *card)
888
45
{
889
45
  int result = SC_SUCCESS;
890
45
  LOG_FUNC_CALLED(card->ctx);
891
45
  dnie_clear_cache(GET_DNIE_PRIV_DATA(card));
892
  /* disable sm channel if established */
893
45
  result = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_OFF);
894
45
  free(GET_DNIE_PRIV_DATA(card)->cwa_provider);
895
45
  free(card->drv_data);
896
45
  LOG_FUNC_RETURN(card->ctx, result);
897
45
}
898
899
/* ISO 7816-4 functions */
900
901
/**
902
 * Check whether data are compressed.
903
 *
904
 * @param card pointer to sc_card_t structure
905
 * @param from buffer to get data from
906
 * @param len buffer length
907
 * @return 1 if data are compressed, 0 otherwise; len points to expected length of decompressed data
908
 */
909
910
static int dnie_is_compressed(sc_card_t * card, u8 * from, size_t len)
911
0
{
912
0
#ifdef ENABLE_ZLIB
913
0
  size_t uncompressed = 0L;
914
0
  size_t compressed = 0L;
915
916
0
  if (!card || !card->ctx || !from || !len)
917
0
    return 0;
918
0
  LOG_FUNC_CALLED(card->ctx);
919
920
  /* if data size not enough for compression header assume uncompressed */
921
0
  if (len < 8)
922
0
    goto compress_exit;
923
  /* evaluate compressed an uncompressed sizes (little endian format) */
924
0
  uncompressed = lebytes2ulong(from);
925
0
  compressed = lebytes2ulong(from + 4);
926
  /* if compressed size doesn't match data length assume not compressed */
927
0
  if (compressed != len - 8)
928
0
    goto compress_exit;
929
  /* if compressed size greater than uncompressed, assume uncompressed data */
930
0
  if (uncompressed < compressed)
931
0
    goto compress_exit;
932
  /* Do not try to allocate insane size if we receive bogus data */
933
0
  if (uncompressed > MAX_FILE_SIZE)
934
0
    goto compress_exit;
935
936
0
  sc_log(card->ctx, "Data seems to be compressed.");
937
0
  return 1;
938
0
compress_exit:
939
0
#endif
940
941
0
  sc_log(card->ctx, "Data not compressed.");
942
0
  return 0;
943
0
}
944
945
/**
946
 * Fill file cache for read_binary() operation.
947
 *
948
 * Fill a temporary buffer by mean of consecutive calls to read_binary()
949
 * until card sends eof
950
 *
951
 * DNIe card stores user certificates in compressed format. so we need
952
 * some way to detect and uncompress on-the-fly compressed files, to
953
 * let read_binary() work transparently.
954
 * This is the main goal of this routine: create an in-memory buffer
955
 * for read_binary operation, filling this buffer on first read_binary()
956
 * call, and uncompress data if compression detected. Further
957
 * read_binary() calls then make use of cached data, instead
958
 * of accessing the card
959
 *
960
 * @param card Pointer to card structure
961
 * @return SC_SUCCESS if OK; else error code
962
 */
963
static int dnie_fill_cache(sc_card_t * card,unsigned long *flags)
964
0
{
965
0
  u8 tmp[MAX_RESP_BUFFER_SIZE];
966
0
  sc_apdu_t apdu;
967
0
  size_t count = 0;
968
0
  size_t len = 0;
969
0
  u8 *buffer = NULL;
970
0
  u8 *p;
971
0
  sc_context_t *ctx = NULL;
972
973
0
  if (!card || !card->ctx)
974
0
    return SC_ERROR_INVALID_ARGUMENTS;
975
0
  ctx = card->ctx;
976
977
0
  LOG_FUNC_CALLED(ctx);
978
979
  /* mark cache empty */
980
0
  dnie_clear_cache(GET_DNIE_PRIV_DATA(card));
981
982
  /* initialize apdu */
983
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, 0x00, 0x00);
984
985
  /* try to read_binary while data available but never long than 32767 */
986
0
  count = card->max_recv_size;
987
0
  for (len = 0; len < 0x7fff;) {
988
0
    int r = SC_SUCCESS;
989
    /* fill apdu */
990
0
    apdu.p1 = 0xff & (len >> 8);
991
0
    apdu.p2 = 0xff & len;
992
0
    apdu.le = count;
993
0
    apdu.resplen = MAX_RESP_BUFFER_SIZE;
994
0
    apdu.resp = tmp;
995
    /* transmit apdu */
996
0
    r = sc_transmit_apdu(card, &apdu);
997
0
    if (r != SC_SUCCESS) {
998
0
      free(buffer);
999
0
      if (apdu.resp != tmp)
1000
0
        free(apdu.resp);
1001
0
      sc_log(ctx, "read_binary() APDU transmit failed");
1002
0
      LOG_FUNC_RETURN(ctx, r);
1003
0
    }
1004
0
    if (apdu.resplen == 0) {
1005
      /* on no data received, check if requested len is longer than
1006
         available data in card. If so, ask just for remaining data */
1007
0
      r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1008
0
      if (r == SC_ERROR_WRONG_LENGTH) {
1009
0
        count = 0xff & apdu.sw2;
1010
0
        if (count != 0) {
1011
0
          if (apdu.resp != tmp)
1012
0
            free(apdu.resp);
1013
0
          continue; /* read again with correct size */
1014
0
        }
1015
0
        goto read_done; /* no more data to read */
1016
0
      }
1017
0
      if (r == SC_ERROR_INCORRECT_PARAMETERS)
1018
0
        goto read_done;
1019
0
      free(buffer);
1020
0
      if (apdu.resp != tmp)
1021
0
        free(apdu.resp);
1022
0
      LOG_FUNC_RETURN(ctx, r); /* arriving here means response error */
1023
0
    }
1024
    /* copy received data into buffer. realloc() if not enough space */
1025
0
    count = apdu.resplen;
1026
0
    p = realloc(buffer, len + count);
1027
0
    if (!p) {
1028
0
      free(buffer);
1029
0
      free((void *)apdu.data);
1030
0
      if (apdu.resp != tmp)
1031
0
        free(apdu.resp);
1032
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1033
0
    }
1034
0
    buffer = p;
1035
0
    memcpy(buffer + len, apdu.resp, count);
1036
0
    if (apdu.resp != tmp) {
1037
0
      free(apdu.resp);
1038
0
      apdu.resp = tmp;
1039
0
    }
1040
0
    len += count;
1041
0
    if (count != card->max_recv_size)
1042
0
      goto read_done;
1043
0
  }
1044
1045
0
 read_done:
1046
0
  free((void *)apdu.data);
1047
0
  if (apdu.resp != tmp)
1048
0
    free(apdu.resp);
1049
1050
0
  if (dnie_is_compressed(card, buffer, len)) {
1051
0
    if (flags)
1052
0
      *flags |= SC_FILE_FLAG_COMPRESSED_ZLIB;
1053
    /* Remove first 8 bytes with compression info*/
1054
0
    len -= 8;
1055
0
    p = malloc(len);
1056
0
    if (!p) {
1057
0
      free(buffer);
1058
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1059
0
    }
1060
0
    memcpy(p, buffer + 8, len);
1061
0
    free(buffer);
1062
0
    buffer = p;
1063
0
  }
1064
1065
1066
  /* ok: as final step, set correct cache data into dnie_priv structures */
1067
0
  GET_DNIE_PRIV_DATA(card)->cache = buffer;
1068
0
  GET_DNIE_PRIV_DATA(card)->cachelen = len;
1069
0
  sc_log(ctx,
1070
0
         "fill_cache() done. length '%"SC_FORMAT_LEN_SIZE_T"u' bytes",
1071
0
         len);
1072
0
  LOG_FUNC_RETURN(ctx, (int)len);
1073
0
}
1074
1075
/**
1076
 * OpenDNIe implementation of read_binary().
1077
 *
1078
 * Reads a binary stream from card by mean of READ BINARY iso command
1079
 * Creates and handle a cache to allow data uncompression
1080
 *
1081
 * @param card pointer to sc_card_t structure
1082
 * @param idx offset from card file to ask data for
1083
 * @param buf where to store read data. must be non null
1084
 * @param count number of bytes to read
1085
 * @param flags. not used
1086
 * @return number of bytes read, 0 on EOF, error code on error
1087
 */
1088
static int dnie_read_binary(struct sc_card *card,
1089
          unsigned int idx,
1090
          u8 * buf, size_t count, unsigned long *flags)
1091
0
{
1092
0
  size_t res = 0;
1093
0
  int rc;
1094
0
  sc_context_t *ctx = NULL;
1095
  /* preliminary checks */
1096
0
  if (!card || !card->ctx || !buf || (count <= 0))
1097
0
    return SC_ERROR_INVALID_ARGUMENTS;
1098
0
  ctx = card->ctx;
1099
1100
0
  LOG_FUNC_CALLED(ctx);
1101
0
  if (idx == 0 || GET_DNIE_PRIV_DATA(card)->cache == NULL) {
1102
    /* on first block or no cache, try to fill */
1103
0
    rc = dnie_fill_cache(card, flags);
1104
0
    if (rc < 0) {
1105
0
      sc_log(ctx, "Cannot fill cache. using iso_read_binary()");
1106
0
      return iso_ops->read_binary(card, idx, buf, count, flags);
1107
0
    }
1108
0
  }
1109
0
  if (idx >= GET_DNIE_PRIV_DATA(card)->cachelen)
1110
0
    return 0; /* at eof */
1111
0
  res = MIN(count, GET_DNIE_PRIV_DATA(card)->cachelen - idx);  /* eval how many bytes to read */
1112
0
  memcpy(buf, GET_DNIE_PRIV_DATA(card)->cache + idx, res);  /* copy data from buffer */
1113
0
  sc_log(ctx, "dnie_read_binary() '%zu' bytes", res);
1114
0
  LOG_FUNC_RETURN(ctx, (int)res);
1115
0
}
1116
1117
/**
1118
 * Send apdu to the card
1119
 *
1120
 * @param card pointer to sc_card_t structure
1121
 * @param path
1122
 * @param pathlen
1123
 * @param p1
1124
 * @param file_out
1125
 * @return result
1126
 */
1127
static int dnie_compose_and_send_apdu(sc_card_t *card, const u8 *path, size_t pathlen,
1128
          u8 p1, sc_file_t **file_out)
1129
112
{
1130
112
  int res = 0;
1131
112
  sc_apdu_t apdu;
1132
112
  u8 rbuf[MAX_RESP_BUFFER_SIZE];
1133
112
  sc_context_t *ctx = NULL;
1134
1135
112
  if (!card || !card->ctx)
1136
0
    return SC_ERROR_INVALID_ARGUMENTS;
1137
112
  ctx = card->ctx;
1138
1139
112
  LOG_FUNC_CALLED(ctx);
1140
1141
112
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, p1, 0,
1142
112
          sc_get_max_recv_size(card), pathlen,
1143
112
          rbuf, sizeof(rbuf), path, pathlen);
1144
112
  if (p1 == 3)
1145
0
    apdu.cse= SC_APDU_CASE_1;
1146
1147
112
  if (file_out == NULL)
1148
112
    apdu.cse = SC_APDU_CASE_4_SHORT;
1149
1150
112
  res = sc_transmit_apdu(card, &apdu);
1151
112
  if ((res != SC_SUCCESS) || (file_out == NULL))
1152
112
    LOG_TEST_RET(ctx, res, "SelectFile() APDU transmit failed");
1153
100
  if (file_out == NULL) {
1154
100
    if (apdu.sw1 == 0x61)
1155
0
      SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, 0);
1156
100
    SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,
1157
100
             sc_check_sw(card, apdu.sw1, apdu.sw2));
1158
100
  }
1159
1160
  /* analyze response. if FCI, try to parse */
1161
0
  res = sc_check_sw(card, apdu.sw1, apdu.sw2);
1162
0
  if (res != SC_SUCCESS) {
1163
0
    LOG_TEST_RET(ctx, res, "SelectFile() check_sw failed");
1164
0
  }
1165
0
  if ((apdu.resplen < 2) || (apdu.resp[0] == 0x00)) {
1166
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1167
0
  }
1168
1169
0
  if (file_out) {
1170
    /* finally process FCI response */
1171
0
    size_t len = apdu.resp[1];
1172
0
    sc_file_free(*file_out);
1173
0
    *file_out = sc_file_new();
1174
0
    if (*file_out == NULL) {
1175
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1176
0
    }
1177
0
    if (apdu.resplen - 2 < len || len < 1) {
1178
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1179
0
    }
1180
0
    res = card->ops->process_fci(card, *file_out, apdu.resp + 2, len);
1181
0
  }
1182
0
  LOG_FUNC_RETURN(ctx, res);
1183
0
}
1184
1185
/**
1186
 * OpenDNIe implementation of Select_File().
1187
 *
1188
 * Select_file: Does the equivalent of SELECT FILE command specified
1189
 *   in ISO7816-4. Stores information about the selected file to
1190
 *   <file>, if not NULL.
1191
 *
1192
 * SELECT file in DNIe is a bit tricky:
1193
 * - only handles some types:
1194
 * -- <strong>SC_PATH_TYPE_FILE_ID</strong> 2-byte long file ID
1195
 * -- <strong>SC_PATH_TYPE_DF_NAME</strong> named DF's
1196
 * -- <strong>SC_PATH_TYPE_PARENT</strong>  jump to parent DF of current EF/DF - undocumented in DNIe manual
1197
 * -- other file types are marked as unsupported
1198
 *
1199
 * - Also MF must be addressed by their Name, not their ID
1200
 * So some magic is needed:
1201
 * - split <strong>SC_PATH_TYPE_PATH</strong> into several calls to each 2-byte data file ID
1202
 * - Translate initial file id 3F00 to be DF name 'Master.File'
1203
 *
1204
 * Also, Response always handle a proprietary FCI info, so
1205
 * need to handle it manually via dnie_process_fci()
1206
 *
1207
 * @param card Pointer to Card Structure
1208
 * @param in_path Path ID to be selected
1209
 * @param file_out where to store fci information
1210
 * @return SC_SUCCESS if ok; else error code
1211
 */
1212
static int dnie_select_file(struct sc_card *card,
1213
          const struct sc_path *in_path,
1214
          struct sc_file **file_out)
1215
112
{
1216
112
  int res = SC_SUCCESS;
1217
112
  sc_context_t *ctx = NULL;
1218
112
  unsigned char tmp_path[sizeof(DNIE_MF_NAME)];
1219
112
  size_t reminder = 0;
1220
1221
112
  if (!card || !card->ctx || !in_path)
1222
0
    return SC_ERROR_INVALID_ARGUMENTS;
1223
112
  ctx = card->ctx;
1224
1225
112
  LOG_FUNC_CALLED(ctx);
1226
1227
112
  switch (in_path->type) {
1228
0
  case SC_PATH_TYPE_FILE_ID:
1229
    /* pathlen must be of len=2 */
1230
    /*
1231
     * gscriptor shows that DNIe also handles
1232
     * Select child DF (p1=1) and Select EF (p1=2),
1233
     * but we'll use P1=0 as general solution for all cases
1234
     *
1235
     * According iso7816-4 sect 7.1.1  pathlen==0 implies
1236
     * select MF, but this case is not supported by DNIe
1237
     */
1238
0
    if (in_path->len != 2)
1239
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1240
0
    sc_log_hex(ctx, "select_file(ID)", in_path->value, in_path->len);
1241
0
    res = dnie_compose_and_send_apdu(card, in_path->value, in_path->len, 0, file_out);
1242
0
    break;
1243
0
  case SC_PATH_TYPE_DF_NAME:
1244
0
    sc_log_hex(ctx, "select_file(NAME)", in_path->value, in_path->len);
1245
0
    res = dnie_compose_and_send_apdu(card, in_path->value, in_path->len, 4, file_out);
1246
0
    break;
1247
112
  case SC_PATH_TYPE_PATH:
1248
112
    if ((in_path->len == 0) || ((in_path->len & 1) != 0)) /* not divisible by 2 */
1249
112
      LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1250
1251
112
    sc_log_hex(ctx, "select_file(PATH): requested", in_path->value, in_path->len);
1252
1253
    /* convert to SC_PATH_TYPE_FILE_ID */
1254
112
    res = sc_lock(card); /* lock to ensure path traversal */
1255
112
    LOG_TEST_RET(ctx, res, "sc_lock() failed");
1256
112
    if (memcmp(in_path->value, "\x3F\x00", 2) == 0) {
1257
      /* if MF, use the name as path */
1258
112
      strcpy((char *)tmp_path, DNIE_MF_NAME);
1259
112
      sc_log_hex(ctx, "select_file(NAME): requested", tmp_path, sizeof(DNIE_MF_NAME) - 1);
1260
112
      res = dnie_compose_and_send_apdu(card, tmp_path, sizeof(DNIE_MF_NAME) - 1, 4, file_out);
1261
112
      if (res != SC_SUCCESS) {
1262
73
        sc_unlock(card);
1263
73
        LOG_TEST_RET(ctx, res, "select_file(NAME) failed");
1264
73
      }
1265
39
      tmp_path[2] = 0;
1266
39
      reminder = in_path->len - 2;
1267
39
    } else {
1268
0
      tmp_path[2] = 0;
1269
0
      reminder = in_path->len;
1270
0
    }
1271
39
    while (reminder > 0) {
1272
0
      tmp_path[0] = in_path->value[in_path->len - reminder];
1273
0
      tmp_path[1] = in_path->value[1 + in_path->len - reminder];
1274
0
      sc_log(ctx, "select_file(PATH): requested:%s ", sc_dump_hex(tmp_path, 2));
1275
0
      res = dnie_compose_and_send_apdu(card, tmp_path, 2, 0, file_out);
1276
0
      if (res != SC_SUCCESS) {
1277
0
        sc_unlock(card);
1278
0
        LOG_TEST_RET(ctx, res, "select_file(PATH) failed");
1279
0
      }
1280
0
      reminder -= 2;
1281
0
    }
1282
39
    sc_unlock(card);
1283
39
    break;
1284
0
  case SC_PATH_TYPE_FROM_CURRENT:
1285
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_NO_CARD_SUPPORT);
1286
0
    break;
1287
0
  case SC_PATH_TYPE_PARENT:
1288
    /* Hey!! Manual doesn't says anything on this, but
1289
     * gscriptor shows that this type is supported
1290
     */
1291
0
    sc_log(ctx, "select_file(PARENT)");
1292
    /* according iso7816-4 sect 7.1.1 shouldn't have any parameters */
1293
0
    if (in_path->len != 0)
1294
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1295
0
    res = dnie_compose_and_send_apdu(card, NULL, 0, 3, file_out);
1296
0
    break;
1297
0
  default:
1298
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1299
0
    break;
1300
112
  }
1301
1302
  /* as last step clear data cache and return */
1303
39
  dnie_clear_cache(GET_DNIE_PRIV_DATA(card));
1304
39
  LOG_FUNC_RETURN(ctx, res);
1305
39
}
1306
1307
/**
1308
 * OpenDNIe implementation of Get_Challenge() command.
1309
 *
1310
 * Get challenge: retrieve 8 random bytes for any further use
1311
 * (eg perform an external authenticate command)
1312
 *
1313
 * NOTE:
1314
 * Official driver redundantly sets SM before execute this command
1315
 * No reason to do it, as is needed to do SM handshake...
1316
 * Also: official driver reads in blocks of 20 bytes.
1317
 * Why? Manual and iso-7816-4 states that only 8 bytes
1318
 * are required... so we will obey Manual
1319
 *
1320
 * @param card Pointer to card Structure
1321
 * @param rnd Where to store challenge
1322
 * @param len requested challenge length
1323
 * @return SC_SUCCESS if OK; else error code
1324
 */
1325
1326
static int dnie_get_challenge(struct sc_card *card, u8 * rnd, size_t len)
1327
198
{
1328
  /* As DNIe cannot handle other data length than 0x08 and 0x14 */
1329
198
  u8 rbuf[8];
1330
198
  size_t out_len;
1331
198
  int r;
1332
1333
198
  LOG_FUNC_CALLED(card->ctx);
1334
1335
198
  r = iso_ops->get_challenge(card, rbuf, sizeof rbuf);
1336
198
  LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed");
1337
1338
164
  if (len < (size_t) r) {
1339
1
    out_len = len;
1340
163
  } else {
1341
163
    out_len = (size_t) r;
1342
163
  }
1343
164
  memcpy(rnd, rbuf, out_len);
1344
1345
164
  LOG_FUNC_RETURN(card->ctx, (int) out_len);
1346
164
}
1347
1348
/*
1349
 * ISO 7816-8 functions
1350
 */
1351
1352
/**
1353
 * OpenDNIe implementation of Logout() card_driver function.
1354
 *
1355
 *  Resets all access rights that were gained. Disable SM
1356
 *
1357
 * @param card Pointer to Card Structure
1358
 * @return SC_SUCCESS if OK; else error code
1359
 */
1360
static int dnie_logout(struct sc_card *card)
1361
0
{
1362
0
  int result = SC_SUCCESS;
1363
1364
0
  if ((card == NULL) || (card->ctx == NULL))
1365
0
    return SC_ERROR_INVALID_ARGUMENTS;
1366
1367
0
  LOG_FUNC_CALLED(card->ctx);
1368
0
  if (card->sm_ctx.sm_mode != SM_MODE_NONE) {
1369
    /* mark the channel as closed */
1370
0
    result = cwa_create_secure_channel(card,
1371
0
      GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_OFF);
1372
0
    LOG_TEST_RET(card->ctx, result, "Cannot close the secure channel");
1373
0
  }
1374
1375
0
  LOG_FUNC_RETURN(card->ctx, result);
1376
0
}
1377
1378
/**
1379
 * Implementation of Set_Security_Environment card driver command.
1380
 *
1381
 * Initializes the security environment on card
1382
 *   according to <env>, and stores the environment as <se_num> on the
1383
 *   card. If se_num <= 0, the environment will not be stored.
1384
 *   Notice that OpenDNIe SM handling requires a buffer longer than
1385
 *   provided for this command; so special apdu is used in cwa code
1386
 *
1387
 * @param card Pointer to card driver Structure
1388
 * @param env Pointer to security environment data
1389
 * @param num: which Card Security environment to use (ignored in OpenDNIe)
1390
 * @return SC_SUCCESS if OK; else error code
1391
 *
1392
 * TODO: mix these code with SM set_security_env operations
1393
 *
1394
 */
1395
static int dnie_set_security_env(struct sc_card *card,
1396
         const struct sc_security_env *env, int se_num)
1397
0
{
1398
0
  sc_apdu_t apdu;
1399
0
  u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; /* buffer to compose apdu data */
1400
0
  u8 rbuf[MAX_RESP_BUFFER_SIZE];
1401
0
  u8 *p = sbuf;
1402
0
  int result = SC_SUCCESS;
1403
0
  if ((card == NULL) || (card->ctx == NULL) || (env == NULL))
1404
0
    return SC_ERROR_INVALID_ARGUMENTS;
1405
0
  LOG_FUNC_CALLED(card->ctx);
1406
0
  if (se_num!=0) {
1407
0
    sc_log(card->ctx,"DNIe cannot handle several security envs");
1408
0
    LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS);
1409
0
  }
1410
1411
  /* Secure Channel should be on here, if not means an error */
1412
  /*
1413
  result =
1414
      cwa_create_secure_channel(card, dnie_priv.provider, CWA_SM_WARM);
1415
  LOG_TEST_RET(card->ctx, result,
1416
         "set_security_env(); Cannot establish SM");
1417
  */
1418
1419
  /* check for algorithms */
1420
0
  if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) {
1421
0
    sc_log(card->ctx, "checking algorithms");
1422
0
    switch (env->algorithm) {
1423
0
    case SC_ALGORITHM_RSA:
1424
0
      result = SC_SUCCESS;
1425
0
      break;
1426
0
    case SC_ALGORITHM_EC:
1427
0
    case SC_ALGORITHM_GOSTR3410:
1428
0
    default:
1429
0
      result = SC_ERROR_NOT_SUPPORTED;
1430
0
      break;
1431
0
    }
1432
0
    LOG_TEST_RET(card->ctx, result, "Unsupported algorithm");
1433
0
    if ((env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1) == 0) {
1434
0
      result = SC_ERROR_NOT_SUPPORTED;
1435
      /* TODO:
1436
       * Manual says that only RSA with SHA1 is supported, but found
1437
       * some docs where states that SHA256 is also handled
1438
       */
1439
0
    }
1440
0
    LOG_TEST_RET(card->ctx, result,
1441
0
           "Only RSA with SHA1 is supported");
1442
    /* ok: insert algorithm reference into buffer */
1443
0
    *p++ = 0x80;  /* algorithm reference tag */
1444
0
    *p++ = 0x01;  /* len */
1445
0
    *p++ = env->algorithm_ref & 0xff; /* val */
1446
0
  }
1447
1448
  /* check for key references */
1449
0
  if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) {
1450
0
    sc_log(card->ctx, "checking key references");
1451
0
    if (env->key_ref_len != 1) {
1452
0
      sc_log(card->ctx, "Null or invalid key ID reference");
1453
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1454
0
    }
1455
0
    sc_log(card->ctx, "Using key reference '%s'",
1456
0
           sc_dump_hex(env->key_ref, env->key_ref_len));
1457
    /* ok: insert key reference into buffer */
1458
    /* notice that DNIe uses same key reference for pubk and privk */
1459
1460
    /* see cwa14890-2 sect B.1 about Control Reference Template Tags */
1461
0
    *p++ = 0x84;  /* TODO: make proper detection of 0x83 /0x84 tag usage */
1462
0
    *p++ = 0x02;  /* len  */
1463
0
    *p++ = 0x01;  /* key ID prefix (MSB byte of keyFile ID) */
1464
0
    memcpy(p, env->key_ref, env->key_ref_len);  /* in DNIe key_ref_len=1 */
1465
0
    p += env->key_ref_len;
1466
    /* store key reference into private data */
1467
0
    GET_DNIE_PRIV_DATA(card)->rsa_key_ref = 0xff & env->key_ref[0];
1468
0
  }
1469
1470
  /* create and format apdu */
1471
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x22, 0x00, 0x00, 255, p - sbuf,
1472
0
          rbuf, MAX_RESP_BUFFER_SIZE, sbuf, p - sbuf);
1473
1474
  /* check and perform operation */
1475
0
  switch (env->operation) {
1476
0
  case SC_SEC_OPERATION_DECIPHER:
1477
    /* TODO: Manual is unsure about if (de)cipher() is supported */
1478
0
    apdu.p1 = 0xC1;
1479
0
    apdu.p2 = 0xB8;
1480
0
    break;
1481
0
  case SC_SEC_OPERATION_SIGN:
1482
0
    apdu.p1 = 0x41; /* SET; internal operation */
1483
0
    apdu.p2 = 0xB6; /* Template for Digital Signature */
1484
0
    break;
1485
0
  default:
1486
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1487
0
  }
1488
1489
  /* Notice that Manual states that DNIE only allows handle of
1490
   * current security environment, so se_num is ignored, and
1491
   * store sec env apdu (00 22 F2 se_num) command will not be issued */
1492
1493
  /* send composed apdu and parse result */
1494
0
  result = sc_transmit_apdu(card, &apdu);
1495
0
  LOG_TEST_RET(card->ctx, result, "Set Security Environment failed");
1496
0
  result = sc_check_sw(card, apdu.sw1, apdu.sw2);
1497
1498
0
  LOG_FUNC_RETURN(card->ctx, result);
1499
0
}
1500
1501
/**
1502
 * OpenDNIe implementation of Decipher() card driver operation.
1503
 *
1504
 * Engages the deciphering operation.  Card will use the
1505
 * security environment set in a call to set_security_env or
1506
 * restore_security_env.
1507
 *
1508
 * Notice that DNIe manual doesn't say anything about crypt/decrypt
1509
 * operations. So this code is based on ISO standards and still needs
1510
 * to be checked
1511
 *
1512
 * ADD: seems that DNIe supports a minimal cipher/decipher operation
1513
 * but restricted to 1024 data chunks . Need more info and tests
1514
 *
1515
 * @param card Pointer to Card Driver Structure
1516
 * @param crgram cryptogram to be (de)ciphered
1517
 * @param crgram_len cryptogram length
1518
 * @param out where to store result
1519
 * @param outlen length of result buffer
1520
 * @return SC_SUCCESS if OK; else error code
1521
 */
1522
static int dnie_decipher(struct sc_card *card,
1523
       const u8 * crgram, size_t crgram_len,
1524
       u8 * out, size_t outlen)
1525
0
{
1526
0
  struct sc_apdu apdu;
1527
0
  u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
1528
0
  u8 sbuf[MAX_RESP_BUFFER_SIZE];
1529
0
  size_t len;
1530
0
  int result = SC_SUCCESS;
1531
0
  if ((card == NULL) || (card->ctx == NULL))
1532
0
    return SC_ERROR_INVALID_ARGUMENTS;
1533
0
  LOG_FUNC_CALLED(card->ctx);
1534
0
  if ((crgram == NULL) || (out == NULL) || (crgram_len > 255)) {
1535
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1536
0
  }
1537
  /* Secure Channel should be on. Elsewhere an error will be thrown */
1538
  /*
1539
  result =
1540
      cwa_create_secure_channel(card, dnie_priv.provider, CWA_SM_WARM);
1541
  LOG_TEST_RET(card->ctx, result, "decipher(); Cannot establish SM");
1542
  */
1543
1544
  /* Official driver uses an undocumented proprietary APDU
1545
   * (90 74 40 keyID). This code uses standard 00 2A 80 8x one)
1546
   * as shown in card-atrust-acos.c and card-jcop.c
1547
   */
1548
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT,
1549
0
      0x2A, /* INS: 0x2A  perform security operation */
1550
0
      0x80, /* P1: Response is plain value */
1551
0
      0x86, /* P2: 8x: Padding indicator byte followed by cryptogram */
1552
0
      256, crgram_len + 1, rbuf, sizeof(rbuf), sbuf, crgram_len + 1
1553
0
      );
1554
1555
0
  sbuf[0] = 0;    /* padding indicator byte, 0x00 = No further indication */
1556
0
  memcpy(sbuf + 1, crgram, crgram_len);
1557
  /* send apdu */
1558
0
  result = sc_transmit_apdu(card, &apdu);
1559
0
  LOG_TEST_RET(card->ctx, result, "APDU transmit failed");
1560
  /* check response */
1561
0
  result = sc_check_sw(card, apdu.sw1, apdu.sw2);
1562
0
  LOG_TEST_RET(card->ctx, result, "decipher returned error");
1563
  /* responde ok: fill result data and return */
1564
0
  len = apdu.resplen > outlen ? outlen : apdu.resplen;
1565
0
  memcpy(out, apdu.resp, len);
1566
0
  LOG_FUNC_RETURN(card->ctx, result);
1567
0
}
1568
1569
/**
1570
 * OpenDNIe implementation of Compute_Signature() card driver operation.
1571
 *
1572
 * Generates a digital signature on the card.
1573
 * This function handles the process of hash + sign
1574
 * with previously selected keys (by mean of set_security environment
1575
 *
1576
 * AS iso7816 and DNIe Manual states there are 3 ways to perform
1577
 * this operation:
1578
 *
1579
 * - (plaintext) Hash on plaintext + sign
1580
 * - (partial hash) Send a externally evaluated pkcs1 hash + sign
1581
 * - (hash) directly sign a given sha1 hash
1582
 *
1583
 * So the code analyze incoming data, decide which method to be used
1584
 * and applies
1585
 *
1586
 * @param card pointer to sc_card_t structure
1587
 * @param data data to be hashed/signed
1588
 * @param datalen length of provided data
1589
 * @param out buffer to store results into
1590
 * @param outlen available space in result buffer
1591
 * @return
1592
 *  - Positive value: Size of data stored in out buffer when no error
1593
 *  - Negative value: error code
1594
 */
1595
static int dnie_compute_signature(struct sc_card *card,
1596
          const u8 * data, size_t datalen,
1597
          u8 * out, size_t outlen)
1598
0
{
1599
0
  int result = SC_SUCCESS;
1600
0
  size_t result_resplen = 0;
1601
0
  struct sc_apdu apdu;
1602
0
  u8 rbuf[MAX_RESP_BUFFER_SIZE];  /* to receive sign response */
1603
1604
  /* some preliminary checks */
1605
0
  if ((card == NULL) || (card->ctx == NULL))
1606
0
    return SC_ERROR_INVALID_ARGUMENTS;
1607
  /* OK: start working */
1608
0
  LOG_FUNC_CALLED(card->ctx);
1609
  /* more checks */
1610
0
  if ((data == NULL) || (out == NULL))
1611
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1612
0
  if (datalen > SC_MAX_APDU_BUFFER_SIZE) /* should be 256 */
1613
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1614
1615
#ifdef ENABLE_DNIE_UI
1616
  /* (Requested by DGP): on signature operation, ask user consent */
1617
  if (GET_DNIE_PRIV_DATA(card)->rsa_key_ref == 0x02) {  /* TODO: revise key ID handling */
1618
    result = dnie_ask_user_consent(card,user_consent_title,user_consent_message);
1619
    LOG_TEST_RET(card->ctx, result, "User consent denied");
1620
  }
1621
#endif
1622
1623
  /*
1624
     Seems that OpenSC already provides pkcs#1 v1.5 DigestInfo structure
1625
     with pre-calculated hash. So no need to to any Hash calculation,
1626
1627
     So just extract 15+20 DigestInfo+Hash info from ASN.1 provided
1628
     data and feed them into sign() command
1629
   */
1630
0
  sc_log_hex(card->ctx,
1631
0
         "Compute signature\n============================================================",
1632
0
         data, datalen);
1633
1634
  /*INS: 0x2A  PERFORM SECURITY OPERATION
1635
   * P1:  0x9E  Resp: Digital Signature
1636
   * P2:  0x9A  Cmd: Input for Digital Signature */
1637
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A, 256, datalen,
1638
0
          rbuf, sizeof(rbuf), data, datalen);
1639
  /* tell card to compute signature */
1640
0
  result = sc_transmit_apdu(card, &apdu);
1641
0
  if (result != SC_SUCCESS) {
1642
0
    LOG_TEST_RET(card->ctx, result, "compute_signature() failed");
1643
0
  }
1644
  /* check response */
1645
0
  result = sc_check_sw(card, apdu.sw1, apdu.sw2);
1646
0
  if (result != SC_SUCCESS) {
1647
0
    LOG_TEST_RET(card->ctx, result, "compute_signature() response error");
1648
0
  }
1649
1650
  /* ok: copy result from buffer */
1651
0
  result_resplen = apdu.resplen;
1652
0
  if (outlen < result_resplen)
1653
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1654
0
  memcpy(out, apdu.resp, result_resplen);
1655
  /* and return response length */
1656
0
  LOG_FUNC_RETURN(card->ctx, (int)result_resplen);
1657
0
}
1658
1659
/*
1660
 * ISO 7816-9 functions
1661
 */
1662
1663
/**
1664
 * OpenDNIe implementation of List_Files() card driver operation.
1665
 *
1666
 * List available files in current DF
1667
 * This is a dirty and trick implementation:
1668
 * Just try every ID in current dir
1669
 *
1670
 * @param card Pointer to Card Driver structure
1671
 * @param buff buffer to store result into
1672
 * @param bufflen size of provided buffer
1673
 * @return SC_SUCCESS if OK; else error code
1674
 *
1675
 * TODO: check for presence of every file ids on a DF is not
1676
 * practical. Locate a better way to handle, or remove code
1677
 */
1678
static int dnie_list_files(sc_card_t * card, u8 * buf, size_t buflen)
1679
45
{
1680
45
  int res = SC_SUCCESS;
1681
45
  int id1 = 0;
1682
45
  int id2 = 0;
1683
45
  size_t count = 0;
1684
45
  u8 data[2];
1685
45
  sc_apdu_t apdu;
1686
45
  if (!card || !card->ctx)
1687
0
    return SC_ERROR_INVALID_ARGUMENTS;
1688
1689
45
  LOG_FUNC_CALLED(card->ctx);
1690
45
  if (!buf || (buflen < 2))
1691
45
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1692
1693
  /* compose select_file(ID) command */
1694
45
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x00, 0x00, 0, 2,
1695
45
          NULL, 0, data, 2);
1696
  /* iterate on every possible ids */
1697
45
  for (id1 = 0; id1 < 256; id1++) {
1698
45
    for (id2 = 0; id2 < 256; id2++) {
1699
45
      if (count >= (buflen - 2)) {
1700
0
        sc_log(card->ctx,
1701
0
               "list_files: end of buffer. Listing stopped");
1702
0
        LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1703
0
      }
1704
      /* according iso several ids are not allowed, so check for it */
1705
45
      if ((id1 == 0x3F) && (id2 == 0xFF))
1706
0
        continue; /* generic parent "." DF */
1707
45
      if ((id1 == 0x2F) && (id2 == 0x00))
1708
0
        continue; /* RFU see iso 8.2.1.1 */
1709
45
      if ((id1 == 0x2F) && (id2 == 0x01))
1710
0
        continue; /* RFU */
1711
      /* compose and transmit select_file() cmd */
1712
45
      data[0] = (u8) (0xff & id1);
1713
45
      data[1] = (u8) (0xff & id2);
1714
45
      res = sc_transmit_apdu(card, &apdu);
1715
45
      if (res != SC_SUCCESS) {
1716
45
        sc_log(card->ctx, "List file '%02X%02X' failed",
1717
45
               id1, id2);
1718
        /* if file not found, continue; else abort */
1719
45
        if (res != SC_ERROR_FILE_NOT_FOUND)
1720
45
          LOG_FUNC_RETURN(card->ctx, res);
1721
0
        continue;
1722
45
      }
1723
      /* if file found, process fci to get file type */
1724
0
      sc_log(card->ctx, "Found File ID '%02X%02X'", id1, id2);
1725
      /* store id into buffer */
1726
0
      *(buf + count++) = data[0];
1727
0
      *(buf + count++) = data[1];
1728
      /* TODO:
1729
      * if found file is a DF go back to parent DF
1730
      * to continue search */
1731
0
    }
1732
45
  }
1733
  /* arriving here means all done */
1734
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1735
0
}
1736
1737
/**
1738
 * Parse APDU results to generate proper error code.
1739
 *
1740
 * Traps standard check_sw function to take care on special error codes
1741
 * for OpenDNIe (mostly related to SM status and operations)
1742
 *
1743
 * @param card Pointer to Card driver Structure
1744
 * @param sw1 SW1 APDU response byte
1745
 * @param sw2 SW2 APDU response byte
1746
 * @return SC_SUCCESS if no error; else proper error code
1747
 */
1748
static int dnie_check_sw(struct sc_card *card,
1749
       unsigned int sw1, unsigned int sw2)
1750
308
{
1751
308
  int res = SC_SUCCESS;
1752
308
  int n = 0;
1753
308
  if (!card || !card->ctx)
1754
0
    return SC_ERROR_INVALID_ARGUMENTS;
1755
308
  LOG_FUNC_CALLED(card->ctx);
1756
1757
  /* check specific dnie errors */
1758
1.21k
  for (n = 0; dnie_errors[n].SWs != 0; n++) {
1759
921
    if (dnie_errors[n].SWs == ((sw1 << 8) | sw2)) {
1760
10
      sc_log(card->ctx, "%s", dnie_errors[n].errorstr);
1761
10
      return dnie_errors[n].errorno;
1762
10
    }
1763
921
  }
1764
1765
  /* arriving here means check for supported iso error codes */
1766
298
  res = iso_ops->check_sw(card, sw1, sw2);
1767
298
  LOG_FUNC_RETURN(card->ctx, res);
1768
298
}
1769
1770
/**
1771
 * OpenDNIe implementation for Card_Ctl() card driver operation.
1772
 *
1773
 * This command provides access to non standard functions provided by
1774
 * this card driver, as defined in cardctl.h
1775
 *
1776
 * @param card Pointer to card driver structure
1777
 * @param request Operation requested
1778
 * @param data where to get data/store response
1779
 * @return SC_SUCCESS if ok; else error code
1780
 * @see cardctl.h
1781
 *
1782
 * TODO: wait for GET_CARD_INFO generic cardctl to be implemented
1783
 * in opensc and rewrite code according it
1784
 */
1785
static int dnie_card_ctl(struct sc_card *card,
1786
       unsigned long request, void *data)
1787
0
{
1788
0
  int result = SC_SUCCESS;
1789
0
  if ((card == NULL) || (card->ctx == NULL))
1790
0
    return SC_ERROR_INVALID_ARGUMENTS;
1791
0
  LOG_FUNC_CALLED(card->ctx);
1792
0
  if (data == NULL) {
1793
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1794
0
  }
1795
0
  switch (request) {
1796
    /* obtain lifecycle status by reading card->type */
1797
0
  case SC_CARDCTL_LIFECYCLE_GET:
1798
0
    switch (card->type) {
1799
0
    case SC_CARD_TYPE_DNIE_ADMIN:
1800
0
      result = SC_CARDCTRL_LIFECYCLE_ADMIN;
1801
0
      break;
1802
0
    case SC_CARD_TYPE_DNIE_USER:
1803
0
      result = SC_CARDCTRL_LIFECYCLE_USER;
1804
0
      break;
1805
0
    case SC_CARD_TYPE_DNIE_BLANK:
1806
0
    case SC_CARD_TYPE_DNIE_TERMINATED:
1807
0
      result = SC_CARDCTRL_LIFECYCLE_OTHER;
1808
0
      break;
1809
0
    }
1810
0
    *(int *)data = result;
1811
0
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1812
    /* call card to obtain serial number */
1813
0
  case SC_CARDCTL_GET_SERIALNR:
1814
0
    result = dnie_get_serialnr(card, (sc_serial_number_t *) data);
1815
0
    LOG_FUNC_RETURN(card->ctx, result);
1816
0
  case SC_CARDCTL_DNIE_GENERATE_KEY:
1817
    /* some reports says that this card supports genkey */
1818
0
    result = dnie_generate_key(card, data);
1819
0
    LOG_FUNC_RETURN(card->ctx, result);
1820
0
  case SC_CARDCTL_DNIE_GET_INFO:
1821
    /* retrieve name, surname and eid number */
1822
0
    result = dnie_get_info(card, data);
1823
0
    LOG_FUNC_RETURN(card->ctx, result);
1824
0
  default:
1825
    /* default: unsupported function */
1826
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1827
0
  }
1828
0
}
1829
1830
/**
1831
 * Read first bytes of an EF to check for compression data.
1832
 *
1833
 * FCI info on compressed files provides the length of the compressed
1834
 * data. When fci returns filetype = 0x24, needs to check if the
1835
 * file is compressed, and set up properly correct file length, to let
1836
 * the read_binary() file cache work
1837
 *
1838
 * Extract real file length from compressed file is done by mean of
1839
 * reading 8 first bytes for uncompressed/compressed length.
1840
 * Lengths are provided as two 4-byte little endian numbers
1841
 *
1842
 * Implemented just like a direct read binary apdu bypassing dnie file cache
1843
 *
1844
 * @param card sc_card_t structure pointer
1845
 * @return <0: error code - ==0 not compressed - >0 file size
1846
 */
1847
static int dnie_read_header(struct sc_card *card)
1848
0
{
1849
0
  sc_apdu_t apdu;
1850
0
  int r;
1851
0
  u8 buf[MAX_RESP_BUFFER_SIZE];
1852
0
  unsigned long uncompressed = 0L;
1853
0
  unsigned long compressed = 0L;
1854
0
  sc_context_t *ctx = NULL;
1855
1856
0
  if (!card || !card->ctx)
1857
0
    return SC_ERROR_INVALID_ARGUMENTS;
1858
0
  ctx = card->ctx;
1859
0
  LOG_FUNC_CALLED(ctx);
1860
1861
  /* initialize apdu */
1862
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, 0x00, 0x00, 8, 0,
1863
0
          buf, MAX_RESP_BUFFER_SIZE, NULL, 0);
1864
  /* transmit apdu */
1865
0
  r = sc_transmit_apdu(card, &apdu);
1866
0
  if (r != SC_SUCCESS) {
1867
0
    sc_log(ctx, "read_header() APDU transmit failed");
1868
0
    LOG_FUNC_RETURN(ctx, r);
1869
0
  }
1870
  /* check response */
1871
0
  if (apdu.resplen != 8)
1872
0
    goto header_notcompressed;
1873
0
  uncompressed = lebytes2ulong(apdu.resp);
1874
0
  compressed = lebytes2ulong(apdu.resp + 4);
1875
0
  if (uncompressed < compressed)
1876
0
    goto header_notcompressed;
1877
0
  if (uncompressed > 32767)
1878
0
    goto header_notcompressed;
1879
  /* ok: assume data is correct */
1880
0
  sc_log(ctx, "read_header: uncompressed file size is %lu", uncompressed);
1881
0
  return (int)(0x7FFF & uncompressed);
1882
1883
0
 header_notcompressed:
1884
0
  sc_log(ctx, "response doesn't match compressed file header");
1885
0
  return 0;
1886
0
}
1887
1888
/**
1889
 *  Access control list bytes for proprietary DNIe FCI response for DF's.
1890
 *  based in information from official DNIe Driver
1891
 *  Parsing code based on itacns card driver
1892
 */
1893
static int df_acl[] = {   /* to handle DF's */
1894
  SC_AC_OP_CREATE, SC_AC_OP_DELETE,
1895
  SC_AC_OP_REHABILITATE, SC_AC_OP_INVALIDATE,
1896
  -1      /* !hey!, what about 5th byte of FCI info? */
1897
};
1898
1899
/**
1900
 *  Access control list bytes for proprietary DNIe FCI response for EF's.
1901
 *  based in information from official DNIe Driver
1902
 *  Parsing code based on itacns card driver
1903
 */
1904
static int ef_acl[] = {   /* to handle EF's */
1905
  SC_AC_OP_READ, SC_AC_OP_UPDATE,
1906
  SC_AC_OP_REHABILITATE, SC_AC_OP_INVALIDATE,
1907
  -1      /* !hey!, what about 5th byte of FCI info? */
1908
};
1909
1910
/**
1911
 * OpenDNIe implementation of Process_FCI() card driver command.
1912
 *
1913
 * Parse SelectFile's File Control information.
1914
 * - First, std iso_parse_fci is called to parse std fci tags
1915
 * - Then analyze proprietary tag according DNIe Manual
1916
 *
1917
 * @param card OpenSC card structure pointer
1918
 * @param file currently selected EF or DF
1919
 * @param buf received FCI data
1920
 * @param buflen FCI length
1921
 * @return SC_SUCCESS if OK; else error code
1922
 */
1923
static int dnie_process_fci(struct sc_card *card,
1924
          struct sc_file *file, const u8 * buf, size_t buflen)
1925
0
{
1926
0
  int res = SC_SUCCESS;
1927
0
  int *op = df_acl;
1928
0
  int n = 0;
1929
0
  sc_context_t *ctx = NULL;
1930
0
  if ((card == NULL) || (card->ctx == NULL) || (file == NULL) || buflen == 0)
1931
0
    return SC_ERROR_INVALID_ARGUMENTS;
1932
0
  ctx = card->ctx;
1933
0
  LOG_FUNC_CALLED(ctx);
1934
  /* first of all, let iso do the hard work */
1935
0
  res = iso_ops->process_fci(card, file, buf, buflen);
1936
0
  LOG_TEST_RET(ctx, res, "iso7816_process_fci() failed");
1937
  /* if tag 0x85 is received, then file->prop_attr_len should be filled
1938
   * by sc_file_set_prop_attr() code. So check and set data according manual
1939
   * Note errata at pg 35 of Manual  about DF identifier (should be 0x38) */
1940
0
  if (file->prop_attr_len == 0) { /* no proprietary tag (0x85) received */
1941
0
    res = SC_SUCCESS;
1942
0
    goto dnie_process_fci_end;
1943
0
  }
1944
  /* at least 10 bytes should be received */
1945
0
  if (file->prop_attr_len < 10) {
1946
0
    res = SC_ERROR_WRONG_LENGTH;
1947
0
    goto dnie_process_fci_end;
1948
0
  }
1949
  /* byte 0 denotes file type */
1950
0
  switch (file->prop_attr[0]) {
1951
0
  case 0x01:    /* EF for plain files */
1952
0
    file->type = SC_FILE_TYPE_WORKING_EF;
1953
0
    file->ef_structure = SC_FILE_EF_TRANSPARENT;
1954
0
    break;
1955
0
  case 0x15:    /* EF for keys: linear variable simple TLV */
1956
0
    file->type = SC_FILE_TYPE_WORKING_EF;
1957
    /* pin file 3F000000 has also this EF type */
1958
0
    if ( ( file->prop_attr[2] == 0x00 ) && (file->prop_attr[3] == 0x00 ) ) {
1959
0
      sc_log(ctx,"Processing pin EF");
1960
0
      break;
1961
0
    }
1962
    /* FCI response for Keys EF returns 3 additional bytes */
1963
0
    if (file->prop_attr_len < 13) {
1964
0
      sc_log(ctx, "FCI response len for Keys EF should be 13 bytes");
1965
0
      res = SC_ERROR_WRONG_LENGTH;
1966
0
      goto dnie_process_fci_end;
1967
0
    }
1968
0
    break;
1969
0
  case 0x24:    /* EF for compressed certificates */
1970
0
    file->type = SC_FILE_TYPE_WORKING_EF;
1971
0
    file->ef_structure = SC_FILE_EF_TRANSPARENT;
1972
    /* evaluate real length by reading first 8 bytes from file */
1973
0
    res = dnie_read_header(card);
1974
    /* Hey!, we need pin to read certificates... */
1975
0
    if (res == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED)
1976
0
      goto dnie_process_fci_end;
1977
0
    if (res <= 0) {
1978
0
      sc_log(ctx,
1979
0
             "Cannot evaluate uncompressed size. use fci length");
1980
0
    } else {
1981
0
      sc_log(ctx, "Storing uncompressed size '%d' into fci",
1982
0
             res);
1983
0
      file->prop_attr[3] = (u8) ((res >> 8) & 0xff);
1984
0
      file->prop_attr[4] = (u8) (res & 0xff);
1985
0
    }
1986
0
    break;
1987
0
  case 0x38:    /* Errata: manual page 35 says wrong 0x34 */
1988
0
    file->type = SC_FILE_TYPE_DF;
1989
0
    break;
1990
0
  default:
1991
0
    res = SC_ERROR_UNKNOWN_DATA_RECEIVED;
1992
0
    goto dnie_process_fci_end;
1993
0
  }
1994
1995
  /* bytes 1 and 2 stores file ID */
1996
0
  file->id = ( ( 0xff & (int)file->prop_attr[1] ) << 8 ) |
1997
0
      ( 0xff & (int)file->prop_attr[2] ) ;
1998
1999
  /* bytes 3 and 4 states file length */
2000
0
  file->size = ( ( 0xff & (int)file->prop_attr[3] ) << 8 ) |
2001
0
      ( 0xff & (int)file->prop_attr[4] ) ;
2002
2003
  /* bytes 5 to 9 states security attributes */
2004
  /* NOTE:
2005
   * seems that these 5 bytes are handled according iso7816-9 sect 8.
2006
   * but sadly that each card uses their own bits :-(
2007
   * Moreover: Manual talks on 5 bytes, but official driver only uses 4
2008
   * No info available (yet), so copy code from card-jcos.c / card-flex.c
2009
   * card drivers and pray... */
2010
0
  op = (file->type == SC_FILE_TYPE_DF) ? df_acl : ef_acl;
2011
0
  for (n = 0; n < 5; n++) {
2012
0
    int key_ref = 0;
2013
0
    if (*(op + n) == -1)
2014
0
      continue; /* unused entry: skip */
2015
0
    key_ref = file->prop_attr[5 + n] & 0x0F;
2016
0
    switch (0xF0 & file->prop_attr[5 + n]) {
2017
0
    case 0x00:
2018
0
      sc_file_add_acl_entry(file, *(op + n), SC_AC_NONE,
2019
0
                SC_AC_KEY_REF_NONE);
2020
0
      break;
2021
0
    case 0x10:
2022
      /* this tag is omitted in official code
2023
         case 0x20:
2024
       */
2025
0
    case 0x30:
2026
0
      sc_file_add_acl_entry(file, *(op + n), SC_AC_CHV,
2027
0
                key_ref);
2028
0
      break;
2029
0
    case 0x40:
2030
0
      sc_file_add_acl_entry(file, *(op + n), SC_AC_TERM,
2031
0
                key_ref);
2032
0
      break;
2033
0
    case 0xF0:
2034
0
      sc_file_add_acl_entry(file, *(op + n), SC_AC_NEVER,
2035
0
                SC_AC_KEY_REF_NONE);
2036
0
      break;
2037
0
    default:
2038
0
      sc_file_add_acl_entry(file, *(op + n), SC_AC_UNKNOWN,
2039
0
                SC_AC_KEY_REF_NONE);
2040
0
      break;
2041
0
    }
2042
0
  }
2043
  /* NOTE: Following bytes are described at DNIe manual pg 36, but No
2044
     documentation about what to do with following data is provided...
2045
     logs suggest that they are neither generated nor handled.
2046
2047
     UPDATE: these additional bytes are received when FileDescriptor tag
2048
     is 0x15 (EF for keys)
2049
   */
2050
0
  if (file->prop_attr[0] == 0x15) {
2051
0
    sc_log(card->ctx,
2052
0
           "Processing flags for Cryptographic key files");
2053
    /* byte 10 (if present) shows Control Flags for security files */
2054
    /* bytes 11 and 12 (if present) states Control bytes for
2055
       RSA crypto files */
2056
    /* TODO: write when know what to do */
2057
0
  }
2058
0
  res = SC_SUCCESS; /* arriving here means success */
2059
0
 dnie_process_fci_end:
2060
0
  LOG_FUNC_RETURN(card->ctx, res);
2061
0
}
2062
2063
/*
2064
 * PIN related functions
2065
 * NOTE:
2066
 * DNIe manual says only about CHV1 PIN verify, but several sources talks
2067
 * about the ability to also handle CHV1 PIN change
2068
 * So prepare code to eventually support
2069
 *
2070
 * Anyway pin unlock is not available: no way to get PUK as these code is
2071
 * obtained by mean of user fingerprint, only available at police station
2072
 */
2073
2074
/**
2075
 * Change PIN.
2076
 *
2077
 * Not implemented yet, as current availability for DNIe user driver
2078
 * is unknown
2079
 *
2080
 * @param card Pointer to Card Driver data structure
2081
 * @param data Pointer to Pin data structure
2082
 * @return SC_SUCCESS if ok; else error code
2083
 */
2084
static int dnie_pin_change(struct sc_card *card, struct sc_pin_cmd_data * data)
2085
0
{
2086
0
  int res=SC_SUCCESS;
2087
0
  LOG_FUNC_CALLED(card->ctx);
2088
  /* Ensure that secure channel is established from reset */
2089
0
  res = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_ON);
2090
0
  LOG_TEST_RET(card->ctx, res, "Establish SM failed");
2091
0
  LOG_FUNC_RETURN(card->ctx,SC_ERROR_NOT_SUPPORTED);
2092
0
}
2093
2094
/**
2095
 * Verify PIN.
2096
 *
2097
 * Initialize SM and send pin verify CHV1 command to DNIe
2098
 *
2099
 * @param card Pointer to Card Driver data structure
2100
 * @param data Pointer to Pin data structure
2101
 * @param tries_left; on fail stores the number of tries left before car lock
2102
 * @return SC_SUCCESS if ok, else error code; on pin incorrect also sets tries_left
2103
 */
2104
static int dnie_pin_verify(struct sc_card *card,
2105
                        struct sc_pin_cmd_data *data, int *tries_left)
2106
0
{
2107
0
  int res=SC_SUCCESS;
2108
0
  sc_apdu_t apdu;
2109
2110
0
  u8 pinbuffer[SC_MAX_APDU_BUFFER_SIZE];
2111
0
  int pinlen = 0;
2112
0
  int padding = 0;
2113
2114
0
  LOG_FUNC_CALLED(card->ctx);
2115
  /* ensure that secure channel is established from reset */
2116
0
  if (card->atr.value[15] >= DNIE_30_VERSION) {
2117
    /* the provider should be prepared for using PIN information */
2118
0
    sc_log(card->ctx, "DNIe 3.0 detected doing PIN initialization");
2119
0
    dnie_change_cwa_provider_to_pin(card);
2120
0
  }
2121
0
  res = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_ON);
2122
0
  LOG_TEST_RET(card->ctx, res, "Establish SM failed");
2123
2124
  /* compose pin data to be inserted in apdu */
2125
0
  if (data->flags & SC_PIN_CMD_NEED_PADDING)
2126
0
    padding = 1;
2127
0
  data->pin1.offset = 0;
2128
0
  res = sc_build_pin(pinbuffer, sizeof(pinbuffer), &data->pin1, padding);
2129
0
  if (res < 0)
2130
0
    LOG_FUNC_RETURN(card->ctx, res);
2131
0
  pinlen = res;
2132
2133
  /* compose apdu */
2134
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, 0x00, 0, pinlen,
2135
0
          NULL, 0, pinbuffer, pinlen);
2136
2137
  /* and send to card through virtual channel */
2138
0
  res = sc_transmit_apdu(card, &apdu);
2139
0
  if (res != SC_SUCCESS) {
2140
0
    LOG_TEST_RET(card->ctx, res, "VERIFY APDU Transmit fail");
2141
0
  }
2142
2143
  /* check response and if requested setup tries_left */
2144
0
  if (tries_left != NULL) { /* returning tries_left count is requested */
2145
0
    if ((apdu.sw1 == 0x63) && ((apdu.sw2 & 0xF0) == 0xC0)) {
2146
0
      *tries_left = apdu.sw2 & 0x0F;
2147
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
2148
0
    }
2149
0
  }
2150
0
  res = dnie_check_sw(card, apdu.sw1, apdu.sw2);  /* not a pinerr: parse result */
2151
2152
  /* ensure that secure channel is established after a PIN channel in 3.0 */
2153
0
  if (card->atr.value[15] >= DNIE_30_VERSION) {
2154
0
    sc_log(card->ctx, "DNIe 3.0 detected => re-establish secure channel");
2155
0
    dnie_change_cwa_provider_to_secure(card);
2156
0
    if (res == SC_SUCCESS) {
2157
0
      res = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_ON);
2158
0
    }
2159
0
  }
2160
2161
0
  LOG_FUNC_RETURN(card->ctx, res);
2162
0
}
2163
2164
/* pin_cmd: verify/change/unblock command; optionally using the
2165
 * card's pin pad if supported.
2166
 */
2167
2168
/**
2169
 * OpenDNIe implementation for Pin_Cmd() card driver command.
2170
 *
2171
 * @param card Pointer to Card Driver data structure
2172
 * @param data Pointer to Pin data structure
2173
 * @param tries_left; if pin_verify() operation, on incorrect pin stores the number of tries left before car lock
2174
 * @return SC_SUCCESS if ok, else error code; on pin incorrect also sets tries_left
2175
 */
2176
static int dnie_pin_cmd(struct sc_card *card,
2177
      struct sc_pin_cmd_data *data, int *tries_left)
2178
0
{
2179
0
  int res = SC_SUCCESS;
2180
0
  int lc = SC_CARDCTRL_LIFECYCLE_USER;
2181
2182
0
  if ((card == NULL) || (card->ctx == NULL) || (data == NULL))
2183
0
    return SC_ERROR_INVALID_ARGUMENTS;
2184
0
  LOG_FUNC_CALLED(card->ctx);
2185
2186
  /*
2187
  * some flags and settings from documentation
2188
  * No (easy) way to handle pinpad through SM, so disable it
2189
  */
2190
0
  data->flags &= ~SC_PIN_CMD_NEED_PADDING; /* no pin padding */
2191
0
  data->flags &= ~SC_PIN_CMD_USE_PINPAD;  /* cannot handle pinpad */
2192
2193
  /* ensure that card is in USER Lifecycle */
2194
0
  res = dnie_card_ctl(card, SC_CARDCTL_LIFECYCLE_GET, &lc);
2195
0
  LOG_TEST_RET(card->ctx, res, "Cannot get card LC status");
2196
0
  if (lc != SC_CARDCTRL_LIFECYCLE_USER) {
2197
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD);
2198
0
  }
2199
2200
  /* only allow changes on CHV pin ) */
2201
0
  switch (data->pin_type) {
2202
0
  case SC_AC_CHV: /* Card Holder Verifier */
2203
0
    break;
2204
0
  case SC_AC_TERM: /* Terminal auth */
2205
0
  case SC_AC_PRO: /* SM auth */
2206
0
  case SC_AC_AUT: /* Key auth */
2207
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2208
0
  default:
2209
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
2210
0
  }
2211
  /* This DNIe driver only supports VERIFY operation */
2212
0
  switch (data->cmd) {
2213
0
  case SC_PIN_CMD_VERIFY:
2214
0
    res =  dnie_pin_verify(card,data,tries_left);
2215
0
    break;
2216
0
  case SC_PIN_CMD_CHANGE:
2217
0
    res =  dnie_pin_change(card,data);
2218
0
    break;
2219
0
  case SC_PIN_CMD_UNBLOCK:
2220
0
  case SC_PIN_CMD_GET_INFO:
2221
0
    res= SC_ERROR_NOT_SUPPORTED;
2222
0
    break;
2223
0
  default:
2224
0
    res= SC_ERROR_INVALID_ARGUMENTS;
2225
0
    break;
2226
0
  }
2227
  /* return result */
2228
0
  LOG_FUNC_RETURN(card->ctx, res);
2229
0
}
2230
2231
/**********************************************************************/
2232
2233
/**
2234
 * Internal function to initialize card driver function pointers.
2235
 *
2236
 * This is done by getting a copy for iso7816 card operations,
2237
 * and replace every DNIe specific functions
2238
 *
2239
 * @return DNIe card driver data, or null on failure
2240
 */
2241
static sc_card_driver_t *get_dnie_driver(void)
2242
8.77k
{
2243
8.77k
  sc_card_driver_t *iso_drv = sc_get_iso7816_driver();
2244
2245
  /* memcpy() from standard iso7816 declared operations */
2246
8.77k
  if (iso_ops == NULL)
2247
1
    iso_ops = iso_drv->ops;
2248
8.77k
  dnie_ops = *iso_drv->ops;
2249
2250
  /* fill card specific function pointers */
2251
  /* NULL means that function is not supported neither by DNIe nor iso7816.c */
2252
  /* if pointer is omitted, default ISO7816 function will be used */
2253
2254
  /* initialization */
2255
8.77k
  dnie_ops.match_card = dnie_match_card;
2256
8.77k
  dnie_ops.init   = dnie_init;
2257
8.77k
  dnie_ops.finish   = dnie_finish;
2258
2259
  /* iso7816-4 functions */
2260
8.77k
  dnie_ops.read_binary  = dnie_read_binary;
2261
8.77k
  dnie_ops.write_binary = NULL;
2262
8.77k
  dnie_ops.update_binary  = NULL;
2263
8.77k
  dnie_ops.erase_binary = NULL;
2264
8.77k
  dnie_ops.read_record  = NULL;
2265
8.77k
  dnie_ops.write_record = NULL;
2266
8.77k
  dnie_ops.append_record  = NULL;
2267
8.77k
  dnie_ops.update_record  = NULL;
2268
8.77k
  dnie_ops.select_file  = dnie_select_file;
2269
8.77k
  dnie_ops.get_challenge  = dnie_get_challenge;
2270
2271
  /* iso7816-8 functions */
2272
8.77k
  dnie_ops.verify   = NULL;
2273
8.77k
  dnie_ops.logout   = dnie_logout;
2274
  /* dnie_ops.restore_security_env */
2275
8.77k
  dnie_ops.set_security_env = dnie_set_security_env;
2276
8.77k
  dnie_ops.decipher = dnie_decipher;
2277
8.77k
  dnie_ops.compute_signature = dnie_compute_signature;
2278
8.77k
  dnie_ops.change_reference_data = NULL;
2279
8.77k
  dnie_ops.reset_retry_counter = NULL;
2280
2281
  /* iso7816-9 functions */
2282
8.77k
  dnie_ops.create_file  = NULL;
2283
8.77k
  dnie_ops.delete_file  = NULL;
2284
8.77k
  dnie_ops.list_files = dnie_list_files;
2285
8.77k
  dnie_ops.check_sw = dnie_check_sw;
2286
8.77k
  dnie_ops.card_ctl = dnie_card_ctl;
2287
8.77k
  dnie_ops.process_fci  = dnie_process_fci;
2288
  /* dnie_ops.construct_fci */
2289
8.77k
  dnie_ops.pin_cmd  = dnie_pin_cmd;
2290
8.77k
  dnie_ops.get_data = NULL;
2291
8.77k
  dnie_ops.put_data = NULL;
2292
8.77k
  dnie_ops.delete_record  = NULL;
2293
2294
8.77k
  return &dnie_driver;
2295
8.77k
}
2296
2297
/**
2298
 * Entry point for (static) OpenDNIe card driver.
2299
 *
2300
 * This is the only public function on this module
2301
 *
2302
 * @return properly initialized array pointer to card driver operations
2303
 */
2304
sc_card_driver_t *sc_get_dnie_driver(void)
2305
8.77k
{
2306
8.77k
  return get_dnie_driver();
2307
8.77k
}
2308
2309
#undef __CARD_DNIE_C__
2310
2311
#endif        /* ENABLE_OPENSSL */