Coverage Report

Created: 2025-08-29 06:26

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