Coverage Report

Created: 2026-07-10 06:04

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
0
#define DNIE_CHIP_SHORTNAME "dnie"
69
0
#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 (from + 7 + size > buf + len) {
496
    /* not enough data in the source buffer -- invalid data received */
497
0
    return NULL;
498
0
  }
499
0
  if ( size == 0 ) return NULL; /* empty data */
500
0
  res = calloc( size+1, sizeof(char) );
501
0
  if ( res == NULL) return NULL; /* calloc() error */
502
0
  memcpy(res,from+7,size);
503
0
  return res;
504
0
}
505
506
/**
507
 * Retrieve name, surname, and DNIe number.
508
 *
509
 * This is done by mean of reading and parsing CDF file
510
 * at address 3F0050156004
511
 * No need to enter pin nor use Secure Channel
512
 *
513
 * Notice that this is done by mean of a dirty trick: instead
514
 * of parsing ASN1 data on EF(CDF),
515
 * we look for desired OID patterns in binary array
516
 *
517
 * @param card pointer to card info data
518
 * @param data where to store function results (number,name,surname,idesp,version)
519
 * @return SC_SUCCESS if ok, else error code
520
 */
521
static int dnie_get_info(sc_card_t * card, char *data[])
522
0
{
523
0
  sc_file_t *file = NULL;
524
0
        sc_path_t path;
525
0
        u8 *buffer = NULL;
526
0
  size_t bufferlen = 0;
527
0
  char *msg = NULL;
528
0
  u8 SerialNumber [] = { 0x06, 0x03, 0x55, 0x04, 0x05, 0x13 };
529
0
  u8 Name [] = { 0x06, 0x03, 0x55, 0x04, 0x04, 0x0C };
530
0
  u8 GivenName [] = { 0x06, 0x03, 0x55, 0x04, 0x2A, 0x0C };
531
0
  int res = SC_ERROR_NOT_SUPPORTED;
532
533
0
        if ((card == NULL) || (data == NULL))
534
0
                return SC_ERROR_INVALID_ARGUMENTS;
535
0
        LOG_FUNC_CALLED(card->ctx);
536
537
  /* phase 1: get DNIe number, Name and GivenName */
538
539
  /* read EF(CDF) at 3F0050156004 */
540
0
  sc_format_path("3F0050156004", &path);
541
0
  res = dnie_read_file(card, &path, &file, &buffer, &bufferlen);
542
0
  if (res != SC_SUCCESS) {
543
0
    msg = "Cannot read EF(CDF)";
544
0
    goto get_info_end;
545
0
  }
546
  /* locate OID 2.5.4.5 (SerialNumber) - DNIe number*/
547
0
  data[0]= findPattern(SerialNumber,buffer,bufferlen);
548
  /* locate OID 2.5.4.4 (Name)         - Apellidos */
549
0
  data[1]= findPattern(Name,buffer,bufferlen);
550
  /* locate OID 2.5.4.42 (GivenName)   - Nombre */
551
0
  data[2]= findPattern(GivenName,buffer,bufferlen);
552
0
  if ( ! data[0] || !data[1] || !data[2] ) {
553
0
    res = SC_ERROR_INVALID_DATA;
554
0
    msg = "Cannot retrieve info from EF(CDF)";
555
0
    goto get_info_end;
556
0
        }
557
558
  /* phase 2: get IDESP */
559
0
  sc_format_path("3F000006", &path);
560
0
  sc_file_free(file);
561
0
  file = NULL;
562
0
  if (buffer) {
563
0
    free(buffer);
564
0
    buffer=NULL;
565
0
    bufferlen=0;
566
0
  }
567
0
  res = dnie_read_file(card, &path, &file, &buffer, &bufferlen);
568
0
  if (res != SC_SUCCESS) {
569
0
    data[3]=NULL;
570
0
    goto get_info_ph3;
571
0
  }
572
0
  data[3]=calloc(bufferlen+1,sizeof(char));
573
0
  if ( !data[3] ) {
574
0
    msg = "Cannot allocate memory for IDESP data";
575
0
    res = SC_ERROR_OUT_OF_MEMORY;
576
0
    goto get_info_end;
577
0
  }
578
0
  memcpy(data[3],buffer,bufferlen);
579
580
0
get_info_ph3:
581
  /* phase 3: get DNIe software version */
582
0
  sc_format_path("3F002F03", &path);
583
0
  sc_file_free(file);
584
0
  file = NULL;
585
0
  if (buffer) {
586
0
    free(buffer);
587
0
    buffer=NULL;
588
0
    bufferlen=0;
589
0
  }
590
  /*
591
  * Some old DNIe cards seems not to include SW version file,
592
  * so let this code fail without notice
593
  */
594
0
  res = dnie_read_file(card, &path, &file, &buffer, &bufferlen);
595
0
  if (res != SC_SUCCESS) {
596
0
    msg = "Cannot read DNIe Version EF";
597
0
    data[4]=NULL;
598
0
    res = SC_SUCCESS; /* let function return successfully */
599
0
    goto get_info_end;
600
0
  }
601
0
  data[4]=calloc(bufferlen+1,sizeof(char));
602
0
  if ( !data[4] ) {
603
0
    msg = "Cannot allocate memory for DNIe Version data";
604
0
    res = SC_ERROR_OUT_OF_MEMORY;
605
0
    goto get_info_end;
606
0
  }
607
0
  memcpy(data[4],buffer,bufferlen);
608
609
  /* arriving here means ok */
610
0
  res = SC_SUCCESS;
611
0
  msg = NULL;
612
613
0
get_info_end:
614
0
  sc_file_free(file);
615
0
  file = NULL;
616
0
  if (buffer) {
617
0
    free(buffer);
618
0
    buffer=NULL;
619
0
    bufferlen=0;
620
0
  }
621
0
  if (msg)
622
0
    sc_log(card->ctx, "%s", msg);
623
0
        LOG_FUNC_RETURN(card->ctx, res);
624
0
}
625
626
/**
627
 * Retrieve serial number (7 bytes) from card.
628
 *
629
 * This is done by mean of an special APDU command described
630
 * in the DNIe Reference Manual
631
 *
632
 * @param card pointer to card description
633
 * @param serial where to store data retrieved
634
 * @return SC_SUCCESS if ok; else error code
635
 */
636
static int dnie_get_serialnr(sc_card_t * card, sc_serial_number_t * serial)
637
0
{
638
0
  int result;
639
0
  sc_apdu_t apdu;
640
0
  u8 rbuf[MAX_RESP_BUFFER_SIZE];
641
0
  if ((card == NULL) || (card->ctx == NULL) || (serial == NULL))
642
0
    return SC_ERROR_INVALID_ARGUMENTS;
643
644
0
  LOG_FUNC_CALLED(card->ctx);
645
0
  if (card->type != SC_CARD_TYPE_DNIE_USER)
646
0
    return SC_ERROR_NOT_SUPPORTED;
647
  /* if serial number is cached, use it */
648
0
  if (card->serialnr.len) {
649
0
    memcpy(serial, &card->serialnr, sizeof(*serial));
650
0
    sc_log_hex(card->ctx, "Serial Number (cached)", serial->value, serial->len);
651
0
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
652
0
  }
653
  /* not cached, retrieve it by mean of an APDU */
654
  /* official driver read 0x11 bytes, but only uses 7. Manual says just 7 (for le) */
655
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xb8, 0x00, 0x00, 0x07, 0,
656
0
          rbuf, sizeof(rbuf), NULL, 0);
657
0
  apdu.cla = 0x90;  /* proprietary cmd */
658
  /* send apdu */
659
0
  result = sc_transmit_apdu(card, &apdu);
660
0
  if (result != SC_SUCCESS) {
661
0
    LOG_TEST_RET(card->ctx, result, "APDU transmit failed");
662
0
  }
663
0
  if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00)
664
0
    return SC_ERROR_INTERNAL;
665
  /* cache serial number */
666
0
  memcpy(card->serialnr.value, apdu.resp, 7 * sizeof(u8));
667
0
  card->serialnr.len = 7 * sizeof(u8);
668
  /* TODO: fill Issuer Identification Number data with proper (ATR?) info */
669
  /*
670
     card->serialnr.iin.mii=;
671
     card->serialnr.iin.country=;
672
     card->serialnr.iin.issuer_id=;
673
   */
674
  /* copy and return serial number */
675
0
  memcpy(serial, &card->serialnr, sizeof(*serial));
676
0
  sc_log_hex(card->ctx, "Serial Number (apdu)", serial->value, serial->len);
677
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
678
0
}
679
680
/**
681
 * Remove the binary data in the cache.
682
 *
683
 * It frees memory if allocated and resets pointer and length.
684
 * It only touches the private binary cache variables, not the sc_card information.
685
 *
686
 * @param data pointer to dnie private data
687
 */
688
static void dnie_clear_cache(dnie_private_data_t * data)
689
0
{
690
0
  if (data == NULL) return;
691
0
  if (data->cache != NULL)
692
0
    free(data->cache);
693
0
  data->cache = NULL;
694
0
  data->cachelen = 0;
695
0
}
696
697
/**
698
 * Set sc_card flags according to DNIe requirements.
699
 *
700
 * Used in card initialization.
701
 *
702
 * @param card pointer to card data
703
 */
704
static void init_flags(struct sc_card *card)
705
0
{
706
0
  unsigned long algoflags;
707
  /* set up flags according documentation */
708
0
  card->name = DNIE_CHIP_SHORTNAME;
709
0
  card->cla = 0x00; /* default APDU class (interindustry) */
710
0
  card->caps |= SC_CARD_CAP_RNG; /* we have a random number generator */
711
0
  card->max_send_size = (255 - 12); /* manual says 255, but we need 12 extra bytes when encoding */
712
0
  card->max_recv_size = 255;
713
714
  /* RSA Support with PKCS1.5 padding */
715
0
  algoflags = SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_PAD_PKCS1;
716
0
  _sc_card_add_rsa_alg(card, 1024, algoflags, 0);
717
0
  _sc_card_add_rsa_alg(card, 1920, algoflags, 0);
718
0
  _sc_card_add_rsa_alg(card, 2048, algoflags, 0);
719
0
}
720
721
/**************************** sc_card_operations **********************/
722
723
/* Generic operations */
724
725
/**
726
 * Check if provided card can be handled by OpenDNIe.
727
 *
728
 * Called in sc_connect_card().  Must return 1, if the current
729
 * card can be handled with this driver, or 0 otherwise.  ATR
730
 * field of the sc_card struct is filled in before calling
731
 * this function.
732
 * do not declare static, as used by pkcs15-dnie module
733
 *
734
 * @param card Pointer to card structure
735
 * @return on card matching 0 if not match; negative return means error
736
 */
737
int dnie_match_card(struct sc_card *card)
738
0
{
739
0
  int result = 0;
740
0
  int matched = -1;
741
0
  LOG_FUNC_CALLED(card->ctx);
742
0
  matched = _sc_match_atr(card, dnie_atrs, &card->type);
743
0
  result = (matched >= 0) ? 1 : 0;
744
0
  LOG_FUNC_RETURN(card->ctx, result);
745
0
}
746
747
static int dnie_sm_free_wrapped_apdu(struct sc_card *card,
748
    struct sc_apdu *plain, struct sc_apdu **sm_apdu)
749
0
{
750
0
  struct sc_context *ctx = card->ctx;
751
0
  cwa_provider_t *provider = NULL;
752
0
  int rv = SC_SUCCESS;
753
754
0
  LOG_FUNC_CALLED(ctx);
755
0
  provider = GET_DNIE_PRIV_DATA(card)->cwa_provider;
756
0
  if (!sm_apdu)
757
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
758
0
  if (!(*sm_apdu))
759
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
760
761
0
  if ((*sm_apdu) != plain) {
762
0
    rv = cwa_decode_response(card, provider, *sm_apdu);
763
0
    if (plain && rv == SC_SUCCESS) {
764
0
      if (plain->resp) {
765
        /* copy the response into the original resp buffer */
766
0
        if ((*sm_apdu)->resplen <= plain->resplen) {
767
0
          memcpy(plain->resp, (*sm_apdu)->resp, (*sm_apdu)->resplen);
768
0
          plain->resplen = (*sm_apdu)->resplen;
769
0
        } else {
770
0
          sc_log(card->ctx, "Invalid initial length,"
771
0
              " needed %"SC_FORMAT_LEN_SIZE_T"u bytes"
772
0
              " but has %"SC_FORMAT_LEN_SIZE_T"u",
773
0
              (*sm_apdu)->resplen, plain->resplen);
774
0
          rv = SC_ERROR_BUFFER_TOO_SMALL;
775
0
        }
776
0
      }
777
0
      plain->sw1 = (*sm_apdu)->sw1;
778
0
      plain->sw2 = (*sm_apdu)->sw2;
779
0
    }
780
0
    if (plain == NULL || (*sm_apdu)->data != plain->data)
781
0
      free((unsigned char *) (*sm_apdu)->data);
782
0
    if (plain == NULL || (*sm_apdu)->resp != plain->resp)
783
0
      free((*sm_apdu)->resp);
784
0
    free(*sm_apdu);
785
0
  }
786
0
  *sm_apdu = NULL;
787
788
0
  LOG_FUNC_RETURN(ctx, rv);
789
0
}
790
791
static int dnie_sm_get_wrapped_apdu(struct sc_card *card,
792
    struct sc_apdu *plain, struct sc_apdu **sm_apdu)
793
0
{
794
0
  struct sc_context *ctx = card->ctx;
795
0
  cwa_provider_t *provider = NULL;
796
0
  int rv = SC_SUCCESS;
797
798
0
  LOG_FUNC_CALLED(ctx);
799
0
  if (!plain || !sm_apdu)
800
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
801
802
0
  provider = GET_DNIE_PRIV_DATA(card)->cwa_provider;
803
804
0
  if (((plain->cla & 0x0C) == 0) && (plain->ins != 0xC0)) {
805
0
    *sm_apdu = calloc(1, sizeof(struct sc_apdu));
806
0
    if (!(*sm_apdu))
807
0
      return SC_ERROR_OUT_OF_MEMORY;
808
809
0
    rv = cwa_encode_apdu(card, provider, plain, *sm_apdu);
810
811
0
    if (rv != SC_SUCCESS) {
812
0
      dnie_sm_free_wrapped_apdu(card, plain, sm_apdu);
813
0
    }
814
0
  } else
815
0
    *sm_apdu = plain;
816
817
0
  LOG_FUNC_RETURN(ctx, rv);
818
0
}
819
820
/**
821
 * OpenDNIe card structures initialization.
822
 *
823
 * Called when ATR of the inserted card matches an entry in ATR
824
 * table.  May return SC_ERROR_INVALID_CARD to indicate that
825
 * the card cannot be handled with this driver.
826
 *
827
 * @param card Pointer to card structure
828
 * @return SC_SUCCES if ok; else error code
829
 */
830
static int dnie_init(struct sc_card *card)
831
0
{
832
0
  int res = SC_SUCCESS;
833
0
  sc_context_t *ctx = card->ctx;
834
0
  cwa_provider_t *provider = NULL;
835
836
0
  LOG_FUNC_CALLED(ctx);
837
838
  /* if recognized as terminated DNIe card, return error */
839
0
  if (card->type == SC_CARD_TYPE_DNIE_TERMINATED)
840
0
      LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "DNIe card is terminated.");
841
842
  /* create and initialize cwa-dnie provider*/
843
0
  provider = dnie_get_cwa_provider(card);
844
0
  if (!provider)
845
0
      LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "Error initializing cwa-dnie provider");
846
847
  /** Secure messaging initialization section **/
848
0
  memset(&(card->sm_ctx), 0, sizeof(sm_context_t));
849
0
  card->sm_ctx.ops.get_sm_apdu = dnie_sm_get_wrapped_apdu;
850
0
  card->sm_ctx.ops.free_sm_apdu = dnie_sm_free_wrapped_apdu;
851
0
  card->sm_ctx.sm_mode = SM_MODE_NONE;
852
853
0
  res = cwa_create_secure_channel(card, provider, CWA_SM_OFF);
854
0
  if (res < 0)
855
0
    free(provider);
856
0
  LOG_TEST_RET(card->ctx, res, "Failure resetting CWA secure channel.");
857
858
  /* initialize private data */
859
0
  card->drv_data = calloc(1, sizeof(dnie_private_data_t));
860
0
  if (card->drv_data == NULL) {
861
0
    free(provider);
862
0
      LOG_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "Could not allocate DNIe private data.");
863
0
  }
864
865
#ifdef ENABLE_DNIE_UI
866
  /* read environment from configuration file */
867
  res = dnie_get_environment(card, &(GET_DNIE_UI_CTX(card)));
868
  if (res != SC_SUCCESS) {
869
    free(card->drv_data);
870
    free(provider);
871
    LOG_TEST_RET(card->ctx, res, "Failure reading DNIe environment.");
872
  }
873
#endif
874
875
0
  init_flags(card);
876
877
0
  GET_DNIE_PRIV_DATA(card)->cwa_provider = provider;
878
879
0
  LOG_FUNC_RETURN(card->ctx, res);
880
0
}
881
882
/**
883
 * De-initialization routine.
884
 *
885
 * Called when the card object is being freed.  finish() has to
886
 * deallocate all possible private data.
887
 *
888
 * @param card Pointer to card driver data structure
889
 * @return SC_SUCCESS if ok; else error code
890
 */
891
static int dnie_finish(struct sc_card *card)
892
0
{
893
0
  int result = SC_SUCCESS;
894
0
  LOG_FUNC_CALLED(card->ctx);
895
0
  dnie_clear_cache(GET_DNIE_PRIV_DATA(card));
896
  /* disable sm channel if established */
897
0
  result = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_OFF);
898
0
  free(GET_DNIE_PRIV_DATA(card)->cwa_provider);
899
0
  free(card->drv_data);
900
0
  LOG_FUNC_RETURN(card->ctx, result);
901
0
}
902
903
/* ISO 7816-4 functions */
904
905
/**
906
 * Check whether data are compressed.
907
 *
908
 * @param card pointer to sc_card_t structure
909
 * @param from buffer to get data from
910
 * @param len buffer length
911
 * @return 1 if data are compressed, 0 otherwise; len points to expected length of decompressed data
912
 */
913
914
static int dnie_is_compressed(sc_card_t * card, u8 * from, size_t len)
915
0
{
916
0
#ifdef ENABLE_ZLIB
917
0
  size_t uncompressed = 0L;
918
0
  size_t compressed = 0L;
919
920
0
  if (!card || !card->ctx || !from || !len)
921
0
    return 0;
922
0
  LOG_FUNC_CALLED(card->ctx);
923
924
  /* if data size not enough for compression header assume uncompressed */
925
0
  if (len < 8)
926
0
    goto compress_exit;
927
  /* evaluate compressed an uncompressed sizes (little endian format) */
928
0
  uncompressed = lebytes2ulong(from);
929
0
  compressed = lebytes2ulong(from + 4);
930
  /* if compressed size doesn't match data length assume not compressed */
931
0
  if (compressed != len - 8)
932
0
    goto compress_exit;
933
  /* if compressed size greater than uncompressed, assume uncompressed data */
934
0
  if (uncompressed < compressed)
935
0
    goto compress_exit;
936
  /* Do not try to allocate insane size if we receive bogus data */
937
0
  if (uncompressed > MAX_FILE_SIZE)
938
0
    goto compress_exit;
939
940
0
  sc_log(card->ctx, "Data seems to be compressed.");
941
0
  return 1;
942
0
compress_exit:
943
0
#endif
944
945
0
  sc_log(card->ctx, "Data not compressed.");
946
0
  return 0;
947
0
}
948
949
/**
950
 * Fill file cache for read_binary() operation.
951
 *
952
 * Fill a temporary buffer by mean of consecutive calls to read_binary()
953
 * until card sends eof
954
 *
955
 * DNIe card stores user certificates in compressed format. so we need
956
 * some way to detect and uncompress on-the-fly compressed files, to
957
 * let read_binary() work transparently.
958
 * This is the main goal of this routine: create an in-memory buffer
959
 * for read_binary operation, filling this buffer on first read_binary()
960
 * call, and uncompress data if compression detected. Further
961
 * read_binary() calls then make use of cached data, instead
962
 * of accessing the card
963
 *
964
 * @param card Pointer to card structure
965
 * @return SC_SUCCESS if OK; else error code
966
 */
967
static int dnie_fill_cache(sc_card_t * card,unsigned long *flags)
968
0
{
969
0
  u8 tmp[MAX_RESP_BUFFER_SIZE];
970
0
  sc_apdu_t apdu;
971
0
  size_t count = 0;
972
0
  size_t len = 0;
973
0
  u8 *buffer = NULL;
974
0
  u8 *p;
975
0
  sc_context_t *ctx = NULL;
976
977
0
  if (!card || !card->ctx)
978
0
    return SC_ERROR_INVALID_ARGUMENTS;
979
0
  ctx = card->ctx;
980
981
0
  LOG_FUNC_CALLED(ctx);
982
983
  /* mark cache empty */
984
0
  dnie_clear_cache(GET_DNIE_PRIV_DATA(card));
985
986
  /* initialize apdu */
987
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, 0x00, 0x00);
988
989
  /* try to read_binary while data available but never long than 32767 */
990
0
  count = card->max_recv_size;
991
0
  for (len = 0; len < 0x7fff;) {
992
0
    int r = SC_SUCCESS;
993
    /* fill apdu */
994
0
    apdu.p1 = 0xff & (len >> 8);
995
0
    apdu.p2 = 0xff & len;
996
0
    apdu.le = count;
997
0
    apdu.resplen = MAX_RESP_BUFFER_SIZE;
998
0
    apdu.resp = tmp;
999
    /* transmit apdu */
1000
0
    r = sc_transmit_apdu(card, &apdu);
1001
0
    if (r != SC_SUCCESS) {
1002
0
      free(buffer);
1003
0
      if (apdu.resp != tmp)
1004
0
        free(apdu.resp);
1005
0
      sc_log(ctx, "read_binary() APDU transmit failed");
1006
0
      LOG_FUNC_RETURN(ctx, r);
1007
0
    }
1008
0
    if (apdu.resplen == 0) {
1009
      /* on no data received, check if requested len is longer than
1010
         available data in card. If so, ask just for remaining data */
1011
0
      r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1012
0
      if (r == SC_ERROR_WRONG_LENGTH) {
1013
0
        count = 0xff & apdu.sw2;
1014
0
        if (count != 0) {
1015
0
          if (apdu.resp != tmp)
1016
0
            free(apdu.resp);
1017
0
          continue; /* read again with correct size */
1018
0
        }
1019
0
        goto read_done; /* no more data to read */
1020
0
      }
1021
0
      if (r == SC_ERROR_INCORRECT_PARAMETERS)
1022
0
        goto read_done;
1023
0
      free(buffer);
1024
0
      if (apdu.resp != tmp)
1025
0
        free(apdu.resp);
1026
0
      LOG_FUNC_RETURN(ctx, r); /* arriving here means response error */
1027
0
    }
1028
    /* copy received data into buffer. realloc() if not enough space */
1029
0
    count = apdu.resplen;
1030
0
    p = realloc(buffer, len + count);
1031
0
    if (!p) {
1032
0
      free(buffer);
1033
0
      free((void *)apdu.data);
1034
0
      if (apdu.resp != tmp)
1035
0
        free(apdu.resp);
1036
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1037
0
    }
1038
0
    buffer = p;
1039
0
    memcpy(buffer + len, apdu.resp, count);
1040
0
    if (apdu.resp != tmp) {
1041
0
      free(apdu.resp);
1042
0
      apdu.resp = tmp;
1043
0
    }
1044
0
    len += count;
1045
0
    if (count != card->max_recv_size)
1046
0
      goto read_done;
1047
0
  }
1048
1049
0
 read_done:
1050
0
  free((void *)apdu.data);
1051
0
  if (apdu.resp != tmp)
1052
0
    free(apdu.resp);
1053
1054
0
  if (dnie_is_compressed(card, buffer, len)) {
1055
0
    if (flags)
1056
0
      *flags |= SC_FILE_FLAG_COMPRESSED_ZLIB;
1057
    /* Remove first 8 bytes with compression info*/
1058
0
    len -= 8;
1059
0
    p = malloc(len);
1060
0
    if (!p) {
1061
0
      free(buffer);
1062
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1063
0
    }
1064
0
    memcpy(p, buffer + 8, len);
1065
0
    free(buffer);
1066
0
    buffer = p;
1067
0
  }
1068
1069
1070
  /* ok: as final step, set correct cache data into dnie_priv structures */
1071
0
  GET_DNIE_PRIV_DATA(card)->cache = buffer;
1072
0
  GET_DNIE_PRIV_DATA(card)->cachelen = len;
1073
0
  sc_log(ctx,
1074
0
         "fill_cache() done. length '%"SC_FORMAT_LEN_SIZE_T"u' bytes",
1075
0
         len);
1076
0
  LOG_FUNC_RETURN(ctx, (int)len);
1077
0
}
1078
1079
/**
1080
 * OpenDNIe implementation of read_binary().
1081
 *
1082
 * Reads a binary stream from card by mean of READ BINARY iso command
1083
 * Creates and handle a cache to allow data uncompression
1084
 *
1085
 * @param card pointer to sc_card_t structure
1086
 * @param idx offset from card file to ask data for
1087
 * @param buf where to store read data. must be non null
1088
 * @param count number of bytes to read
1089
 * @param flags. not used
1090
 * @return number of bytes read, 0 on EOF, error code on error
1091
 */
1092
static int dnie_read_binary(struct sc_card *card,
1093
          unsigned int idx,
1094
          u8 * buf, size_t count, unsigned long *flags)
1095
0
{
1096
0
  size_t res = 0;
1097
0
  int rc;
1098
0
  sc_context_t *ctx = NULL;
1099
  /* preliminary checks */
1100
0
  if (!card || !card->ctx || !buf || (count <= 0))
1101
0
    return SC_ERROR_INVALID_ARGUMENTS;
1102
0
  ctx = card->ctx;
1103
1104
0
  LOG_FUNC_CALLED(ctx);
1105
0
  if (idx == 0 || GET_DNIE_PRIV_DATA(card)->cache == NULL) {
1106
    /* on first block or no cache, try to fill */
1107
0
    rc = dnie_fill_cache(card, flags);
1108
0
    if (rc < 0) {
1109
0
      sc_log(ctx, "Cannot fill cache. using iso_read_binary()");
1110
0
      return iso_ops->read_binary(card, idx, buf, count, flags);
1111
0
    }
1112
0
  }
1113
0
  if (idx >= GET_DNIE_PRIV_DATA(card)->cachelen)
1114
0
    return 0; /* at eof */
1115
0
  res = MIN(count, GET_DNIE_PRIV_DATA(card)->cachelen - idx);  /* eval how many bytes to read */
1116
0
  memcpy(buf, GET_DNIE_PRIV_DATA(card)->cache + idx, res);  /* copy data from buffer */
1117
0
  sc_log(ctx, "dnie_read_binary() '%zu' bytes", res);
1118
0
  LOG_FUNC_RETURN(ctx, (int)res);
1119
0
}
1120
1121
/**
1122
 * Send apdu to the card
1123
 *
1124
 * @param card pointer to sc_card_t structure
1125
 * @param path
1126
 * @param pathlen
1127
 * @param p1
1128
 * @param file_out
1129
 * @return result
1130
 */
1131
static int dnie_compose_and_send_apdu(sc_card_t *card, const u8 *path, size_t pathlen,
1132
          u8 p1, sc_file_t **file_out)
1133
0
{
1134
0
  int res = 0;
1135
0
  sc_apdu_t apdu;
1136
0
  u8 rbuf[MAX_RESP_BUFFER_SIZE];
1137
0
  sc_context_t *ctx = NULL;
1138
1139
0
  if (!card || !card->ctx)
1140
0
    return SC_ERROR_INVALID_ARGUMENTS;
1141
0
  ctx = card->ctx;
1142
1143
0
  LOG_FUNC_CALLED(ctx);
1144
1145
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, p1, 0,
1146
0
          sc_get_max_recv_size(card), pathlen,
1147
0
          rbuf, sizeof(rbuf), path, pathlen);
1148
0
  if (p1 == 3)
1149
0
    apdu.cse= SC_APDU_CASE_1;
1150
1151
0
  if (file_out == NULL)
1152
0
    apdu.cse = SC_APDU_CASE_4_SHORT;
1153
1154
0
  res = sc_transmit_apdu(card, &apdu);
1155
0
  if ((res != SC_SUCCESS) || (file_out == NULL))
1156
0
    LOG_TEST_RET(ctx, res, "SelectFile() APDU transmit failed");
1157
0
  if (file_out == NULL) {
1158
0
    if (apdu.sw1 == 0x61)
1159
0
      SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, 0);
1160
0
    SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,
1161
0
             sc_check_sw(card, apdu.sw1, apdu.sw2));
1162
0
  }
1163
1164
  /* analyze response. if FCI, try to parse */
1165
0
  res = sc_check_sw(card, apdu.sw1, apdu.sw2);
1166
0
  if (res != SC_SUCCESS) {
1167
0
    LOG_TEST_RET(ctx, res, "SelectFile() check_sw failed");
1168
0
  }
1169
0
  if ((apdu.resplen < 2) || (apdu.resp[0] == 0x00)) {
1170
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1171
0
  }
1172
1173
0
  if (file_out) {
1174
    /* finally process FCI response */
1175
0
    size_t len = apdu.resp[1];
1176
0
    sc_file_free(*file_out);
1177
0
    *file_out = sc_file_new();
1178
0
    if (*file_out == NULL) {
1179
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1180
0
    }
1181
0
    if (apdu.resplen - 2 < len || len < 1) {
1182
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1183
0
    }
1184
0
    res = card->ops->process_fci(card, *file_out, apdu.resp + 2, len);
1185
0
  }
1186
0
  LOG_FUNC_RETURN(ctx, res);
1187
0
}
1188
1189
/**
1190
 * OpenDNIe implementation of Select_File().
1191
 *
1192
 * Select_file: Does the equivalent of SELECT FILE command specified
1193
 *   in ISO7816-4. Stores information about the selected file to
1194
 *   <file>, if not NULL.
1195
 *
1196
 * SELECT file in DNIe is a bit tricky:
1197
 * - only handles some types:
1198
 * -- <strong>SC_PATH_TYPE_FILE_ID</strong> 2-byte long file ID
1199
 * -- <strong>SC_PATH_TYPE_DF_NAME</strong> named DF's
1200
 * -- <strong>SC_PATH_TYPE_PARENT</strong>  jump to parent DF of current EF/DF - undocumented in DNIe manual
1201
 * -- other file types are marked as unsupported
1202
 *
1203
 * - Also MF must be addressed by their Name, not their ID
1204
 * So some magic is needed:
1205
 * - split <strong>SC_PATH_TYPE_PATH</strong> into several calls to each 2-byte data file ID
1206
 * - Translate initial file id 3F00 to be DF name 'Master.File'
1207
 *
1208
 * Also, Response always handle a proprietary FCI info, so
1209
 * need to handle it manually via dnie_process_fci()
1210
 *
1211
 * @param card Pointer to Card Structure
1212
 * @param in_path Path ID to be selected
1213
 * @param file_out where to store fci information
1214
 * @return SC_SUCCESS if ok; else error code
1215
 */
1216
static int dnie_select_file(struct sc_card *card,
1217
          const struct sc_path *in_path,
1218
          struct sc_file **file_out)
1219
0
{
1220
0
  int res = SC_SUCCESS;
1221
0
  sc_context_t *ctx = NULL;
1222
0
  unsigned char tmp_path[sizeof(DNIE_MF_NAME)];
1223
0
  size_t reminder = 0;
1224
1225
0
  if (!card || !card->ctx || !in_path)
1226
0
    return SC_ERROR_INVALID_ARGUMENTS;
1227
0
  ctx = card->ctx;
1228
1229
0
  LOG_FUNC_CALLED(ctx);
1230
1231
0
  switch (in_path->type) {
1232
0
  case SC_PATH_TYPE_FILE_ID:
1233
    /* pathlen must be of len=2 */
1234
    /*
1235
     * gscriptor shows that DNIe also handles
1236
     * Select child DF (p1=1) and Select EF (p1=2),
1237
     * but we'll use P1=0 as general solution for all cases
1238
     *
1239
     * According iso7816-4 sect 7.1.1  pathlen==0 implies
1240
     * select MF, but this case is not supported by DNIe
1241
     */
1242
0
    if (in_path->len != 2)
1243
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1244
0
    sc_log_hex(ctx, "select_file(ID)", in_path->value, in_path->len);
1245
0
    res = dnie_compose_and_send_apdu(card, in_path->value, in_path->len, 0, file_out);
1246
0
    break;
1247
0
  case SC_PATH_TYPE_DF_NAME:
1248
0
    sc_log_hex(ctx, "select_file(NAME)", in_path->value, in_path->len);
1249
0
    res = dnie_compose_and_send_apdu(card, in_path->value, in_path->len, 4, file_out);
1250
0
    break;
1251
0
  case SC_PATH_TYPE_PATH:
1252
0
    if ((in_path->len == 0) || ((in_path->len & 1) != 0)) /* not divisible by 2 */
1253
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1254
1255
0
    sc_log_hex(ctx, "select_file(PATH): requested", in_path->value, in_path->len);
1256
1257
    /* convert to SC_PATH_TYPE_FILE_ID */
1258
0
    res = sc_lock(card); /* lock to ensure path traversal */
1259
0
    LOG_TEST_RET(ctx, res, "sc_lock() failed");
1260
0
    if (memcmp(in_path->value, "\x3F\x00", 2) == 0) {
1261
      /* if MF, use the name as path */
1262
0
      strcpy((char *)tmp_path, DNIE_MF_NAME);
1263
0
      sc_log_hex(ctx, "select_file(NAME): requested", tmp_path, sizeof(DNIE_MF_NAME) - 1);
1264
0
      res = dnie_compose_and_send_apdu(card, tmp_path, sizeof(DNIE_MF_NAME) - 1, 4, file_out);
1265
0
      if (res != SC_SUCCESS) {
1266
0
        sc_unlock(card);
1267
0
        LOG_TEST_RET(ctx, res, "select_file(NAME) failed");
1268
0
      }
1269
0
      tmp_path[2] = 0;
1270
0
      reminder = in_path->len - 2;
1271
0
    } else {
1272
0
      tmp_path[2] = 0;
1273
0
      reminder = in_path->len;
1274
0
    }
1275
0
    while (reminder > 0) {
1276
0
      tmp_path[0] = in_path->value[in_path->len - reminder];
1277
0
      tmp_path[1] = in_path->value[1 + in_path->len - reminder];
1278
0
      sc_log(ctx, "select_file(PATH): requested:%s ", sc_dump_hex(tmp_path, 2));
1279
0
      res = dnie_compose_and_send_apdu(card, tmp_path, 2, 0, file_out);
1280
0
      if (res != SC_SUCCESS) {
1281
0
        sc_unlock(card);
1282
0
        LOG_TEST_RET(ctx, res, "select_file(PATH) failed");
1283
0
      }
1284
0
      reminder -= 2;
1285
0
    }
1286
0
    sc_unlock(card);
1287
0
    break;
1288
0
  case SC_PATH_TYPE_FROM_CURRENT:
1289
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_NO_CARD_SUPPORT);
1290
0
    break;
1291
0
  case SC_PATH_TYPE_PARENT:
1292
    /* Hey!! Manual doesn't says anything on this, but
1293
     * gscriptor shows that this type is supported
1294
     */
1295
0
    sc_log(ctx, "select_file(PARENT)");
1296
    /* according iso7816-4 sect 7.1.1 shouldn't have any parameters */
1297
0
    if (in_path->len != 0)
1298
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1299
0
    res = dnie_compose_and_send_apdu(card, NULL, 0, 3, file_out);
1300
0
    break;
1301
0
  default:
1302
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1303
0
    break;
1304
0
  }
1305
1306
  /* as last step clear data cache and return */
1307
0
  dnie_clear_cache(GET_DNIE_PRIV_DATA(card));
1308
0
  LOG_FUNC_RETURN(ctx, res);
1309
0
}
1310
1311
/**
1312
 * OpenDNIe implementation of Get_Challenge() command.
1313
 *
1314
 * Get challenge: retrieve 8 random bytes for any further use
1315
 * (eg perform an external authenticate command)
1316
 *
1317
 * NOTE:
1318
 * Official driver redundantly sets SM before execute this command
1319
 * No reason to do it, as is needed to do SM handshake...
1320
 * Also: official driver reads in blocks of 20 bytes.
1321
 * Why? Manual and iso-7816-4 states that only 8 bytes
1322
 * are required... so we will obey Manual
1323
 *
1324
 * @param card Pointer to card Structure
1325
 * @param rnd Where to store challenge
1326
 * @param len requested challenge length
1327
 * @return SC_SUCCESS if OK; else error code
1328
 */
1329
1330
static int dnie_get_challenge(struct sc_card *card, u8 * rnd, size_t len)
1331
0
{
1332
  /* As DNIe cannot handle other data length than 0x08 and 0x14 */
1333
0
  u8 rbuf[8];
1334
0
  size_t out_len;
1335
0
  int r;
1336
1337
0
  LOG_FUNC_CALLED(card->ctx);
1338
1339
0
  r = iso_ops->get_challenge(card, rbuf, sizeof rbuf);
1340
0
  LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed");
1341
1342
0
  if (len < (size_t) r) {
1343
0
    out_len = len;
1344
0
  } else {
1345
0
    out_len = (size_t) r;
1346
0
  }
1347
0
  memcpy(rnd, rbuf, out_len);
1348
1349
0
  LOG_FUNC_RETURN(card->ctx, (int) out_len);
1350
0
}
1351
1352
/*
1353
 * ISO 7816-8 functions
1354
 */
1355
1356
/**
1357
 * OpenDNIe implementation of Logout() card_driver function.
1358
 *
1359
 *  Resets all access rights that were gained. Disable SM
1360
 *
1361
 * @param card Pointer to Card Structure
1362
 * @return SC_SUCCESS if OK; else error code
1363
 */
1364
static int dnie_logout(struct sc_card *card)
1365
0
{
1366
0
  int result = SC_SUCCESS;
1367
1368
0
  if ((card == NULL) || (card->ctx == NULL))
1369
0
    return SC_ERROR_INVALID_ARGUMENTS;
1370
1371
0
  LOG_FUNC_CALLED(card->ctx);
1372
0
  if (card->sm_ctx.sm_mode != SM_MODE_NONE) {
1373
    /* mark the channel as closed */
1374
0
    result = cwa_create_secure_channel(card,
1375
0
      GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_OFF);
1376
0
    LOG_TEST_RET(card->ctx, result, "Cannot close the secure channel");
1377
0
  }
1378
1379
0
  LOG_FUNC_RETURN(card->ctx, result);
1380
0
}
1381
1382
/**
1383
 * Implementation of Set_Security_Environment card driver command.
1384
 *
1385
 * Initializes the security environment on card
1386
 *   according to <env>, and stores the environment as <se_num> on the
1387
 *   card. If se_num <= 0, the environment will not be stored.
1388
 *   Notice that OpenDNIe SM handling requires a buffer longer than
1389
 *   provided for this command; so special apdu is used in cwa code
1390
 *
1391
 * @param card Pointer to card driver Structure
1392
 * @param env Pointer to security environment data
1393
 * @param num: which Card Security environment to use (ignored in OpenDNIe)
1394
 * @return SC_SUCCESS if OK; else error code
1395
 *
1396
 * TODO: mix these code with SM set_security_env operations
1397
 *
1398
 */
1399
static int dnie_set_security_env(struct sc_card *card,
1400
         const struct sc_security_env *env, int se_num)
1401
0
{
1402
0
  sc_apdu_t apdu;
1403
0
  u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; /* buffer to compose apdu data */
1404
0
  u8 rbuf[MAX_RESP_BUFFER_SIZE];
1405
0
  u8 *p = sbuf;
1406
0
  int result = SC_SUCCESS;
1407
0
  if ((card == NULL) || (card->ctx == NULL) || (env == NULL))
1408
0
    return SC_ERROR_INVALID_ARGUMENTS;
1409
0
  LOG_FUNC_CALLED(card->ctx);
1410
0
  if (se_num!=0) {
1411
0
    sc_log(card->ctx,"DNIe cannot handle several security envs");
1412
0
    LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS);
1413
0
  }
1414
1415
  /* Secure Channel should be on here, if not means an error */
1416
  /*
1417
  result =
1418
      cwa_create_secure_channel(card, dnie_priv.provider, CWA_SM_WARM);
1419
  LOG_TEST_RET(card->ctx, result,
1420
         "set_security_env(); Cannot establish SM");
1421
  */
1422
1423
  /* check for algorithms */
1424
0
  if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) {
1425
0
    sc_log(card->ctx, "checking algorithms");
1426
0
    switch (env->algorithm) {
1427
0
    case SC_ALGORITHM_RSA:
1428
0
      result = SC_SUCCESS;
1429
0
      break;
1430
0
    case SC_ALGORITHM_EC:
1431
0
    case SC_ALGORITHM_GOSTR3410:
1432
0
    default:
1433
0
      result = SC_ERROR_NOT_SUPPORTED;
1434
0
      break;
1435
0
    }
1436
0
    LOG_TEST_RET(card->ctx, result, "Unsupported algorithm");
1437
0
    if ((env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1) == 0) {
1438
0
      result = SC_ERROR_NOT_SUPPORTED;
1439
      /* TODO:
1440
       * Manual says that only RSA with SHA1 is supported, but found
1441
       * some docs where states that SHA256 is also handled
1442
       */
1443
0
    }
1444
0
    LOG_TEST_RET(card->ctx, result,
1445
0
           "Only RSA with SHA1 is supported");
1446
    /* ok: insert algorithm reference into buffer */
1447
0
    *p++ = 0x80;  /* algorithm reference tag */
1448
0
    *p++ = 0x01;  /* len */
1449
0
    *p++ = env->algorithm_ref & 0xff; /* val */
1450
0
  }
1451
1452
  /* check for key references */
1453
0
  if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) {
1454
0
    sc_log(card->ctx, "checking key references");
1455
0
    if (env->key_ref_len != 1) {
1456
0
      sc_log(card->ctx, "Null or invalid key ID reference");
1457
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1458
0
    }
1459
0
    sc_log(card->ctx, "Using key reference '%s'",
1460
0
           sc_dump_hex(env->key_ref, env->key_ref_len));
1461
    /* ok: insert key reference into buffer */
1462
    /* notice that DNIe uses same key reference for pubk and privk */
1463
1464
    /* see cwa14890-2 sect B.1 about Control Reference Template Tags */
1465
0
    *p++ = 0x84;  /* TODO: make proper detection of 0x83 /0x84 tag usage */
1466
0
    *p++ = 0x02;  /* len  */
1467
0
    *p++ = 0x01;  /* key ID prefix (MSB byte of keyFile ID) */
1468
0
    memcpy(p, env->key_ref, env->key_ref_len);  /* in DNIe key_ref_len=1 */
1469
0
    p += env->key_ref_len;
1470
    /* store key reference into private data */
1471
0
    GET_DNIE_PRIV_DATA(card)->rsa_key_ref = 0xff & env->key_ref[0];
1472
0
  }
1473
1474
  /* create and format apdu */
1475
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x22, 0x00, 0x00, 255, p - sbuf,
1476
0
          rbuf, MAX_RESP_BUFFER_SIZE, sbuf, p - sbuf);
1477
1478
  /* check and perform operation */
1479
0
  switch (env->operation) {
1480
0
  case SC_SEC_OPERATION_DECIPHER:
1481
    /* TODO: Manual is unsure about if (de)cipher() is supported */
1482
0
    apdu.p1 = 0xC1;
1483
0
    apdu.p2 = 0xB8;
1484
0
    break;
1485
0
  case SC_SEC_OPERATION_SIGN:
1486
0
    apdu.p1 = 0x41; /* SET; internal operation */
1487
0
    apdu.p2 = 0xB6; /* Template for Digital Signature */
1488
0
    break;
1489
0
  default:
1490
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1491
0
  }
1492
1493
  /* Notice that Manual states that DNIE only allows handle of
1494
   * current security environment, so se_num is ignored, and
1495
   * store sec env apdu (00 22 F2 se_num) command will not be issued */
1496
1497
  /* send composed apdu and parse result */
1498
0
  result = sc_transmit_apdu(card, &apdu);
1499
0
  LOG_TEST_RET(card->ctx, result, "Set Security Environment failed");
1500
0
  result = sc_check_sw(card, apdu.sw1, apdu.sw2);
1501
1502
0
  LOG_FUNC_RETURN(card->ctx, result);
1503
0
}
1504
1505
/**
1506
 * OpenDNIe implementation of Decipher() card driver operation.
1507
 *
1508
 * Engages the deciphering operation.  Card will use the
1509
 * security environment set in a call to set_security_env or
1510
 * restore_security_env.
1511
 *
1512
 * Notice that DNIe manual doesn't say anything about crypt/decrypt
1513
 * operations. So this code is based on ISO standards and still needs
1514
 * to be checked
1515
 *
1516
 * ADD: seems that DNIe supports a minimal cipher/decipher operation
1517
 * but restricted to 1024 data chunks . Need more info and tests
1518
 *
1519
 * @param card Pointer to Card Driver Structure
1520
 * @param crgram cryptogram to be (de)ciphered
1521
 * @param crgram_len cryptogram length
1522
 * @param out where to store result
1523
 * @param outlen length of result buffer
1524
 * @return SC_SUCCESS if OK; else error code
1525
 */
1526
static int dnie_decipher(struct sc_card *card,
1527
       const u8 * crgram, size_t crgram_len,
1528
       u8 * out, size_t outlen)
1529
0
{
1530
0
  struct sc_apdu apdu;
1531
0
  u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
1532
0
  u8 sbuf[MAX_RESP_BUFFER_SIZE];
1533
0
  size_t len;
1534
0
  int result = SC_SUCCESS;
1535
0
  if ((card == NULL) || (card->ctx == NULL))
1536
0
    return SC_ERROR_INVALID_ARGUMENTS;
1537
0
  LOG_FUNC_CALLED(card->ctx);
1538
0
  if ((crgram == NULL) || (out == NULL) || (crgram_len > 255)) {
1539
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1540
0
  }
1541
  /* Secure Channel should be on. Elsewhere an error will be thrown */
1542
  /*
1543
  result =
1544
      cwa_create_secure_channel(card, dnie_priv.provider, CWA_SM_WARM);
1545
  LOG_TEST_RET(card->ctx, result, "decipher(); Cannot establish SM");
1546
  */
1547
1548
  /* Official driver uses an undocumented proprietary APDU
1549
   * (90 74 40 keyID). This code uses standard 00 2A 80 8x one)
1550
   * as shown in card-atrust-acos.c and card-jcop.c
1551
   */
1552
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT,
1553
0
      0x2A, /* INS: 0x2A  perform security operation */
1554
0
      0x80, /* P1: Response is plain value */
1555
0
      0x86, /* P2: 8x: Padding indicator byte followed by cryptogram */
1556
0
      256, crgram_len + 1, rbuf, sizeof(rbuf), sbuf, crgram_len + 1
1557
0
      );
1558
1559
0
  sbuf[0] = 0;    /* padding indicator byte, 0x00 = No further indication */
1560
0
  memcpy(sbuf + 1, crgram, crgram_len);
1561
  /* send apdu */
1562
0
  result = sc_transmit_apdu(card, &apdu);
1563
0
  LOG_TEST_RET(card->ctx, result, "APDU transmit failed");
1564
  /* check response */
1565
0
  result = sc_check_sw(card, apdu.sw1, apdu.sw2);
1566
0
  LOG_TEST_RET(card->ctx, result, "decipher returned error");
1567
  /* responde ok: fill result data and return */
1568
0
  len = apdu.resplen > outlen ? outlen : apdu.resplen;
1569
0
  memcpy(out, apdu.resp, len);
1570
0
  LOG_FUNC_RETURN(card->ctx, result);
1571
0
}
1572
1573
/**
1574
 * OpenDNIe implementation of Compute_Signature() card driver operation.
1575
 *
1576
 * Generates a digital signature on the card.
1577
 * This function handles the process of hash + sign
1578
 * with previously selected keys (by mean of set_security environment
1579
 *
1580
 * AS iso7816 and DNIe Manual states there are 3 ways to perform
1581
 * this operation:
1582
 *
1583
 * - (plaintext) Hash on plaintext + sign
1584
 * - (partial hash) Send a externally evaluated pkcs1 hash + sign
1585
 * - (hash) directly sign a given sha1 hash
1586
 *
1587
 * So the code analyze incoming data, decide which method to be used
1588
 * and applies
1589
 *
1590
 * @param card pointer to sc_card_t structure
1591
 * @param data data to be hashed/signed
1592
 * @param datalen length of provided data
1593
 * @param out buffer to store results into
1594
 * @param outlen available space in result buffer
1595
 * @return
1596
 *  - Positive value: Size of data stored in out buffer when no error
1597
 *  - Negative value: error code
1598
 */
1599
static int dnie_compute_signature(struct sc_card *card,
1600
          const u8 * data, size_t datalen,
1601
          u8 * out, size_t outlen)
1602
0
{
1603
0
  int result = SC_SUCCESS;
1604
0
  size_t result_resplen = 0;
1605
0
  struct sc_apdu apdu;
1606
0
  u8 rbuf[MAX_RESP_BUFFER_SIZE];  /* to receive sign response */
1607
1608
  /* some preliminary checks */
1609
0
  if ((card == NULL) || (card->ctx == NULL))
1610
0
    return SC_ERROR_INVALID_ARGUMENTS;
1611
  /* OK: start working */
1612
0
  LOG_FUNC_CALLED(card->ctx);
1613
  /* more checks */
1614
0
  if ((data == NULL) || (out == NULL))
1615
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1616
0
  if (datalen > SC_MAX_APDU_BUFFER_SIZE) /* should be 256 */
1617
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1618
1619
#ifdef ENABLE_DNIE_UI
1620
  /* (Requested by DGP): on signature operation, ask user consent */
1621
  if (GET_DNIE_PRIV_DATA(card)->rsa_key_ref == 0x02) {  /* TODO: revise key ID handling */
1622
    result = dnie_ask_user_consent(card,user_consent_title,user_consent_message);
1623
    LOG_TEST_RET(card->ctx, result, "User consent denied");
1624
  }
1625
#endif
1626
1627
  /*
1628
     Seems that OpenSC already provides pkcs#1 v1.5 DigestInfo structure
1629
     with pre-calculated hash. So no need to to any Hash calculation,
1630
1631
     So just extract 15+20 DigestInfo+Hash info from ASN.1 provided
1632
     data and feed them into sign() command
1633
   */
1634
0
  sc_log_hex(card->ctx,
1635
0
         "Compute signature\n============================================================",
1636
0
         data, datalen);
1637
1638
  /*INS: 0x2A  PERFORM SECURITY OPERATION
1639
   * P1:  0x9E  Resp: Digital Signature
1640
   * P2:  0x9A  Cmd: Input for Digital Signature */
1641
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A, 256, datalen,
1642
0
          rbuf, sizeof(rbuf), data, datalen);
1643
  /* tell card to compute signature */
1644
0
  result = sc_transmit_apdu(card, &apdu);
1645
0
  if (result != SC_SUCCESS) {
1646
0
    LOG_TEST_RET(card->ctx, result, "compute_signature() failed");
1647
0
  }
1648
  /* check response */
1649
0
  result = sc_check_sw(card, apdu.sw1, apdu.sw2);
1650
0
  if (result != SC_SUCCESS) {
1651
0
    LOG_TEST_RET(card->ctx, result, "compute_signature() response error");
1652
0
  }
1653
1654
  /* ok: copy result from buffer */
1655
0
  result_resplen = apdu.resplen;
1656
0
  if (outlen < result_resplen)
1657
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1658
0
  memcpy(out, apdu.resp, result_resplen);
1659
  /* and return response length */
1660
0
  LOG_FUNC_RETURN(card->ctx, (int)result_resplen);
1661
0
}
1662
1663
/*
1664
 * ISO 7816-9 functions
1665
 */
1666
1667
/**
1668
 * OpenDNIe implementation of List_Files() card driver operation.
1669
 *
1670
 * List available files in current DF
1671
 * This is a dirty and trick implementation:
1672
 * Just try every ID in current dir
1673
 *
1674
 * @param card Pointer to Card Driver structure
1675
 * @param buff buffer to store result into
1676
 * @param bufflen size of provided buffer
1677
 * @return SC_SUCCESS if OK; else error code
1678
 *
1679
 * TODO: check for presence of every file ids on a DF is not
1680
 * practical. Locate a better way to handle, or remove code
1681
 */
1682
static int dnie_list_files(sc_card_t * card, u8 * buf, size_t buflen)
1683
0
{
1684
0
  int res = SC_SUCCESS;
1685
0
  int id1 = 0;
1686
0
  int id2 = 0;
1687
0
  size_t count = 0;
1688
0
  u8 data[2];
1689
0
  sc_apdu_t apdu;
1690
0
  if (!card || !card->ctx)
1691
0
    return SC_ERROR_INVALID_ARGUMENTS;
1692
1693
0
  LOG_FUNC_CALLED(card->ctx);
1694
0
  if (!buf || (buflen < 2))
1695
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1696
1697
  /* compose select_file(ID) command */
1698
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x00, 0x00, 0, 2,
1699
0
          NULL, 0, data, 2);
1700
  /* iterate on every possible ids */
1701
0
  for (id1 = 0; id1 < 256; id1++) {
1702
0
    for (id2 = 0; id2 < 256; id2++) {
1703
0
      if (count >= (buflen - 2)) {
1704
0
        sc_log(card->ctx,
1705
0
               "list_files: end of buffer. Listing stopped");
1706
0
        LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1707
0
      }
1708
      /* according iso several ids are not allowed, so check for it */
1709
0
      if ((id1 == 0x3F) && (id2 == 0xFF))
1710
0
        continue; /* generic parent "." DF */
1711
0
      if ((id1 == 0x2F) && (id2 == 0x00))
1712
0
        continue; /* RFU see iso 8.2.1.1 */
1713
0
      if ((id1 == 0x2F) && (id2 == 0x01))
1714
0
        continue; /* RFU */
1715
      /* compose and transmit select_file() cmd */
1716
0
      data[0] = (u8) (0xff & id1);
1717
0
      data[1] = (u8) (0xff & id2);
1718
0
      res = sc_transmit_apdu(card, &apdu);
1719
0
      if (res != SC_SUCCESS) {
1720
0
        sc_log(card->ctx, "List file '%02X%02X' failed",
1721
0
               id1, id2);
1722
        /* if file not found, continue; else abort */
1723
0
        if (res != SC_ERROR_FILE_NOT_FOUND)
1724
0
          LOG_FUNC_RETURN(card->ctx, res);
1725
0
        continue;
1726
0
      }
1727
      /* if file found, process fci to get file type */
1728
0
      sc_log(card->ctx, "Found File ID '%02X%02X'", id1, id2);
1729
      /* store id into buffer */
1730
0
      *(buf + count++) = data[0];
1731
0
      *(buf + count++) = data[1];
1732
      /* TODO:
1733
      * if found file is a DF go back to parent DF
1734
      * to continue search */
1735
0
    }
1736
0
  }
1737
  /* arriving here means all done */
1738
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1739
0
}
1740
1741
/**
1742
 * Parse APDU results to generate proper error code.
1743
 *
1744
 * Traps standard check_sw function to take care on special error codes
1745
 * for OpenDNIe (mostly related to SM status and operations)
1746
 *
1747
 * @param card Pointer to Card driver Structure
1748
 * @param sw1 SW1 APDU response byte
1749
 * @param sw2 SW2 APDU response byte
1750
 * @return SC_SUCCESS if no error; else proper error code
1751
 */
1752
static int dnie_check_sw(struct sc_card *card,
1753
       unsigned int sw1, unsigned int sw2)
1754
0
{
1755
0
  int res = SC_SUCCESS;
1756
0
  int n = 0;
1757
0
  if (!card || !card->ctx)
1758
0
    return SC_ERROR_INVALID_ARGUMENTS;
1759
0
  LOG_FUNC_CALLED(card->ctx);
1760
1761
  /* check specific dnie errors */
1762
0
  for (n = 0; dnie_errors[n].SWs != 0; n++) {
1763
0
    if (dnie_errors[n].SWs == ((sw1 << 8) | sw2)) {
1764
0
      sc_log(card->ctx, "%s", dnie_errors[n].errorstr);
1765
0
      return dnie_errors[n].errorno;
1766
0
    }
1767
0
  }
1768
1769
  /* arriving here means check for supported iso error codes */
1770
0
  res = iso_ops->check_sw(card, sw1, sw2);
1771
0
  LOG_FUNC_RETURN(card->ctx, res);
1772
0
}
1773
1774
/**
1775
 * OpenDNIe implementation for Card_Ctl() card driver operation.
1776
 *
1777
 * This command provides access to non standard functions provided by
1778
 * this card driver, as defined in cardctl.h
1779
 *
1780
 * @param card Pointer to card driver structure
1781
 * @param request Operation requested
1782
 * @param data where to get data/store response
1783
 * @return SC_SUCCESS if ok; else error code
1784
 * @see cardctl.h
1785
 *
1786
 * TODO: wait for GET_CARD_INFO generic cardctl to be implemented
1787
 * in opensc and rewrite code according it
1788
 */
1789
static int dnie_card_ctl(struct sc_card *card,
1790
       unsigned long request, void *data)
1791
0
{
1792
0
  int result = SC_SUCCESS;
1793
0
  if ((card == NULL) || (card->ctx == NULL))
1794
0
    return SC_ERROR_INVALID_ARGUMENTS;
1795
0
  LOG_FUNC_CALLED(card->ctx);
1796
0
  if (data == NULL) {
1797
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1798
0
  }
1799
0
  switch (request) {
1800
    /* obtain lifecycle status by reading card->type */
1801
0
  case SC_CARDCTL_LIFECYCLE_GET:
1802
0
    switch (card->type) {
1803
0
    case SC_CARD_TYPE_DNIE_ADMIN:
1804
0
      result = SC_CARDCTRL_LIFECYCLE_ADMIN;
1805
0
      break;
1806
0
    case SC_CARD_TYPE_DNIE_USER:
1807
0
      result = SC_CARDCTRL_LIFECYCLE_USER;
1808
0
      break;
1809
0
    case SC_CARD_TYPE_DNIE_BLANK:
1810
0
    case SC_CARD_TYPE_DNIE_TERMINATED:
1811
0
      result = SC_CARDCTRL_LIFECYCLE_OTHER;
1812
0
      break;
1813
0
    }
1814
0
    *(int *)data = result;
1815
0
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1816
    /* call card to obtain serial number */
1817
0
  case SC_CARDCTL_GET_SERIALNR:
1818
0
    result = dnie_get_serialnr(card, (sc_serial_number_t *) data);
1819
0
    LOG_FUNC_RETURN(card->ctx, result);
1820
0
  case SC_CARDCTL_DNIE_GENERATE_KEY:
1821
    /* some reports says that this card supports genkey */
1822
0
    result = dnie_generate_key(card, data);
1823
0
    LOG_FUNC_RETURN(card->ctx, result);
1824
0
  case SC_CARDCTL_DNIE_GET_INFO:
1825
    /* retrieve name, surname and eid number */
1826
0
    result = dnie_get_info(card, data);
1827
0
    LOG_FUNC_RETURN(card->ctx, result);
1828
0
  default:
1829
    /* default: unsupported function */
1830
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1831
0
  }
1832
0
}
1833
1834
/**
1835
 * Read first bytes of an EF to check for compression data.
1836
 *
1837
 * FCI info on compressed files provides the length of the compressed
1838
 * data. When fci returns filetype = 0x24, needs to check if the
1839
 * file is compressed, and set up properly correct file length, to let
1840
 * the read_binary() file cache work
1841
 *
1842
 * Extract real file length from compressed file is done by mean of
1843
 * reading 8 first bytes for uncompressed/compressed length.
1844
 * Lengths are provided as two 4-byte little endian numbers
1845
 *
1846
 * Implemented just like a direct read binary apdu bypassing dnie file cache
1847
 *
1848
 * @param card sc_card_t structure pointer
1849
 * @return <0: error code - ==0 not compressed - >0 file size
1850
 */
1851
static int dnie_read_header(struct sc_card *card)
1852
0
{
1853
0
  sc_apdu_t apdu;
1854
0
  int r;
1855
0
  u8 buf[MAX_RESP_BUFFER_SIZE];
1856
0
  unsigned long uncompressed = 0L;
1857
0
  unsigned long compressed = 0L;
1858
0
  sc_context_t *ctx = NULL;
1859
1860
0
  if (!card || !card->ctx)
1861
0
    return SC_ERROR_INVALID_ARGUMENTS;
1862
0
  ctx = card->ctx;
1863
0
  LOG_FUNC_CALLED(ctx);
1864
1865
  /* initialize apdu */
1866
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, 0x00, 0x00, 8, 0,
1867
0
          buf, MAX_RESP_BUFFER_SIZE, NULL, 0);
1868
  /* transmit apdu */
1869
0
  r = sc_transmit_apdu(card, &apdu);
1870
0
  if (r != SC_SUCCESS) {
1871
0
    sc_log(ctx, "read_header() APDU transmit failed");
1872
0
    LOG_FUNC_RETURN(ctx, r);
1873
0
  }
1874
  /* check response */
1875
0
  if (apdu.resplen != 8)
1876
0
    goto header_notcompressed;
1877
0
  uncompressed = lebytes2ulong(apdu.resp);
1878
0
  compressed = lebytes2ulong(apdu.resp + 4);
1879
0
  if (uncompressed < compressed)
1880
0
    goto header_notcompressed;
1881
0
  if (uncompressed > 32767)
1882
0
    goto header_notcompressed;
1883
  /* ok: assume data is correct */
1884
0
  sc_log(ctx, "read_header: uncompressed file size is %lu", uncompressed);
1885
0
  return (int)(0x7FFF & uncompressed);
1886
1887
0
 header_notcompressed:
1888
0
  sc_log(ctx, "response doesn't match compressed file header");
1889
0
  return 0;
1890
0
}
1891
1892
/**
1893
 *  Access control list bytes for proprietary DNIe FCI response for DF's.
1894
 *  based in information from official DNIe Driver
1895
 *  Parsing code based on itacns card driver
1896
 */
1897
static int df_acl[] = {   /* to handle DF's */
1898
  SC_AC_OP_CREATE, SC_AC_OP_DELETE,
1899
  SC_AC_OP_REHABILITATE, SC_AC_OP_INVALIDATE,
1900
  -1      /* !hey!, what about 5th byte of FCI info? */
1901
};
1902
1903
/**
1904
 *  Access control list bytes for proprietary DNIe FCI response for EF's.
1905
 *  based in information from official DNIe Driver
1906
 *  Parsing code based on itacns card driver
1907
 */
1908
static int ef_acl[] = {   /* to handle EF's */
1909
  SC_AC_OP_READ, SC_AC_OP_UPDATE,
1910
  SC_AC_OP_REHABILITATE, SC_AC_OP_INVALIDATE,
1911
  -1      /* !hey!, what about 5th byte of FCI info? */
1912
};
1913
1914
/**
1915
 * OpenDNIe implementation of Process_FCI() card driver command.
1916
 *
1917
 * Parse SelectFile's File Control information.
1918
 * - First, std iso_parse_fci is called to parse std fci tags
1919
 * - Then analyze proprietary tag according DNIe Manual
1920
 *
1921
 * @param card OpenSC card structure pointer
1922
 * @param file currently selected EF or DF
1923
 * @param buf received FCI data
1924
 * @param buflen FCI length
1925
 * @return SC_SUCCESS if OK; else error code
1926
 */
1927
static int dnie_process_fci(struct sc_card *card,
1928
          struct sc_file *file, const u8 * buf, size_t buflen)
1929
0
{
1930
0
  int res = SC_SUCCESS;
1931
0
  int *op = df_acl;
1932
0
  int n = 0;
1933
0
  sc_context_t *ctx = NULL;
1934
0
  if ((card == NULL) || (card->ctx == NULL) || (file == NULL) || buflen == 0)
1935
0
    return SC_ERROR_INVALID_ARGUMENTS;
1936
0
  ctx = card->ctx;
1937
0
  LOG_FUNC_CALLED(ctx);
1938
  /* first of all, let iso do the hard work */
1939
0
  res = iso_ops->process_fci(card, file, buf, buflen);
1940
0
  LOG_TEST_RET(ctx, res, "iso7816_process_fci() failed");
1941
  /* if tag 0x85 is received, then file->prop_attr_len should be filled
1942
   * by sc_file_set_prop_attr() code. So check and set data according manual
1943
   * Note errata at pg 35 of Manual  about DF identifier (should be 0x38) */
1944
0
  if (file->prop_attr_len == 0) { /* no proprietary tag (0x85) received */
1945
0
    res = SC_SUCCESS;
1946
0
    goto dnie_process_fci_end;
1947
0
  }
1948
  /* at least 10 bytes should be received */
1949
0
  if (file->prop_attr_len < 10) {
1950
0
    res = SC_ERROR_WRONG_LENGTH;
1951
0
    goto dnie_process_fci_end;
1952
0
  }
1953
  /* byte 0 denotes file type */
1954
0
  switch (file->prop_attr[0]) {
1955
0
  case 0x01:    /* EF for plain files */
1956
0
    file->type = SC_FILE_TYPE_WORKING_EF;
1957
0
    file->ef_structure = SC_FILE_EF_TRANSPARENT;
1958
0
    break;
1959
0
  case 0x15:    /* EF for keys: linear variable simple TLV */
1960
0
    file->type = SC_FILE_TYPE_WORKING_EF;
1961
    /* pin file 3F000000 has also this EF type */
1962
0
    if ( ( file->prop_attr[2] == 0x00 ) && (file->prop_attr[3] == 0x00 ) ) {
1963
0
      sc_log(ctx,"Processing pin EF");
1964
0
      break;
1965
0
    }
1966
    /* FCI response for Keys EF returns 3 additional bytes */
1967
0
    if (file->prop_attr_len < 13) {
1968
0
      sc_log(ctx, "FCI response len for Keys EF should be 13 bytes");
1969
0
      res = SC_ERROR_WRONG_LENGTH;
1970
0
      goto dnie_process_fci_end;
1971
0
    }
1972
0
    break;
1973
0
  case 0x24:    /* EF for compressed certificates */
1974
0
    file->type = SC_FILE_TYPE_WORKING_EF;
1975
0
    file->ef_structure = SC_FILE_EF_TRANSPARENT;
1976
    /* evaluate real length by reading first 8 bytes from file */
1977
0
    res = dnie_read_header(card);
1978
    /* Hey!, we need pin to read certificates... */
1979
0
    if (res == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED)
1980
0
      goto dnie_process_fci_end;
1981
0
    if (res <= 0) {
1982
0
      sc_log(ctx,
1983
0
             "Cannot evaluate uncompressed size. use fci length");
1984
0
    } else {
1985
0
      sc_log(ctx, "Storing uncompressed size '%d' into fci",
1986
0
             res);
1987
0
      file->prop_attr[3] = (u8) ((res >> 8) & 0xff);
1988
0
      file->prop_attr[4] = (u8) (res & 0xff);
1989
0
    }
1990
0
    break;
1991
0
  case 0x38:    /* Errata: manual page 35 says wrong 0x34 */
1992
0
    file->type = SC_FILE_TYPE_DF;
1993
0
    break;
1994
0
  default:
1995
0
    res = SC_ERROR_UNKNOWN_DATA_RECEIVED;
1996
0
    goto dnie_process_fci_end;
1997
0
  }
1998
1999
  /* bytes 1 and 2 stores file ID */
2000
0
  file->id = ( ( 0xff & (int)file->prop_attr[1] ) << 8 ) |
2001
0
      ( 0xff & (int)file->prop_attr[2] ) ;
2002
2003
  /* bytes 3 and 4 states file length */
2004
0
  file->size = ( ( 0xff & (int)file->prop_attr[3] ) << 8 ) |
2005
0
      ( 0xff & (int)file->prop_attr[4] ) ;
2006
2007
  /* bytes 5 to 9 states security attributes */
2008
  /* NOTE:
2009
   * seems that these 5 bytes are handled according iso7816-9 sect 8.
2010
   * but sadly that each card uses their own bits :-(
2011
   * Moreover: Manual talks on 5 bytes, but official driver only uses 4
2012
   * No info available (yet), so copy code from card-jcos.c / card-flex.c
2013
   * card drivers and pray... */
2014
0
  op = (file->type == SC_FILE_TYPE_DF) ? df_acl : ef_acl;
2015
0
  for (n = 0; n < 5; n++) {
2016
0
    int key_ref = 0;
2017
0
    if (*(op + n) == -1)
2018
0
      continue; /* unused entry: skip */
2019
0
    key_ref = file->prop_attr[5 + n] & 0x0F;
2020
0
    switch (0xF0 & file->prop_attr[5 + n]) {
2021
0
    case 0x00:
2022
0
      sc_file_add_acl_entry(file, *(op + n), SC_AC_NONE,
2023
0
                SC_AC_KEY_REF_NONE);
2024
0
      break;
2025
0
    case 0x10:
2026
      /* this tag is omitted in official code
2027
         case 0x20:
2028
       */
2029
0
    case 0x30:
2030
0
      sc_file_add_acl_entry(file, *(op + n), SC_AC_CHV,
2031
0
                key_ref);
2032
0
      break;
2033
0
    case 0x40:
2034
0
      sc_file_add_acl_entry(file, *(op + n), SC_AC_TERM,
2035
0
                key_ref);
2036
0
      break;
2037
0
    case 0xF0:
2038
0
      sc_file_add_acl_entry(file, *(op + n), SC_AC_NEVER,
2039
0
                SC_AC_KEY_REF_NONE);
2040
0
      break;
2041
0
    default:
2042
0
      sc_file_add_acl_entry(file, *(op + n), SC_AC_UNKNOWN,
2043
0
                SC_AC_KEY_REF_NONE);
2044
0
      break;
2045
0
    }
2046
0
  }
2047
  /* NOTE: Following bytes are described at DNIe manual pg 36, but No
2048
     documentation about what to do with following data is provided...
2049
     logs suggest that they are neither generated nor handled.
2050
2051
     UPDATE: these additional bytes are received when FileDescriptor tag
2052
     is 0x15 (EF for keys)
2053
   */
2054
0
  if (file->prop_attr[0] == 0x15) {
2055
0
    sc_log(card->ctx,
2056
0
           "Processing flags for Cryptographic key files");
2057
    /* byte 10 (if present) shows Control Flags for security files */
2058
    /* bytes 11 and 12 (if present) states Control bytes for
2059
       RSA crypto files */
2060
    /* TODO: write when know what to do */
2061
0
  }
2062
0
  res = SC_SUCCESS; /* arriving here means success */
2063
0
 dnie_process_fci_end:
2064
0
  LOG_FUNC_RETURN(card->ctx, res);
2065
0
}
2066
2067
/*
2068
 * PIN related functions
2069
 * NOTE:
2070
 * DNIe manual says only about CHV1 PIN verify, but several sources talks
2071
 * about the ability to also handle CHV1 PIN change
2072
 * So prepare code to eventually support
2073
 *
2074
 * Anyway pin unlock is not available: no way to get PUK as these code is
2075
 * obtained by mean of user fingerprint, only available at police station
2076
 */
2077
2078
/**
2079
 * Change PIN.
2080
 *
2081
 * Not implemented yet, as current availability for DNIe user driver
2082
 * is unknown
2083
 *
2084
 * @param card Pointer to Card Driver data structure
2085
 * @param data Pointer to Pin data structure
2086
 * @return SC_SUCCESS if ok; else error code
2087
 */
2088
static int dnie_pin_change(struct sc_card *card, struct sc_pin_cmd_data * data)
2089
0
{
2090
0
  int res=SC_SUCCESS;
2091
0
  LOG_FUNC_CALLED(card->ctx);
2092
  /* Ensure that secure channel is established from reset */
2093
0
  res = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_ON);
2094
0
  LOG_TEST_RET(card->ctx, res, "Establish SM failed");
2095
0
  LOG_FUNC_RETURN(card->ctx,SC_ERROR_NOT_SUPPORTED);
2096
0
}
2097
2098
/**
2099
 * Verify PIN.
2100
 *
2101
 * Initialize SM and send pin verify CHV1 command to DNIe
2102
 *
2103
 * @param card Pointer to Card Driver data structure
2104
 * @param data Pointer to Pin data structure
2105
 * @param tries_left; on fail stores the number of tries left before car lock
2106
 * @return SC_SUCCESS if ok, else error code; on pin incorrect also sets tries_left
2107
 */
2108
static int dnie_pin_verify(struct sc_card *card, struct sc_pin_cmd_data *data)
2109
0
{
2110
0
  int res=SC_SUCCESS;
2111
0
  sc_apdu_t apdu;
2112
2113
0
  u8 pinbuffer[SC_MAX_APDU_BUFFER_SIZE];
2114
0
  int pinlen = 0;
2115
0
  int padding = 0;
2116
2117
0
  LOG_FUNC_CALLED(card->ctx);
2118
  /* ensure that secure channel is established from reset */
2119
0
  if (card->atr.value[15] >= DNIE_30_VERSION) {
2120
    /* the provider should be prepared for using PIN information */
2121
0
    sc_log(card->ctx, "DNIe 3.0 detected doing PIN initialization");
2122
0
    dnie_change_cwa_provider_to_pin(card);
2123
0
  }
2124
0
  res = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_ON);
2125
0
  LOG_TEST_RET(card->ctx, res, "Establish SM failed");
2126
2127
  /* compose pin data to be inserted in apdu */
2128
0
  if (data->flags & SC_PIN_CMD_NEED_PADDING)
2129
0
    padding = 1;
2130
0
  data->pin1.offset = 0;
2131
0
  res = sc_build_pin(pinbuffer, sizeof(pinbuffer), &data->pin1, padding);
2132
0
  if (res < 0)
2133
0
    LOG_FUNC_RETURN(card->ctx, res);
2134
0
  pinlen = res;
2135
2136
  /* compose apdu */
2137
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, 0x00, 0, pinlen,
2138
0
          NULL, 0, pinbuffer, pinlen);
2139
2140
  /* and send to card through virtual channel */
2141
0
  res = sc_transmit_apdu(card, &apdu);
2142
0
  if (res != SC_SUCCESS) {
2143
0
    LOG_TEST_RET(card->ctx, res, "VERIFY APDU Transmit fail");
2144
0
  }
2145
2146
  /* check response and if requested setup tries_left */
2147
0
  if ((apdu.sw1 == 0x63) && ((apdu.sw2 & 0xF0) == 0xC0)) {
2148
0
    data->pin1.tries_left = apdu.sw2 & 0x0F;
2149
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
2150
0
  }
2151
0
  res = dnie_check_sw(card, apdu.sw1, apdu.sw2);  /* not a pinerr: parse result */
2152
2153
  /* ensure that secure channel is established after a PIN channel in 3.0 */
2154
0
  if (card->atr.value[15] >= DNIE_30_VERSION) {
2155
0
    sc_log(card->ctx, "DNIe 3.0 detected => re-establish secure channel");
2156
0
    dnie_change_cwa_provider_to_secure(card);
2157
0
    if (res == SC_SUCCESS) {
2158
0
      res = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_ON);
2159
0
    }
2160
0
  }
2161
2162
0
  LOG_FUNC_RETURN(card->ctx, res);
2163
0
}
2164
2165
/* pin_cmd: verify/change/unblock command; optionally using the
2166
 * card's pin pad if supported.
2167
 */
2168
2169
/**
2170
 * OpenDNIe implementation for Pin_Cmd() card driver command.
2171
 *
2172
 * @param card Pointer to Card Driver data structure
2173
 * @param data Pointer to Pin data structure
2174
 * @param tries_left; if pin_verify() operation, on incorrect pin stores the number of tries left before car lock
2175
 * @return SC_SUCCESS if ok, else error code; on pin incorrect also sets tries_left
2176
 */
2177
static int dnie_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data)
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);
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
0
{
2243
0
  sc_card_driver_t *iso_drv = sc_get_iso7816_driver();
2244
2245
  /* memcpy() from standard iso7816 declared operations */
2246
0
  if (iso_ops == NULL)
2247
0
    iso_ops = iso_drv->ops;
2248
0
  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
0
  dnie_ops.match_card = dnie_match_card;
2256
0
  dnie_ops.init   = dnie_init;
2257
0
  dnie_ops.finish   = dnie_finish;
2258
2259
  /* iso7816-4 functions */
2260
0
  dnie_ops.read_binary  = dnie_read_binary;
2261
0
  dnie_ops.write_binary = NULL;
2262
0
  dnie_ops.update_binary  = NULL;
2263
0
  dnie_ops.erase_binary = NULL;
2264
0
  dnie_ops.read_record  = NULL;
2265
0
  dnie_ops.write_record = NULL;
2266
0
  dnie_ops.append_record  = NULL;
2267
0
  dnie_ops.update_record  = NULL;
2268
0
  dnie_ops.select_file  = dnie_select_file;
2269
0
  dnie_ops.get_challenge  = dnie_get_challenge;
2270
2271
  /* iso7816-8 functions */
2272
0
  dnie_ops.verify   = NULL;
2273
0
  dnie_ops.logout   = dnie_logout;
2274
  /* dnie_ops.restore_security_env */
2275
0
  dnie_ops.set_security_env = dnie_set_security_env;
2276
0
  dnie_ops.decipher = dnie_decipher;
2277
0
  dnie_ops.compute_signature = dnie_compute_signature;
2278
0
  dnie_ops.change_reference_data = NULL;
2279
0
  dnie_ops.reset_retry_counter = NULL;
2280
2281
  /* iso7816-9 functions */
2282
0
  dnie_ops.create_file  = NULL;
2283
0
  dnie_ops.delete_file  = NULL;
2284
0
  dnie_ops.list_files = dnie_list_files;
2285
0
  dnie_ops.check_sw = dnie_check_sw;
2286
0
  dnie_ops.card_ctl = dnie_card_ctl;
2287
0
  dnie_ops.process_fci  = dnie_process_fci;
2288
  /* dnie_ops.construct_fci */
2289
0
  dnie_ops.pin_cmd  = dnie_pin_cmd;
2290
0
  dnie_ops.get_data = NULL;
2291
0
  dnie_ops.put_data = NULL;
2292
0
  dnie_ops.delete_record  = NULL;
2293
2294
0
  return &dnie_driver;
2295
0
}
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
0
{
2306
0
  return get_dnie_driver();
2307
0
}
2308
2309
#undef __CARD_DNIE_C__
2310
2311
#endif        /* ENABLE_OPENSSL */