Coverage Report

Created: 2026-10-17 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/card-gids.c
Line
Count
Source
1
/*
2
 * card-gids.c: Support for GIDS smart cards.
3
 *
4
 * Copyright (C) 2015 Vincent Le Toux (My Smart Logon) <vincent.letoux@mysmartlogon.com>
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
21
/*
22
The GIDS specification can be viewed here:
23
https://msdn.microsoft.com/en-us/library/windows/hardware/dn642100%28v=vs.85%29.aspx
24
25
and its formatting into the MS minidriver specification.
26
Some features are undocumented like the format used to store certificates. They have been reverse engineered.
27
*/
28
29
30
#ifdef HAVE_CONFIG_H
31
#include "config.h"
32
#endif
33
34
#include <stdlib.h>
35
#include <string.h>
36
37
#ifdef ENABLE_OPENSSL
38
/* openssl only needed for card administration */
39
#include <openssl/evp.h>
40
#include <openssl/rand.h>
41
#endif /* ENABLE_OPENSSL */
42
43
#include "internal.h"
44
#include "asn1.h"
45
#include "cardctl.h"
46
#include "iso7816.h"
47
48
#ifdef ENABLE_ZLIB
49
50
#include "compression.h"
51
// used for changing the default label if used twice
52
#include "../pkcs15init/pkcs15-init.h"
53
#include "card-gids.h"
54
#include "../common/compat_strlcat.h"
55
#include "../common/compat_strlcpy.h"
56
57
4.41k
#define GIDS_STATE_NONE 0
58
0
#define GIDS_STATE_READ_DATA_PRESENT 1
59
60
0
#define INS_ACTIVATE_FILE 0x44
61
0
#define INS_CREATE_FILE 0xE0
62
#define INS_DELETE_FILE 0xE4
63
0
#define INS_GENERAL_AUTHENTICATE 0x87
64
0
#define INS_GENERATE_ASYMECTRIC_KEY_PAIR 0x47
65
997
#define INS_GET_DATA 0xCB
66
0
#define INS_MANAGE_SECURITY_ENVIRONMENT 0x22
67
0
#define INS_PUT_DATA 0xDB
68
29.7k
#define INS_SELECT 0xA4
69
0
#define INS_VERIFY 0x20
70
71
#define P1_SELECT_DF_OR_EF_WITH_EFID 0x00
72
29.7k
#define P1_SELECT_DF_BY_NAME 0x04
73
0
#define P1_DECIPHERMENT_INTERNAL_AUTHENTICATE_KEY_AGREEMENT 0x41
74
75
29.7k
#define P2_SELECT_FIRST_OR_ONLY_OCCURENCE 0x00
76
0
#define P2_PIN_DEAUTHENTICATE 0x82
77
0
#define P2_DIGITAL_SIGNATURE 0xB6
78
0
#define P2_DECIPHERMENT 0xB8
79
80
0
#define GIDS_PIN_STATUS_OBJECT_IDENTIFIER 0x7F71
81
0
#define GIDS_PUK_STATUS_OBJECT_IDENTIFIER 0x7F73
82
0
#define GIDS_APPLET_EFID 0x3FFF
83
0
#define GIDS_PUT_KEY_DO 0x70
84
0
#define GIDS_RSA_1024_IDENTIFIER 0x06
85
0
#define GIDS_RSA_2048_IDENTIFIER 0x07
86
0
#define GIDS_RSA_3072_IDENTIFIER 0x08
87
0
#define GIDS_RSA_4096_IDENTIFIER 0x09
88
0
#define GIDS_ECC_192_IDENTIFIER 0x0A
89
0
#define GIDS_ECC_224_IDENTIFIER 0x0B
90
0
#define GIDS_ECC_256_IDENTIFIER 0x0C
91
0
#define GIDS_ECC_384_IDENTIFIER 0x0D
92
0
#define GIDS_ECC_521_IDENTIFIER 0x0E
93
94
0
#define GIDS_PUBKEY_TAG 0x7F49
95
0
#define GIDS_PUBKEY_TAG_MODULUS 0x81
96
0
#define GIDS_PUBKEY_TAG_EXPONENT 0x82
97
98
0
#define GIDS_FIRST_KEY_IDENTIFIER 0x81
99
100
0
#define GIDS_PIN_IDENTIFIER 0x80
101
0
#define GIDS_PUK_IDENTIFIER 0x81
102
0
#define GIDS_TRY_COUNTER_OLD_TAG 0x9F17
103
0
#define GIDS_TRY_COUNTER_TAG 0x97
104
0
#define GIDS_TRY_LIMIT_TAG 0x93
105
240
#define GIDS_APPLICATION_TEMPLATE_TAG 0x61
106
134
#define GIDS_APPLICATION_AID_TAG 0x4F
107
108
0
#define GIDS_KEY_TYPE_AT_KEYEXCHANGE 0x9A
109
0
#define GIDS_KEY_TYPE_AT_SIGNATURE 0x9C
110
111
static struct sc_card_operations *iso_ops;
112
static struct sc_card_operations gids_ops;
113
static struct sc_card_driver gids_drv = {
114
  "GIDS Smart Card",
115
  "gids",
116
  &gids_ops,
117
  NULL, 0, NULL
118
};
119
120
struct gids_aid {
121
  int enumtag;
122
  size_t len_short; /* min length without version */
123
  size_t len_long;  /* With version and other stuff */
124
  u8 *value;
125
};
126
127
/* GIDS AID */
128
struct sc_aid gids_aid = { { 0xA0,0x00,0x00,0x03,0x97,0x42,0x54,0x46,0x59 }, 9 };
129
130
static struct gids_aid gids_aids[] = {
131
  {SC_CARD_TYPE_GIDS_V1,
132
     9, 10, (u8 *) "\xA0\x00\x00\x03\x97\x42\x54\x46\x59\x01" },
133
  {SC_CARD_TYPE_GIDS_V2,
134
     9, 10, (u8 *) "\xA0\x00\x00\x03\x97\x42\x54\x46\x59\x02" },
135
  {0,  9, 0, NULL }
136
};
137
138
// stolen from cardmod.h for the cardcf file
139
typedef struct _CARD_CACHE_FILE_FORMAT
140
{
141
  unsigned char bVersion;       // Cache version
142
  unsigned char bPinsFreshness; // Card PIN
143
  unsigned short wContainersFreshness;
144
  unsigned short wFilesFreshness;
145
} CARD_CACHE_FILE_FORMAT, *PCARD_CACHE_FILE_FORMAT;
146
147
struct gids_private_data {
148
  u8 masterfile[MAX_GIDS_FILE_SIZE];
149
  size_t masterfilesize;
150
  u8 cmapfile[MAX_GIDS_FILE_SIZE];
151
  size_t cmapfilesize;
152
  unsigned short currentEFID;
153
  unsigned short currentDO;
154
  int state;
155
  u8 buffer[SC_MAX_EXT_APDU_BUFFER_SIZE];
156
  size_t buffersize;
157
};
158
159
// LOW LEVEL API
160
///////////////////////////////////////////
161
162
// find file identifier & DO identifier from the masterfile for a directory/file
163
496
static int gids_get_identifiers(sc_card_t* card, u8* masterfile, size_t masterfilesize, char *directory, char *filename, int *fileIdentifier, int *dataObjectIdentifier) {
164
496
  gids_mf_record_t *records = (gids_mf_record_t *) (masterfile+1);
165
496
  size_t recordcount = ((masterfilesize-1) / sizeof(gids_mf_record_t));
166
496
  size_t i;
167
496
  if (masterfilesize < 1)
168
0
    return SC_ERROR_INTERNAL;
169
170
1.62k
  for (i = 0; i < recordcount; i++) {
171
1.14k
    if (strncmp(directory, records[i].directory, sizeof(records[i].directory)) == 0 && strncmp(filename, records[i].filename, sizeof(records[i].filename)) == 0) {
172
11
      *fileIdentifier = records[i].fileIdentifier;
173
11
      *dataObjectIdentifier = records[i].dataObjectIdentifier;
174
11
      sc_log(card->ctx,
175
11
    "Identifiers of %s %s is fileIdentifier=%x, dataObjectIdentifier=%x\n", directory, filename, *fileIdentifier, *dataObjectIdentifier);
176
11
      return 0;
177
11
    }
178
1.14k
  }
179
485
  sc_log(card->ctx, "file %s %s not found\n", directory, filename);
180
485
  return SC_ERROR_FILE_NOT_FOUND;
181
496
}
182
183
// used when storing a new certificates
184
0
static int gids_find_available_DO(sc_card_t *card, u8* masterfile, size_t masterfilesize, int* fileIdentifier, int *dataObjectIdentifier) {
185
  // find the first available DO from the masterfile since A010 DF21
186
  // A010 = read everyone, card user write
187
0
  gids_mf_record_t *records = (gids_mf_record_t *) (masterfile+1);
188
0
  size_t recordcount = (masterfilesize / sizeof(gids_mf_record_t));
189
0
  size_t i;
190
191
0
  if (masterfilesize < 1)
192
0
    return SC_ERROR_INTERNAL;
193
194
0
  *fileIdentifier = CERT_FI;
195
196
0
  for (*dataObjectIdentifier = CARDAPPS_DO; *dataObjectIdentifier < GIDS_MAX_DO; (*dataObjectIdentifier)++) {
197
0
    for (i = 0; i < recordcount; i++) {
198
0
      if (records[i].fileIdentifier == *fileIdentifier && records[i].dataObjectIdentifier == *dataObjectIdentifier) {
199
0
        break;
200
0
      }
201
0
    }
202
0
    if (i == recordcount) {
203
0
      return SC_SUCCESS;
204
0
    }
205
0
  }
206
0
  return SC_ERROR_NOT_ENOUGH_MEMORY;
207
0
}
208
209
// read a DO from the card
210
997
static int gids_get_DO(sc_card_t* card, int fileIdentifier, int dataObjectIdentifier, u8* response, size_t *responselen) {
211
997
  sc_apdu_t apdu;
212
997
  int r;
213
997
  u8 data[4] = {0x5C, 0x02, (dataObjectIdentifier&0xFF00)>>8, (dataObjectIdentifier&0xFF)};
214
997
  size_t datasize = 0;
215
997
  const u8* p;
216
997
  u8 buffer[MAX_GIDS_FILE_SIZE];
217
997
  size_t buffer_len = sizeof(buffer);
218
219
997
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
220
997
  sc_log(card->ctx, "Got args: fileIdentifier=%x, dataObjectIdentifier=%x, response=%p, responselen=%zu",
221
997
      fileIdentifier, dataObjectIdentifier, response, responselen ? *responselen : 0);
222
223
997
  sc_format_apdu(card, &apdu,
224
997
    response == NULL ? SC_APDU_CASE_3_SHORT : SC_APDU_CASE_4_SHORT, INS_GET_DATA, (fileIdentifier&0xFF00)>>8, (fileIdentifier&0xFF));
225
997
  apdu.lc = 04;
226
997
  apdu.data = data;
227
997
  apdu.datalen = 04;
228
997
  apdu.resp = buffer;
229
997
  apdu.resplen = buffer_len;
230
997
  apdu.le = 256;
231
232
997
  r = sc_transmit_apdu(card, &apdu);
233
997
  LOG_TEST_RET(card->ctx, r, "gids get data failed");
234
968
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return");
235
590
  buffer_len = apdu.resplen;
236
237
590
  p = sc_asn1_find_tag(card->ctx, buffer, buffer_len, dataObjectIdentifier, &datasize);
238
590
  if (!p) {
239
77
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND);
240
77
  }
241
513
  if (response && responselen) {
242
513
    if (datasize > *responselen) {
243
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_BUFFER_TOO_SMALL);
244
0
    }
245
513
    memcpy(response, p, datasize);
246
513
    *responselen = datasize;
247
513
  }
248
513
  return SC_SUCCESS;
249
513
}
250
251
// write a DO to the card
252
0
static int gids_put_DO(sc_card_t* card, int fileIdentifier, int dataObjectIdentifier, u8 *data, size_t datalen) {
253
0
  sc_apdu_t apdu;
254
0
  int r;
255
0
  u8 buffer[SC_MAX_EXT_APDU_BUFFER_SIZE];
256
0
  u8* p = buffer;
257
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
258
0
  sc_log(card->ctx, "Got args: fileIdentifier=%x, dataObjectIdentifier=%x, data=%p, datalen=%zu",
259
0
      fileIdentifier, dataObjectIdentifier, data, datalen);
260
261
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, INS_PUT_DATA, (fileIdentifier&0xFF00)>>8, (fileIdentifier&0xFF));
262
263
0
  r = sc_asn1_put_tag(dataObjectIdentifier, data, datalen, buffer, sizeof(buffer), &p);
264
0
  LOG_TEST_RET(card->ctx, r, "Error handling TLV.");
265
266
0
  apdu.data = buffer;
267
0
  apdu.datalen = (size_t) (p - buffer);
268
0
  apdu.lc = apdu.datalen;
269
0
  apdu.flags |= SC_APDU_FLAGS_CHAINING;
270
271
0
  r = sc_transmit_apdu(card, &apdu);
272
0
  LOG_TEST_RET(card->ctx, r, "gids put data failed");
273
0
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return");
274
275
0
  return SC_SUCCESS;
276
0
}
277
278
// select the GIDS applet
279
static int gids_select_aid(sc_card_t* card, u8* aid, size_t aidlen, u8* response, size_t *responselen)
280
29.7k
{
281
29.7k
  sc_apdu_t apdu;
282
29.7k
  int r;
283
284
29.7k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
285
29.7k
  sc_log(card->ctx, "Got args: aid=%p, aidlen=%zu, response=%p, responselen=%zu",
286
29.7k
      aid, aidlen, response, responselen ? *responselen : 0);
287
288
29.7k
  sc_format_apdu(card, &apdu,
289
29.7k
    response == NULL ? SC_APDU_CASE_3_SHORT : SC_APDU_CASE_4_SHORT, INS_SELECT, P1_SELECT_DF_BY_NAME, P2_SELECT_FIRST_OR_ONLY_OCCURENCE);
290
29.7k
  apdu.lc = aidlen;
291
29.7k
  apdu.data = aid;
292
29.7k
  apdu.datalen = aidlen;
293
29.7k
  apdu.resp = response;
294
29.7k
  apdu.resplen = responselen ? *responselen : 0;
295
29.7k
  apdu.le = response == NULL ? 0 : 256; /* could be 21 for fci */
296
297
29.7k
  r = sc_transmit_apdu(card, &apdu);
298
29.7k
  if (responselen)
299
29.7k
    *responselen = apdu.resplen;
300
29.7k
  LOG_TEST_RET(card->ctx, r, "gids select failed");
301
29.6k
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
302
29.6k
}
303
304
// DIRECT FILE MANIPULATION
305
///////////////////////////////////////////
306
307
// read a file given the masterfile
308
496
static int gids_read_gidsfile_without_cache(sc_card_t* card, u8* masterfile, size_t masterfilesize, char *directory, char *filename, u8* response, size_t *responselen) {
309
496
  int r;
310
496
  int fileIdentifier;
311
496
  int dataObjectIdentifier;
312
313
496
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
314
496
  r = gids_get_identifiers(card, masterfile, masterfilesize, directory, filename, &fileIdentifier, &dataObjectIdentifier);
315
496
  LOG_TEST_RET(card->ctx, r, "unable to get the identifier for the gids file");
316
11
  r = gids_get_DO(card, fileIdentifier, dataObjectIdentifier, response, responselen);
317
11
  LOG_TEST_RET(card->ctx, r, "unable to get the data from the file");
318
2
  return r;
319
11
}
320
321
// write a file given the masterfile
322
0
static int gids_write_gidsfile_without_cache(sc_card_t* card, u8* masterfile, size_t masterfilesize, char *directory, char *filename, u8* data, size_t datalen) {
323
0
  int r;
324
0
  int fileIdentifier;
325
0
  int dataObjectIdentifier;
326
327
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
328
0
  if (datalen > MAX_GIDS_FILE_SIZE) {
329
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
330
0
  }
331
332
0
  r = gids_get_identifiers(card, masterfile, masterfilesize, directory, filename, &fileIdentifier, &dataObjectIdentifier);
333
0
  LOG_TEST_RET(card->ctx, r, "unable to get the identifier for the gids file");
334
0
  r = gids_put_DO(card, fileIdentifier, dataObjectIdentifier, data, datalen);
335
0
  LOG_TEST_RET(card->ctx, r, "unable to get the data from the file");
336
0
  return r;
337
0
}
338
339
// read the masterfile from the card
340
986
static int gids_read_masterfile(sc_card_t* card) {
341
986
  struct gids_private_data* data = (struct gids_private_data*) card->drv_data;
342
986
  int r = SC_SUCCESS;
343
344
986
  data->masterfilesize = sizeof(data->masterfile);
345
986
  r = gids_get_DO(card, MF_FI, MF_DO, data->masterfile, &data->masterfilesize);
346
986
  if (r<0) {
347
475
    data->masterfilesize = sizeof(data->masterfile);
348
475
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD);
349
475
  }
350
511
  if (data->masterfilesize < 1 || data->masterfile[0] != 1) {
351
29
    data->masterfilesize = sizeof(data->masterfile);
352
29
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD);
353
29
  }
354
482
  return r;
355
511
}
356
357
// signal to the windows minidriver that something changed on the card and that it should refresh its cache
358
// the format of this file is specified in the minidriver specification
359
0
static int gids_update_cardcf(sc_card_t* card, int file, int container) {
360
0
  struct gids_private_data* data = (struct gids_private_data*) card->drv_data;
361
0
  u8 cardcf[6];
362
0
  int r;
363
0
  size_t cardcfsize = sizeof(cardcf);
364
0
  r = gids_read_gidsfile_without_cache(card, data->masterfile, data->masterfilesize, "", "cardcf", cardcf, &cardcfsize);
365
0
  LOG_TEST_RET(card->ctx, r, "unable to get the cardcf");
366
367
0
  if (file) {
368
0
    short filefreshness = cardcf[4] + cardcf[5] * 0x100;
369
0
    filefreshness++;
370
0
    cardcf[4] = filefreshness & 0xFF;
371
0
    cardcf[5] = (filefreshness>>8) & 0xFF;
372
0
  }
373
0
  if (container) {
374
0
    short containerfreshness = cardcf[2] + cardcf[3] * 0x100;
375
0
    containerfreshness++;
376
0
    cardcf[2] = containerfreshness & 0xFF;
377
0
    cardcf[3] = (containerfreshness>>8) & 0xFF;
378
0
  }
379
0
  r = gids_write_gidsfile_without_cache(card, data->masterfile, data->masterfilesize, "", "cardcf", cardcf, 6);
380
0
  LOG_TEST_RET(card->ctx, r, "unable to update the cardcf file");
381
0
  return r;
382
0
}
383
384
// read a file
385
584
static int gids_read_gidsfile(sc_card_t* card, char *directory, char *filename, u8* response, size_t *responselen) {
386
584
  struct gids_private_data* privatedata = (struct gids_private_data*) card->drv_data;
387
584
  int r;
388
584
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
389
584
  if (privatedata->masterfilesize == sizeof(privatedata->masterfile)) {
390
117
    r = gids_read_masterfile(card);
391
117
    LOG_TEST_RET(card->ctx, r, "unable to get the masterfile");
392
117
  }
393
496
  r = gids_read_gidsfile_without_cache(card, privatedata->masterfile, privatedata->masterfilesize,
394
496
    directory, filename, response, responselen);
395
496
  LOG_TEST_RET(card->ctx, r, "unable to read the file");
396
2
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r);
397
2
}
398
399
// check for the existence of a file
400
0
static int gids_does_file_exists(sc_card_t *card, char* directory, char* filename) {
401
0
  struct gids_private_data* privatedata = (struct gids_private_data*) card->drv_data;
402
0
  int fileIdentifier, dataObjectIdentifier;
403
0
  return gids_get_identifiers(card, privatedata->masterfile, privatedata->masterfilesize, directory, filename,
404
0
    &fileIdentifier, &dataObjectIdentifier);
405
0
}
406
407
// write a file already existing
408
0
static int gids_write_gidsfile(sc_card_t* card, char *directory, char *filename, u8* data, size_t datalen) {
409
0
  struct gids_private_data* privatedata = (struct gids_private_data*) card->drv_data;
410
0
  int r;
411
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
412
0
  r = gids_update_cardcf(card, 1, 0);
413
0
  LOG_TEST_RET(card->ctx, r, "unable to update the cache file");
414
415
0
  r = gids_write_gidsfile_without_cache(card, privatedata->masterfile, privatedata->masterfilesize,
416
0
    directory, filename, data, datalen);
417
0
  LOG_TEST_RET(card->ctx, r, "unable to write the file");
418
0
  if (strcmp(directory, "mscp") == 0 && strcmp(filename, "cmapfile") == 0) {
419
    // update the cmapfile cache
420
0
    privatedata->cmapfilesize = datalen;
421
0
    memcpy(privatedata->cmapfile, data, datalen);
422
0
  }
423
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r);
424
0
}
425
426
// read the cmapfile (container description)
427
453
static int gids_read_cmapfile(sc_card_t* card) {
428
453
  struct gids_private_data* data = (struct gids_private_data*) card->drv_data;
429
453
  int r = SC_SUCCESS;
430
431
453
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
432
453
  data->cmapfilesize = sizeof(data->cmapfile);
433
453
  r = gids_read_gidsfile(card, "mscp", "cmapfile", data->cmapfile, &data->cmapfilesize);
434
453
  if (r<0) {
435
453
    data->cmapfilesize = sizeof(data->cmapfile);
436
453
  }
437
453
  LOG_TEST_RET(card->ctx, r, "unable to get the cmapfile");
438
0
  return r;
439
453
}
440
441
// create a file record in the masterfile
442
0
static int gids_create_file(sc_card_t *card, char* directory, char* filename) {
443
0
  int r;
444
0
  u8 masterfilebuffer[MAX_GIDS_FILE_SIZE];
445
0
  size_t masterfilebuffersize;
446
0
  struct gids_private_data* privatedata = (struct gids_private_data*) card->drv_data;
447
0
  int fileIdentifier, dataObjectIdentifier;
448
0
  size_t records;
449
0
  size_t offset;
450
0
  gids_mf_record_t* record;
451
452
0
  r = gids_find_available_DO(card, privatedata->masterfile, privatedata->masterfilesize, &fileIdentifier, &dataObjectIdentifier);
453
0
  LOG_TEST_RET(card->ctx, r, "unable to find an empty DO");
454
455
0
  memcpy(masterfilebuffer, privatedata->masterfile, privatedata->masterfilesize);
456
0
  masterfilebuffersize = privatedata->masterfilesize + sizeof(gids_mf_record_t);
457
0
  if (masterfilebuffersize > MAX_GIDS_FILE_SIZE) {
458
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_ENOUGH_MEMORY);
459
0
  }
460
461
0
  records = ((privatedata->masterfilesize - 1) / sizeof(gids_mf_record_t));
462
0
  offset = 1 + sizeof(gids_mf_record_t) * records;
463
0
  memcpy(masterfilebuffer + offset + sizeof(gids_mf_record_t), masterfilebuffer + offset,
464
0
    privatedata->masterfilesize - offset);
465
0
  memset(masterfilebuffer + offset, 0, sizeof(gids_mf_record_t));
466
0
  record = (gids_mf_record_t*) (masterfilebuffer + offset);
467
0
  strncpy(record->directory, directory, 8);
468
0
  strlcpy(record->filename, filename, sizeof(record->filename));
469
0
  record->fileIdentifier = fileIdentifier;
470
0
  record->dataObjectIdentifier = dataObjectIdentifier;
471
472
0
  r = gids_update_cardcf(card, 1, 0);
473
0
  LOG_TEST_RET(card->ctx, r, "unable to update the cardcf");
474
475
0
  r = gids_put_DO(card, MF_FI, MF_DO, masterfilebuffer, masterfilebuffersize);
476
0
  LOG_TEST_RET(card->ctx, r, "unable to update the masterfile");
477
478
0
  memcpy(privatedata->masterfile, masterfilebuffer, masterfilebuffersize);
479
0
  privatedata->masterfilesize = masterfilebuffersize;
480
0
  return r;
481
0
}
482
483
// CERTIFICATE HANDLING FUNCTIONS
484
////////////////////////////////////////////////////
485
486
// prepare a sc_path structure given a file identifier & DO
487
// this will be an input of the gids_read_public_key function
488
0
static int gids_build_certificate_path(sc_card_t* card, unsigned char containerindex, unsigned char issignatureonly,sc_path_t* cpath) {
489
0
  struct gids_private_data* data = (struct gids_private_data*) card->drv_data;
490
0
  int r, fileIdentifier, dataObjectIdentifier;
491
0
  char file[9];
492
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
493
0
  if (issignatureonly) {
494
0
    snprintf(file, 9, "ksc%02X", containerindex);
495
0
  } else {
496
0
    snprintf(file, 9, "kxc%02X", containerindex);
497
0
  }
498
0
  r = gids_get_identifiers(card, data->masterfile, data->masterfilesize, "mscp", file, &fileIdentifier, &dataObjectIdentifier);
499
0
  if (r < 0) return SC_ERROR_OBJECT_NOT_FOUND;
500
501
0
  memset(cpath, 0, sizeof(sc_path_t));
502
0
  cpath->type = SC_PATH_TYPE_PATH;
503
0
  cpath->len = 4;
504
0
  cpath->value[0] = (u8) ((fileIdentifier >> 8) & 0xFF);
505
0
  cpath->value[1] = (u8) fileIdentifier & 0xFF;
506
0
  cpath->value[2] = (u8) ((dataObjectIdentifier >> 8) & 0xFF);
507
0
  cpath->value[3] = (u8) dataObjectIdentifier & 0xFF;
508
0
  cpath->count = -1;
509
0
  return SC_SUCCESS;
510
0
}
511
512
// PIN HANDLING FUNCTIONS
513
////////////////////////////////////////////////////
514
515
// get the pin status
516
103
static int gids_get_pin_status(sc_card_t *card, int pinreference, int *tries_left, int *max_tries) {
517
103
  int dataObjectIdentifier, r;
518
103
  u8 buffer[100];
519
103
  const u8* p;
520
103
  size_t buffersize = sizeof(buffer);
521
103
  size_t datasize;
522
523
103
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
524
103
  if (tries_left) *tries_left = -1;
525
103
  if (max_tries) *max_tries = -1;
526
103
  switch(pinreference) {
527
0
  case GIDS_PIN_IDENTIFIER:
528
0
    dataObjectIdentifier = GIDS_PIN_STATUS_OBJECT_IDENTIFIER;
529
0
    break;
530
0
  case GIDS_PUK_IDENTIFIER:
531
0
    dataObjectIdentifier = GIDS_PUK_STATUS_OBJECT_IDENTIFIER;
532
0
    break;
533
103
  default:
534
103
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_FOUND);
535
103
  }
536
0
  r = gids_get_DO(card, GIDS_APPLET_EFID, dataObjectIdentifier, buffer, &buffersize);
537
0
  LOG_TEST_RET(card->ctx, r, "unable to update the masterfile");
538
539
0
  buffersize = buffersize > sizeof(buffer) ? sizeof(buffer) : buffersize;
540
541
0
  p = sc_asn1_find_tag(card->ctx, buffer, buffersize, GIDS_TRY_COUNTER_OLD_TAG, &datasize);
542
0
  if (p && datasize == 1) {
543
0
    if (tries_left)
544
0
      *tries_left = p[0];
545
0
  }
546
0
  p = sc_asn1_find_tag(card->ctx, buffer, buffersize, GIDS_TRY_COUNTER_TAG, &datasize);
547
0
  if (p && datasize == 1) {
548
0
    if (tries_left)
549
0
      *tries_left = p[0];
550
0
  }
551
0
  p = sc_asn1_find_tag(card->ctx, buffer, buffersize , GIDS_TRY_LIMIT_TAG, &datasize);
552
0
  if (p && datasize == 1) {
553
0
    if (max_tries)
554
0
      *max_tries = p[0];
555
0
  }
556
557
0
  sc_log(card->ctx,
558
0
    "Pin information for PIN 0x%x: triesleft=%d trieslimit=%d\n", pinreference, (tries_left?*tries_left:-1), (max_tries?*max_tries:-1));
559
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
560
0
}
561
562
static int gids_match_card(sc_card_t * card)
563
29.7k
{
564
29.7k
  u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
565
29.7k
  int r,i;
566
29.7k
  size_t resplen = sizeof(rbuf);
567
29.7k
  const u8 *tag;
568
29.7k
  size_t taglen;
569
29.7k
  const u8 *aid;
570
29.7k
  size_t aidlen;
571
572
29.7k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
573
574
  /* Detect by selecting applet */
575
29.7k
  r = gids_select_aid(card, gids_aid.value, gids_aid.len, rbuf, &resplen);
576
29.7k
  if (r<0) return 0;
577
578
808
  card->type = SC_CARD_TYPE_GIDS_GENERIC;
579
808
  if (resplen > 2) {
580
240
    tag = sc_asn1_find_tag(card->ctx, rbuf, resplen, GIDS_APPLICATION_TEMPLATE_TAG, &taglen);
581
240
    if (tag != NULL) {
582
134
      aid = sc_asn1_find_tag(card->ctx, tag, taglen, GIDS_APPLICATION_AID_TAG, &aidlen);
583
134
      if (aid != NULL ) {
584
123
        sc_log(card->ctx, "found AID");
585
346
        for (i = 0; gids_aids[i].len_long != 0; i++) {
586
239
          if ( aidlen > gids_aids[i].len_long && memcmp(aid, gids_aids[i].value,
587
223
                  gids_aids[i].len_long) == 0) {
588
16
            card->type = gids_aids[i].enumtag;
589
16
            break;
590
16
          }
591
239
        }
592
123
      }
593
134
    }
594
240
  }
595
596
808
  return 1;
597
29.7k
}
598
599
600
// extract the serial number from the cardid file
601
static int gids_get_serialnr(sc_card_t * card, sc_serial_number_t * serial)
602
131
{
603
131
  int r;
604
131
  u8 buffer[SC_MAX_EXT_APDU_BUFFER_SIZE];
605
131
  size_t buffersize;
606
607
131
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
608
609
131
  buffersize = sizeof(buffer);
610
131
  r = gids_read_gidsfile(card, "", "cardid", buffer, &buffersize);
611
131
  LOG_TEST_RET(card->ctx, r, "unable to read cardid");
612
613
2
  if (SC_MAX_SERIALNR < buffersize)
614
1
  {
615
1
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
616
1
  }
617
618
  /* cache serial number */
619
1
  card->serialnr.len = buffersize;
620
1
  memcpy(card->serialnr.value, buffer, card->serialnr.len);
621
622
  /* return cached serial number */
623
1
  if (serial)
624
1
    memcpy(serial, &card->serialnr, sizeof(*serial));
625
626
1
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
627
1
}
628
629
// initialize the driver
630
static int gids_init(sc_card_t * card)
631
808
{
632
808
  unsigned long flags;
633
808
  struct gids_private_data *data;
634
808
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
635
636
  // cache some data in memory
637
808
  data = (struct gids_private_data*) calloc(1, sizeof(struct gids_private_data));
638
808
  if (!data) {
639
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
640
0
  }
641
808
  memset(data, 0, sizeof(struct gids_private_data));
642
808
  card->drv_data = data;
643
  // invalidate the master file and cmap file cache
644
808
  data->cmapfilesize = sizeof(data->cmapfile);
645
808
  data->masterfilesize = sizeof(data->masterfile);
646
647
  /* supported RSA keys and how padding is done */
648
808
  flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_ONBOARD_KEY_GEN;
649
650
  /* fix me: add other algorithms when the gids specification will tell how to extract the algo id from the FCP */
651
808
  _sc_card_add_rsa_alg(card, 1024, flags, 0);
652
808
  _sc_card_add_rsa_alg(card, 2048, flags, 0);
653
808
  _sc_card_add_rsa_alg(card, 3072, flags, 0);
654
808
  _sc_card_add_rsa_alg(card, 4096, flags, 0);
655
656
808
  return SC_SUCCESS;
657
808
}
658
659
// cleanup
660
static int gids_finish(sc_card_t *card)
661
808
{
662
808
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
663
  /* free the private data */
664
808
  if (card->drv_data) {
665
808
    free(card->drv_data);
666
808
    card->drv_data = NULL;
667
808
  }
668
808
  return 0;
669
808
}
670
671
//see 12.5.3.1 Cryptographic Mechanism Identifier for Key with CRT
672
// the cmap file is used to detect the key algorithm / size
673
0
static int gids_get_crypto_identifier_from_key_ref(sc_card_t *card, const unsigned char keyref, unsigned char *cryptoidentifier) {
674
0
  struct gids_private_data *data = (struct gids_private_data *) card->drv_data;
675
0
  PCONTAINER_MAP_RECORD records = (PCONTAINER_MAP_RECORD) data->cmapfile;
676
0
  int recordsnum = (int) (data->cmapfilesize / sizeof(CONTAINER_MAP_RECORD));
677
0
  int index = keyref - GIDS_FIRST_KEY_IDENTIFIER;
678
0
  if (index >= recordsnum) {
679
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
680
0
  }
681
0
  *cryptoidentifier = 0x00; /* initialize to zero */
682
0
  if (records[index].wKeyExchangeKeySizeBits == 1024 || records[index].wSigKeySizeBits == 1024) {
683
0
    *cryptoidentifier = GIDS_RSA_1024_IDENTIFIER;
684
0
    return SC_SUCCESS;
685
0
  }
686
0
  if (records[index].wKeyExchangeKeySizeBits == 2048 || records[index].wSigKeySizeBits == 2048) {
687
0
    *cryptoidentifier = GIDS_RSA_2048_IDENTIFIER;
688
0
    return SC_SUCCESS;
689
0
  }
690
0
  if (records[index].wKeyExchangeKeySizeBits == 3072 || records[index].wSigKeySizeBits == 3072) {
691
0
    *cryptoidentifier = GIDS_RSA_3072_IDENTIFIER;
692
0
    return SC_SUCCESS;
693
0
  }
694
0
  if (records[index].wKeyExchangeKeySizeBits == 4096 || records[index].wSigKeySizeBits == 4096) {
695
0
    *cryptoidentifier = GIDS_RSA_4096_IDENTIFIER;
696
0
    return SC_SUCCESS;
697
0
  }
698
0
  if (records[index].wKeyExchangeKeySizeBits == 192 || records[index].wSigKeySizeBits == 192) {
699
0
    *cryptoidentifier = GIDS_ECC_192_IDENTIFIER;
700
0
    return SC_SUCCESS;
701
0
  }
702
0
  if (records[index].wKeyExchangeKeySizeBits == 224 || records[index].wSigKeySizeBits == 224) {
703
0
    *cryptoidentifier = GIDS_ECC_224_IDENTIFIER;
704
0
    return SC_SUCCESS;
705
0
  }
706
0
  if (records[index].wKeyExchangeKeySizeBits == 256 || records[index].wSigKeySizeBits == 256) {
707
0
    *cryptoidentifier = GIDS_ECC_256_IDENTIFIER;
708
0
    return SC_SUCCESS;
709
0
  }
710
0
  if (records[index].wKeyExchangeKeySizeBits == 384 || records[index].wSigKeySizeBits == 384) {
711
0
    *cryptoidentifier = GIDS_ECC_384_IDENTIFIER;
712
0
    return SC_SUCCESS;
713
0
  }
714
0
  if (records[index].wKeyExchangeKeySizeBits == 521 || records[index].wSigKeySizeBits == 521) {
715
0
    *cryptoidentifier = GIDS_ECC_521_IDENTIFIER;
716
0
    return SC_SUCCESS;
717
0
  }
718
0
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
719
0
}
720
721
// same here
722
0
static u8 gids_get_crypto_identifier_from_prkey_info(struct sc_pkcs15_prkey_info *key_info) {
723
0
  if (key_info->modulus_length > 0) {
724
0
    if (key_info->modulus_length == 1024) {
725
0
      return GIDS_RSA_1024_IDENTIFIER;
726
0
    }
727
0
    if (key_info->modulus_length == 2048) {
728
0
      return GIDS_RSA_2048_IDENTIFIER;
729
0
    }
730
0
    if (key_info->modulus_length == 3072) {
731
0
      return GIDS_RSA_3072_IDENTIFIER;
732
0
    }
733
0
    if (key_info->modulus_length == 4096) {
734
0
      return GIDS_RSA_4096_IDENTIFIER;
735
0
    }
736
0
    return 0;
737
0
  } else {
738
0
    return 0;
739
0
  }
740
0
}
741
742
// GIDS implementation of set security environment
743
static int gids_set_security_env(sc_card_t *card,
744
                                     const sc_security_env_t *env,
745
                                     int se_num)
746
0
{
747
0
  struct sc_apdu apdu;
748
0
  u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
749
0
  u8 *p;
750
0
  int r, locked = 0;
751
752
0
  if (card == NULL || env == NULL)
753
0
    return SC_ERROR_INTERNAL;
754
755
0
  LOG_FUNC_CALLED(card->ctx);
756
0
  memset(sbuf, 0, sizeof(sbuf));
757
758
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, INS_MANAGE_SECURITY_ENVIRONMENT, P1_DECIPHERMENT_INTERNAL_AUTHENTICATE_KEY_AGREEMENT, 0);
759
0
  switch (env->operation) {
760
0
  case SC_SEC_OPERATION_DECIPHER:
761
0
    apdu.p2 = P2_DECIPHERMENT;
762
0
    break;
763
0
  case SC_SEC_OPERATION_SIGN:
764
0
    apdu.p2 = P2_DIGITAL_SIGNATURE;
765
0
    break;
766
0
  default:
767
0
    return SC_ERROR_INVALID_ARGUMENTS;
768
0
  }
769
0
  p = sbuf;
770
0
  if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) {
771
0
    return SC_ERROR_NOT_SUPPORTED;
772
0
  } else {
773
    // ALG REF is mandatory
774
0
    *p++ = 0x80;  /* algorithm reference */
775
0
    *p++ = 0x01;
776
0
    gids_get_crypto_identifier_from_key_ref(card,env->key_ref[0],p);
777
0
    if (env->operation == SC_SEC_OPERATION_DECIPHER) {
778
0
      *p++ |= 0x40;
779
0
    } else {
780
0
      *p++ |= 0x50;
781
0
    }
782
0
  }
783
0
  if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT)) {
784
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
785
0
  }
786
0
  if (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC)
787
0
    *p++ = 0x83;
788
0
  else
789
0
    *p++ = 0x84;
790
0
  *p++ = (u8) env->key_ref_len;
791
0
  if (sizeof(sbuf) - (p - sbuf) < env->key_ref_len)
792
0
    return SC_ERROR_INTERNAL;
793
0
  memcpy(p, env->key_ref, env->key_ref_len);
794
0
  p += env->key_ref_len;
795
796
0
  r = (int) (p - sbuf);
797
0
  apdu.lc = r;
798
0
  apdu.datalen = r;
799
0
  apdu.data = sbuf;
800
0
  if (se_num > 0) {
801
0
    r = sc_lock(card);
802
0
    LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
803
0
    locked = 1;
804
0
  }
805
0
  if (apdu.datalen != 0) {
806
0
    r = sc_transmit_apdu(card, &apdu);
807
0
    if (r) {
808
0
      sc_log(card->ctx, "%s: APDU transmit failed", sc_strerror(r));
809
0
      goto err;
810
0
    }
811
0
    r = sc_check_sw(card, apdu.sw1, apdu.sw2);
812
0
    if (r) {
813
0
      sc_log(card->ctx, "%s: Card returned error", sc_strerror(r));
814
0
      goto err;
815
0
    }
816
0
  }
817
0
  if (se_num <= 0)
818
0
    return 0;
819
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, INS_MANAGE_SECURITY_ENVIRONMENT, 0xF2, se_num);
820
0
  r = sc_transmit_apdu(card, &apdu);
821
0
  sc_unlock(card);
822
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
823
824
0
  return sc_check_sw(card, apdu.sw1, apdu.sw2);
825
0
err:
826
0
  if (locked)
827
0
    sc_unlock(card);
828
0
  return r;
829
0
}
830
831
832
static int
833
gids_decipher(struct sc_card *card,
834
    const u8 * crgram, size_t crgram_len,
835
    u8 * out, size_t outlen)
836
0
{
837
0
  int r;
838
0
  struct sc_apdu apdu;
839
840
0
  if (card == NULL || crgram == NULL || out == NULL) {
841
0
    return SC_ERROR_INVALID_ARGUMENTS;
842
0
  }
843
0
  LOG_FUNC_CALLED(card->ctx);
844
0
  sc_log(card->ctx, "Gids decipher: in-len %zu, out-len %zu", crgram_len, outlen);
845
846
  /* INS: 0x2A  PERFORM SECURITY OPERATION
847
   * P1:  0x80  Resp: Plain value
848
   * P2:  0x86  Cmd: Padding indicator byte followed by cryptogram
849
   * Implementation by Microsoft indicates that Padding indicator
850
   * must not be sent. It may only be needed if Secure Messaging
851
   * is used. This driver does not support SM.
852
   */
853
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x80, 0x86);
854
0
  apdu.resp    = out;
855
0
  apdu.resplen = outlen;
856
0
  apdu.le      = outlen;
857
858
0
  apdu.data = crgram; /* Skip padding indication not needed unless SM */
859
0
  apdu.lc = crgram_len;
860
0
  apdu.datalen = crgram_len;
861
862
0
  iso7816_fixup_transceive_length(card, &apdu);
863
0
  r = sc_transmit_apdu(card, &apdu);
864
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
865
866
0
  if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
867
0
    LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen);
868
869
0
  LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
870
0
}
871
872
// deauthenticate all pins
873
static int gids_logout(sc_card_t *card)
874
0
{
875
0
  struct sc_apdu apdu;
876
0
  int r;
877
0
  if (card == NULL || card->ctx == NULL)
878
0
    return SC_ERROR_INTERNAL;
879
880
0
  LOG_FUNC_CALLED(card->ctx);
881
882
  // use the special PIN to deauthenticate
883
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_1, INS_VERIFY, 0x00, P2_PIN_DEAUTHENTICATE);
884
0
  r = sc_transmit_apdu(card, &apdu);
885
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
886
887
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
888
0
}
889
890
// read a public key
891
static int gids_read_public_key (struct sc_card *card , unsigned int algorithm,
892
      struct sc_path * path, unsigned key_reference, unsigned modulus_length,
893
0
      unsigned char **response, size_t *responselen) {
894
895
0
  struct sc_pkcs15_pubkey_rsa rsa_key;
896
0
  sc_apdu_t apdu;
897
0
  size_t tlen, len;
898
0
  const u8* keytemplate;
899
0
  const u8* keydata;
900
0
  int r;
901
0
  u8 data[] = {0x70, 0x08, // retrieve key
902
0
            0x84, 0x01, key_reference, // key reference
903
0
            0xA5, 0x03, 0x7F, 0x49, 0x80 // key value template: only public key
904
0
        };
905
0
  u8 buffer[SC_MAX_EXT_APDU_BUFFER_SIZE];
906
0
  size_t buffersize = sizeof(buffer);
907
908
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
909
0
  sc_log(card->ctx, "Got args: key_reference=%x, response=%p, responselen=%zu",
910
0
      key_reference, response, responselen ? *responselen : 0);
911
912
0
  sc_format_apdu(card, &apdu,
913
0
    response == NULL ? SC_APDU_CASE_3_SHORT : SC_APDU_CASE_4_SHORT, INS_GET_DATA, 0x3F, 0xFF);
914
0
  apdu.lc = sizeof(data);
915
0
  apdu.data = data;
916
0
  apdu.datalen = sizeof(data);
917
0
  apdu.resp = buffer;
918
0
  apdu.resplen = buffersize;
919
0
  apdu.le = 256;
920
921
0
  r = sc_transmit_apdu(card, &apdu);
922
0
  LOG_TEST_RET(card->ctx, r, "gids read public key failed");
923
0
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return");
924
0
  buffersize = apdu.resplen;
925
926
0
  keytemplate = sc_asn1_find_tag(card->ctx, buffer, buffersize, GIDS_PUBKEY_TAG, &tlen);
927
0
  if (keytemplate == NULL) {
928
0
    sc_log(card->ctx, "invalid public key data: missing tag");
929
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
930
0
  }
931
932
0
  keydata = sc_asn1_find_tag(card->ctx, keytemplate, tlen, GIDS_PUBKEY_TAG_MODULUS, &len);
933
0
  if (keydata != NULL) {
934
0
    rsa_key.modulus.data = (u8*) keydata;
935
0
    rsa_key.modulus.len = len;
936
0
  } else {
937
0
    rsa_key.modulus.len = 0;
938
0
  }
939
940
0
  keydata = sc_asn1_find_tag(card->ctx, keytemplate, tlen, GIDS_PUBKEY_TAG_EXPONENT, &len);
941
0
  if (keydata != NULL) {
942
0
    rsa_key.exponent.data = (u8*) keydata;
943
0
    rsa_key.exponent.len = len;
944
0
  } else {
945
0
    rsa_key.exponent.len = 0;
946
0
  }
947
948
0
  if (rsa_key.exponent.len && rsa_key.modulus.len) {
949
0
    r = sc_pkcs15_encode_pubkey_rsa(card->ctx, &rsa_key, response, responselen);
950
0
    LOG_TEST_RET(card->ctx, r, "failed to read public key: cannot encode RSA public key");
951
0
  } else {
952
0
    sc_log(card->ctx, "it is not a known public key");
953
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
954
0
  }
955
956
0
  if (response && responselen)
957
0
    sc_log_hex(card->ctx, "encoded public key", *response, *responselen);
958
959
0
  return SC_SUCCESS;
960
0
}
961
962
// emulate a filesystem given EF and DO
963
static int gids_select_file(sc_card_t *card, const struct sc_path *in_path,
964
4.41k
         struct sc_file **file_out) {
965
4.41k
  struct sc_file *file = NULL;
966
4.41k
  struct sc_context *ctx = card->ctx;
967
4.41k
  struct gids_private_data *data = (struct gids_private_data *) card->drv_data;
968
969
4.41k
  LOG_FUNC_CALLED(card->ctx);
970
971
4.41k
  data->state = GIDS_STATE_NONE;
972
4.41k
  data->currentDO = 0;
973
4.41k
  data->currentEFID = 0;
974
4.41k
  if (in_path->len == 4 && in_path->value[0] == 0xA0) {
975
    // is it a DO pseudo file ?
976
    // yes, succeed
977
3
    data->currentEFID = in_path->value[1] + (in_path->value[0]<<8);
978
3
    data->currentDO = in_path->value[3] + (in_path->value[2]<<8);
979
980
3
    if (file_out) {
981
3
      file = sc_file_new();
982
3
      if (file == NULL)
983
3
        LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
984
3
      file->path = *in_path;
985
3
      file->type = SC_FILE_TYPE_WORKING_EF;
986
3
      file->ef_structure = SC_FILE_EF_TRANSPARENT;
987
3
      file->size = SC_MAX_EXT_APDU_BUFFER_SIZE;
988
3
      *file_out = file;
989
3
    }
990
3
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
991
4.40k
  } else if (in_path->len == 4 && in_path->value[0] == 0x3F && in_path->value[1] == 0xFF &&  in_path->type == SC_PATH_TYPE_PATH) {
992
    // GIDS does not allow a select with a path containing a DF
993
    // replace the file selection from SC_PATH_TYPE_PATH to SC_PATH_TYPE_FILE_ID
994
10
    struct sc_path key_path;
995
10
    memset(&key_path, 0, sizeof(key_path));
996
10
    key_path.len = 2;
997
10
    key_path.value[0] = in_path->value[2];
998
10
    key_path.value[1] = in_path->value[3];
999
10
    key_path.type = SC_PATH_TYPE_FILE_ID;
1000
10
    return iso_ops->select_file(card, &key_path, file_out);
1001
4.39k
  } else {
1002
4.39k
    return iso_ops->select_file(card, in_path, file_out);
1003
4.39k
  }
1004
4.41k
}
1005
1006
103
static int gids_get_pin_policy(struct sc_card *card, struct sc_pin_cmd_data *data) {
1007
103
  int r;
1008
103
  if (data->pin_type != SC_AC_CHV) {
1009
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1010
0
  }
1011
103
  r = gids_get_pin_status(card, data->pin_reference, &(data->pin1.tries_left), &(data->pin1.max_tries));
1012
103
  LOG_TEST_RET(card->ctx, r, "gids_get_pin_status failed");
1013
0
  data->pin1.max_length = 16;
1014
0
  data->pin1.min_length = 4;
1015
0
  data->pin1.encoding = SC_PIN_ENCODING_ASCII;
1016
0
  data->pin1.offset = 5;
1017
0
  data->pin1.logged_in = SC_PIN_STATE_UNKNOWN;
1018
0
  return SC_SUCCESS;
1019
103
}
1020
1021
static int
1022
103
gids_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data) {
1023
103
  if (data->cmd == SC_PIN_CMD_GET_INFO) {
1024
103
    return gids_get_pin_policy(card, data);
1025
103
  } else {
1026
0
    return iso_ops->pin_cmd(card, data);
1027
0
  }
1028
103
}
1029
1030
// used to read existing certificates
1031
static int gids_read_binary(sc_card_t *card, unsigned int offset,
1032
44
    unsigned char *buf, size_t count, unsigned long *flags) {
1033
44
  struct gids_private_data *data = (struct gids_private_data *) card->drv_data;
1034
44
  struct sc_context *ctx = card->ctx;
1035
44
  int r;
1036
44
  int size;
1037
1038
44
  LOG_FUNC_CALLED(card->ctx);
1039
1040
44
  if (! data->currentDO || ! data->currentEFID) {
1041
44
    LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
1042
44
  }
1043
0
  if (data->state != GIDS_STATE_READ_DATA_PRESENT) {
1044
    // this function is called to read the certificate only
1045
0
    u8 buffer[SC_MAX_EXT_APDU_BUFFER_SIZE];
1046
0
    size_t buffersize = sizeof(buffer);
1047
0
    r = gids_get_DO(card, data->currentEFID, data->currentDO, buffer, &(buffersize));
1048
0
    if (r <0) return r;
1049
0
    if (buffersize < 4) {
1050
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
1051
0
    }
1052
0
    if (buffer[0] == 1 && buffer[1] == 0) {
1053
0
      if (flags)
1054
0
        *flags |= SC_FILE_FLAG_COMPRESSED_ZLIB;
1055
      /* compressed data are starting on position buffer + 4 */
1056
0
      data->buffersize = buffersize - 4;
1057
0
      memcpy(data->buffer, buffer + 4, buffersize - 4);
1058
0
    } else {
1059
0
      sc_log(card->ctx, "unknown compression method %d", buffer[0] + (buffer[1] << 8));
1060
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
1061
0
    }
1062
0
    data->state = GIDS_STATE_READ_DATA_PRESENT;
1063
0
  }
1064
0
  if (offset >= data->buffersize) {
1065
0
    return 0;
1066
0
  }
1067
0
  size = (int) MIN((data->buffersize - offset), count);
1068
0
  memcpy(buf, data->buffer + offset, size);
1069
0
  return size;
1070
0
}
1071
1072
// refresh the internal caches and return the number of containers
1073
static int
1074
815
gids_get_all_containers(sc_card_t* card, size_t *recordsnum) {
1075
815
  int r;
1076
815
  struct gids_private_data *privatedata = (struct gids_private_data *) card->drv_data;
1077
815
  r = gids_read_masterfile(card);
1078
815
  LOG_TEST_RET(card->ctx, r, "unable to read the masterfile");
1079
449
  r = gids_read_cmapfile(card);
1080
449
  LOG_TEST_RET(card->ctx, r, "unable to read the cmapfile");
1081
0
  *recordsnum = (privatedata ->cmapfilesize / sizeof(CONTAINER_MAP_RECORD));
1082
0
  return SC_SUCCESS;
1083
449
}
1084
1085
// return the detail about a container to emulate a pkcs15 card
1086
static int
1087
0
gids_get_container_detail(sc_card_t* card, sc_cardctl_gids_get_container_t* container) {
1088
0
  PCONTAINER_MAP_RECORD records = NULL;
1089
0
  struct gids_private_data *privatedata = (struct gids_private_data *) card->drv_data;
1090
0
  size_t recordsnum, num, i;
1091
0
  records = (PCONTAINER_MAP_RECORD) privatedata ->cmapfile;
1092
0
  recordsnum = (privatedata ->cmapfilesize / sizeof(CONTAINER_MAP_RECORD));
1093
1094
0
  num = container->containernum ;
1095
0
  if (num >= recordsnum) {
1096
0
    return SC_ERROR_OBJECT_NOT_FOUND;
1097
0
  }
1098
0
  memset(container, 0, sizeof(sc_cardctl_gids_get_container_t));
1099
0
  container->containernum = num;
1100
1101
0
  if (!(records[num].bFlags & CONTAINER_MAP_VALID_CONTAINER)) {
1102
0
    return SC_SUCCESS;
1103
0
  }
1104
  // ignore problematic containers
1105
0
  if (records[num].wKeyExchangeKeySizeBits > 0 && records[num].wSigKeySizeBits > 0) {
1106
0
    return SC_SUCCESS;
1107
0
  }
1108
0
  if (records[num].wKeyExchangeKeySizeBits == 0 && records[num].wSigKeySizeBits == 0) {
1109
0
    return SC_SUCCESS;
1110
0
  }
1111
0
  for (i = 0; i < MAX_CONTAINER_NAME_LEN; i++) {
1112
0
    container->label[i] = (char) records[num].wszGuid[i];
1113
0
  }
1114
0
  container->label[MAX_CONTAINER_NAME_LEN] = 0;
1115
1116
0
  container->module_length = MAX(records[num].wKeyExchangeKeySizeBits, records[num].wSigKeySizeBits);
1117
0
  container->prvusage = SC_PKCS15_PRKEY_USAGE_SIGN;
1118
0
  container->pubusage = SC_PKCS15_PRKEY_USAGE_VERIFY;
1119
0
  if (records[num].wKeyExchangeKeySizeBits > 0) {
1120
0
     container->prvusage |= SC_PKCS15_PRKEY_USAGE_DECRYPT;
1121
0
     container->pubusage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT;
1122
0
  }
1123
1124
  // do not check for return code, typically if there is no certificate associated to the key
1125
0
  gids_build_certificate_path(card, (unsigned char) num, (records[num].wSigKeySizeBits > 0), &(container->certificatepath));
1126
1127
0
  return SC_SUCCESS;
1128
0
}
1129
1130
// find a new key reference
1131
static int
1132
54
gids_select_key_reference(sc_card_t *card, sc_pkcs15_prkey_info_t* key_info) {
1133
54
  struct gids_private_data *data = (struct gids_private_data *) card->drv_data;
1134
54
  PCONTAINER_MAP_RECORD records = (PCONTAINER_MAP_RECORD) data->cmapfile;
1135
54
  size_t recordsnum;
1136
54
  int r;
1137
54
  char ch_tmp[10];
1138
1139
54
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1140
1141
  // refresh the cached data in case some thing has been modified
1142
54
  r = gids_read_masterfile(card);
1143
54
  LOG_TEST_RET(card->ctx, r, "gids read masterfile failed");
1144
4
  r = gids_read_cmapfile(card);
1145
4
  LOG_TEST_RET(card->ctx, r, "gids read cmapfile failed");
1146
1147
0
  recordsnum = (data->cmapfilesize / sizeof(CONTAINER_MAP_RECORD));
1148
1149
0
  if (!key_info->key_reference) {
1150
    // new key
1151
0
    size_t i;
1152
    // search for a key number not used anymore
1153
0
    for (i = 0; i < recordsnum; i++) {
1154
0
      if (!(records[i].bFlags & CONTAINER_MAP_VALID_CONTAINER)) {
1155
0
        key_info->key_reference = (int) (GIDS_FIRST_KEY_IDENTIFIER + i);
1156
0
        return SC_SUCCESS;
1157
0
      }
1158
0
    }
1159
    // use a new key number
1160
0
    if (recordsnum > GIDS_MAX_CONTAINER) {
1161
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY);
1162
0
    }
1163
0
    key_info->key_reference = (int) (GIDS_FIRST_KEY_IDENTIFIER + recordsnum);
1164
0
  } else {
1165
    // key was specified. Search if the key can be used
1166
0
    size_t i = key_info->key_reference - GIDS_FIRST_KEY_IDENTIFIER;
1167
0
    if (i > GIDS_MAX_CONTAINER) {
1168
0
      sc_log(card->ctx, "invalid key ref %d", key_info->key_reference);
1169
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1170
0
    }
1171
0
    if (i > recordsnum) {
1172
0
      sc_log(card->ctx, "container num is not allowed %zu %zu", i, recordsnum);
1173
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1174
0
    }
1175
0
  }
1176
0
  snprintf(ch_tmp, sizeof(ch_tmp), "3FFFB0%02X", (u8) (0xFF & key_info->key_reference));
1177
0
  sc_format_path(ch_tmp, &(key_info->path));
1178
0
  return SC_SUCCESS;
1179
0
}
1180
1181
// perform the creation of the key file
1182
// try to mimic the GIDS minidriver key permission
1183
0
static int gids_perform_create_keyfile(sc_card_t *card, u8 keytype, u8 kid, u8 algid) {
1184
0
  struct sc_apdu apdu;
1185
0
  int r;
1186
0
  u8 keyexchange[] = {0x62,0x47,
1187
0
              0x82,0x01,0x18,  // file type
1188
0
              0x83,0x02,0xB0,kid, // key id = 81
1189
0
              0x8C,0x05,0x8F,0x10,0x10,0x10,0x00, // security
1190
0
              0xA5,0x37,
1191
0
                0xB8,0x09, // confidentiality
1192
0
                  0x80,0x01,algid, //algo: rsa without padding
1193
0
                  0x83,0x01,kid, // key id
1194
0
                  0x95,0x01,0x40, // usage
1195
0
                0xB8,0x09, // confidentiality
1196
0
                  0x80,0x01,0x80 + algid, // RSAES-OAEP padding
1197
0
                  0x83,0x01,kid,
1198
0
                  0x95,0x01,0x40,
1199
0
                0xB8,0x09, // confidentiality
1200
0
                  0x80,0x01,0x40 + algid, // RSAES-PKCS1-v1_5 padding
1201
0
                  0x83,0x01,kid,
1202
0
                  0x95,0x01,0x40,
1203
0
                0xB6,0x09, // signature
1204
0
                  0x80,0x01,0x10 + algid, // Full SHA off-card authorized
1205
0
                  0x83,0x01,kid,
1206
0
                  0x95,0x01,0x40,
1207
0
                0xB6,0x09, // signature
1208
0
                  0x80,0x01,0x50 + algid, // RSASSA PKCS1-v 1_5 padding scheme (for RSA only; otherwise, RFU)
1209
0
                  0x83,0x01,kid,
1210
0
                  0x95,0x01,0x40
1211
0
  };
1212
0
  u8 sign[] = {0x62,0x26,
1213
0
          0x82,0x01,0x18,  // file type
1214
0
          0x83,0x02,0xB0,kid, // key id = 81
1215
0
          0x8C,0x05,0x8F,0x10,0x10,0x10,0x00, // security
1216
0
          0xA5,0x16,
1217
0
            0xB6,0x09, // signature
1218
0
              0x80,0x01,0x10+ algid, // Full SHA off-card authorized
1219
0
              0x83,0x01,0x83, // key id
1220
0
              0x95,0x01,0x40, // usage
1221
0
            0xB6,0x09, // signature
1222
0
              0x80,0x01,0x50 + algid, // RSASSA PKCS1-v 1_5 padding scheme (for RSA only; otherwise, RFU)
1223
0
              0x83,0x01,0x83,
1224
0
              0x95,0x01,0x40};
1225
1226
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1227
1228
  // create the key file
1229
1230
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, INS_CREATE_FILE, 0x00, 0x00);
1231
0
  if (keytype == 1) {
1232
0
    apdu.lc = sizeof(keyexchange);
1233
0
    apdu.datalen = sizeof(keyexchange);
1234
0
    apdu.data = keyexchange;
1235
0
  } else if (keytype == 2) {
1236
0
    apdu.lc = sizeof(sign);
1237
0
    apdu.datalen = sizeof(sign);
1238
0
    apdu.data = sign;
1239
0
  } else {
1240
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1241
0
  }
1242
1243
0
  r = sc_transmit_apdu(card, &apdu);
1244
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1245
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1246
0
  LOG_TEST_RET(card->ctx, r, "Card returned error");
1247
1248
  // activate file
1249
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_1, INS_ACTIVATE_FILE, 0x00, 0x00);
1250
1251
0
  r = sc_transmit_apdu(card, &apdu);
1252
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1253
1254
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1255
0
  LOG_TEST_RET(card->ctx, r, "ACTIVATE_FILE returned error");
1256
1257
0
  LOG_FUNC_RETURN(card->ctx, r);
1258
0
}
1259
1260
// perform the creation of the keyfile and its registration in the cmapfile and keymap file
1261
0
static int gids_create_keyfile(sc_card_t *card, sc_pkcs15_object_t *object) {
1262
1263
0
  int r;
1264
0
  u8 keytype;
1265
0
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data;
1266
0
  u8 kid = key_info->key_reference;
1267
0
  u8 algid = gids_get_crypto_identifier_from_prkey_info(key_info);
1268
0
  u8 cmapbuffer[MAX_GIDS_FILE_SIZE];
1269
0
  size_t cmapbuffersize = 0;
1270
0
  u8 keymapbuffer[MAX_GIDS_FILE_SIZE];
1271
0
  size_t keymapbuffersize = 0;
1272
0
  size_t keymaprecordnum = 0;
1273
0
  struct gids_private_data *data = (struct gids_private_data *) card->drv_data;
1274
0
  size_t recordnum;
1275
0
  size_t containernum = key_info->key_reference - GIDS_FIRST_KEY_IDENTIFIER;
1276
0
  PCONTAINER_MAP_RECORD records = ((PCONTAINER_MAP_RECORD) cmapbuffer) + containernum;
1277
0
  struct gids_keymap_record* keymaprecord = NULL;
1278
0
  int i;
1279
1280
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1281
  // sanity check
1282
0
  if ((object->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY)
1283
0
    return SC_ERROR_INTERNAL;
1284
1285
0
  if (!algid) {
1286
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1287
0
  }
1288
1289
  // masterfile & cmapfile have been refreshed in gids_perform_create_keyfile
1290
1291
0
  recordnum = (data->cmapfilesize / sizeof(CONTAINER_MAP_RECORD));
1292
1293
  // sanity check
1294
0
  if (containernum > recordnum || containernum > GIDS_MAX_CONTAINER)
1295
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
1296
1297
  // refresh the key map file
1298
0
  keymapbuffersize = sizeof(keymapbuffer);
1299
0
  r = gids_get_DO(card, KEYMAP_FI, KEYMAP_DO, keymapbuffer, &keymapbuffersize);
1300
0
  if (r<0) {
1301
    // the keymap DO should be present if the cmapfile is not empty
1302
0
    if (recordnum > 0) {
1303
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
1304
0
    }
1305
    // else can be empty if not record
1306
0
    keymapbuffersize = 0;
1307
0
  } else {
1308
0
    keymaprecordnum = (keymapbuffersize - 1) / sizeof(struct gids_keymap_record);
1309
0
    if (keymaprecordnum != recordnum) {
1310
0
      sc_log(card->ctx, "Error: Unable to create the key file because the keymap and cmapfile are inconsistent");
1311
0
      sc_log(card->ctx, "keymaprecordnum = %zu recordnum = %zu", keymaprecordnum, recordnum);
1312
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
1313
0
    }
1314
0
  }
1315
1316
1317
  // prepare the cmap & keymap buffer
1318
0
  if (containernum == recordnum) {
1319
    // reserve space on the cmap file
1320
0
    memset(cmapbuffer, 0, sizeof(cmapbuffer));
1321
0
    memcpy(cmapbuffer, data->cmapfile, data->cmapfilesize);
1322
0
    cmapbuffersize = data->cmapfilesize + sizeof(CONTAINER_MAP_RECORD);
1323
0
    r = gids_write_gidsfile(card, "mscp", "cmapfile", cmapbuffer, cmapbuffersize);
1324
0
    LOG_TEST_RET(card->ctx, r, "unable to reserve space on the cmapfile");
1325
1326
0
    if (keymapbuffersize == 0) {
1327
0
      keymapbuffersize = 1;
1328
0
      keymapbuffer[0] = 1;
1329
0
    }
1330
0
    keymapbuffersize += sizeof(struct gids_keymap_record);
1331
0
  } else {
1332
0
    memcpy(cmapbuffer, data->cmapfile, data->cmapfilesize);
1333
0
    cmapbuffersize = data->cmapfilesize;
1334
0
  }
1335
0
  keymaprecord = ((struct gids_keymap_record*)(keymapbuffer +1)) + containernum;
1336
1337
0
  memset(records, 0, sizeof(CONTAINER_MAP_RECORD));
1338
0
  memset(keymaprecord, 0, sizeof(struct gids_keymap_record));
1339
1340
0
  if (key_info->usage & SC_PKCS15_PRKEY_USAGE_DECRYPT) {
1341
0
    keytype = 1; // AT_KEYEXCHANGE
1342
0
    records->wKeyExchangeKeySizeBits = (unsigned short) key_info->modulus_length;
1343
0
    keymaprecord->keytype = GIDS_KEY_TYPE_AT_KEYEXCHANGE;
1344
0
  } else if (key_info->usage & SC_PKCS15_PRKEY_USAGE_SIGN) {
1345
0
    keytype = 2; // AT_SIGNATURE
1346
0
    records->wSigKeySizeBits = (unsigned short) key_info->modulus_length;
1347
0
    keymaprecord->keytype = GIDS_KEY_TYPE_AT_SIGNATURE;
1348
0
  } else {
1349
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1350
0
  }
1351
1352
  //the GIDS card must have unique container names
1353
  // avoid the problem with the default label by making it unique
1354
0
  if (strcmp(DEFAULT_PRIVATE_KEY_LABEL, object->label) == 0 && strlen(DEFAULT_PRIVATE_KEY_LABEL) + 3 < MAX_CONTAINER_NAME_LEN) {
1355
0
    char addition[4] = " 00";
1356
0
    addition[1] += containernum % 10;
1357
0
    addition[2] += (containernum & 0xFF) / 10;
1358
0
    strlcat(object->label, addition, SC_PKCS15_MAX_LABEL_SIZE);
1359
0
  }
1360
1361
  // convert char to wchar
1362
0
  for(i = 0; i < MAX_CONTAINER_NAME_LEN && object->label[i]; i++) {
1363
0
    records->wszGuid[i] = object->label[i];
1364
0
  }
1365
1366
  // TODO: check if a container with the same name already exists and prevent is creation or change its name
1367
1368
0
  records->bFlags = CONTAINER_MAP_VALID_CONTAINER;
1369
0
  if (recordnum == 0) {
1370
0
    records->bFlags |= CONTAINER_MAP_DEFAULT_CONTAINER;
1371
0
  }
1372
0
  keymaprecord->algid = algid;
1373
0
  keymaprecord->state = 1;
1374
0
  keymaprecord->unknownWithFFFF = (unsigned short) (-1);
1375
0
  keymaprecord->keyref = 0xB000 + kid;
1376
0
  r = gids_perform_create_keyfile(card, keytype, kid, algid);
1377
0
  LOG_TEST_RET(card->ctx, r, "unable to create the key file");
1378
1379
0
  r = gids_update_cardcf(card, 0, 1);
1380
0
  LOG_TEST_RET(card->ctx, r, "unable to update the cardcf file regarding container");
1381
0
  r = gids_put_DO(card, KEYMAP_FI, KEYMAP_DO, keymapbuffer, keymapbuffersize);
1382
0
  LOG_TEST_RET(card->ctx, r, "unable to write the keymap file");
1383
1384
0
  r = gids_write_gidsfile(card, "mscp", "cmapfile", cmapbuffer, cmapbuffersize);
1385
0
  LOG_TEST_RET(card->ctx, r, "unable to write the cmap file after the container creation");
1386
1387
0
  LOG_FUNC_RETURN(card->ctx, r);
1388
0
}
1389
1390
// generate a key on an existing container
1391
0
static int gids_generate_key(sc_card_t *card, sc_pkcs15_object_t *object, struct sc_pkcs15_pubkey* pubkey) {
1392
1393
0
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data;
1394
0
  u8 kid = key_info->key_reference;
1395
0
  u8 algid = gids_get_crypto_identifier_from_prkey_info(key_info);
1396
0
  struct sc_apdu apdu;
1397
0
  u8 generatekey[] = {0xAC, 0x06, // CRT template
1398
0
              0x80, 0x01, algid, // algorithm
1399
0
              0x83, 0x01, kid // key reference
1400
0
            };
1401
0
  int r;
1402
0
  u8 *buffer = NULL;
1403
0
  size_t buffersize = 0;
1404
1405
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1406
0
  if ((object->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY)
1407
0
    return SC_ERROR_INTERNAL;
1408
1409
0
  if ((key_info->key_reference > GIDS_FIRST_KEY_IDENTIFIER + GIDS_MAX_CONTAINER) || (kid < GIDS_FIRST_KEY_IDENTIFIER)) {
1410
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
1411
0
  }
1412
1413
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, INS_GENERATE_ASYMECTRIC_KEY_PAIR, 0x00, 0x00);
1414
0
  apdu.lc = sizeof(generatekey);
1415
0
  apdu.datalen = sizeof(generatekey);
1416
0
  apdu.data = generatekey;
1417
1418
0
  r = sc_transmit_apdu(card, &apdu);
1419
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1420
1421
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1422
0
  LOG_TEST_RET(card->ctx, r, "generate key returned error");
1423
1424
0
  r = gids_read_public_key(card, 0, NULL, kid, 0, &buffer, &buffersize);
1425
0
  LOG_TEST_RET(card->ctx, r, "read public key returned error");
1426
0
  r = sc_pkcs15_decode_pubkey(card->ctx, pubkey, buffer, buffersize);
1427
0
  if (buffer)
1428
0
    free(buffer);
1429
0
  LOG_FUNC_RETURN(card->ctx, r);
1430
0
}
1431
1432
// import the key in an existing container
1433
0
static int gids_import_key(sc_card_t *card, sc_pkcs15_object_t *object, sc_pkcs15_prkey_t *key) {
1434
0
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data;
1435
0
  int version = 0;
1436
0
  int keytype = 2; // RSA
1437
0
  u8 kid = key_info->key_reference;
1438
0
  size_t len = 1;
1439
0
  int encryptkeyref = 0; //NONE
1440
0
  int r;
1441
0
  u8* buffer = NULL;
1442
0
  size_t buflen = 0;
1443
1444
0
  struct sc_asn1_entry asn1_key_usage_template[] = {
1445
0
    { "keyReference", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING | SC_ASN1_CTX, 0, NULL, NULL },
1446
0
    { "KeyValueTemplate", SC_ASN1_STRUCT, SC_ASN1_TAG_NULL | SC_ASN1_CTX | SC_ASN1_CONS, 0, NULL, NULL },
1447
0
    { NULL, 0, 0, 0, NULL, NULL }
1448
0
  };
1449
1450
0
  struct sc_asn1_entry asn1_key_value_template[] = {
1451
0
    { "keyType", SC_ASN1_INTEGER, SC_ASN1_TAG_BIT_STRING | SC_ASN1_CTX, 0, NULL, NULL },
1452
0
    { "encryptKeyRef", SC_ASN1_INTEGER, SC_ASN1_TAG_OCTET_STRING | SC_ASN1_CTX, 0, NULL, NULL },
1453
0
    { "keyValue", SC_ASN1_STRUCT, SC_ASN1_TAG_OBJECT_DESCRIPTOR | SC_ASN1_CTX, 0, NULL, NULL },
1454
0
    { NULL, 0, 0, 0, NULL, NULL }
1455
0
  };
1456
1457
0
  struct sc_asn1_entry asn1_key_data[] = {
1458
0
    { "keyData", SC_ASN1_STRUCT, SC_ASN1_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
1459
0
    { NULL, 0, 0, 0, NULL, NULL }
1460
0
  };
1461
1462
0
  struct sc_asn1_entry asn1_rsa_priv_coefficients_gids[] = {
1463
0
    { "version", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
1464
0
    { "modulus", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC, NULL, NULL },
1465
0
    { "publicExponent", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC, NULL, NULL },
1466
0
    { "privateExponent", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC, NULL, NULL },
1467
0
    { "p", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC, NULL, NULL },
1468
0
    { "q", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC, NULL, NULL },
1469
0
    { "dmp1", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC, NULL, NULL },
1470
0
    { "dmq1", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC, NULL, NULL },
1471
0
    { "iqmp", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC, NULL, NULL },
1472
0
    { NULL, 0, 0, 0, NULL, NULL }
1473
0
  };
1474
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1475
0
  if ((object->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY)
1476
0
    return SC_ERROR_INTERNAL;
1477
1478
0
  if (object->type != SC_PKCS15_TYPE_PRKEY_RSA || key->algorithm != SC_ALGORITHM_RSA) {
1479
0
    sc_log(card->ctx, "GIDS supports RSA keys only (but may support ECC one day).");
1480
0
    return SC_ERROR_NOT_SUPPORTED;
1481
0
  }
1482
0
  if (!key->u.rsa.dmp1.len || !key->u.rsa.dmq1.len || !key->u.rsa.iqmp.len) {
1483
0
    sc_log(card->ctx, "GIDS needs dmp1 & dmq1 & iqmp");
1484
0
    return SC_ERROR_NOT_SUPPORTED;
1485
0
  }
1486
0
  sc_format_asn1_entry(asn1_rsa_priv_coefficients_gids + 0, &version, NULL, 1);
1487
0
  sc_format_asn1_entry(asn1_rsa_priv_coefficients_gids + 1, key->u.rsa.modulus.data, &key->u.rsa.modulus.len, 1);
1488
0
  sc_format_asn1_entry(asn1_rsa_priv_coefficients_gids + 2, key->u.rsa.exponent.data, &key->u.rsa.exponent.len, 1);
1489
0
  sc_format_asn1_entry(asn1_rsa_priv_coefficients_gids + 3, key->u.rsa.d.data, &key->u.rsa.d.len, 1);
1490
0
  sc_format_asn1_entry(asn1_rsa_priv_coefficients_gids + 4, key->u.rsa.p.data, &key->u.rsa.p.len, 1);
1491
0
  sc_format_asn1_entry(asn1_rsa_priv_coefficients_gids + 5, key->u.rsa.q.data, &key->u.rsa.q.len, 1);
1492
0
  sc_format_asn1_entry(asn1_rsa_priv_coefficients_gids + 6, key->u.rsa.dmp1.data, &key->u.rsa.dmp1.len, 1);
1493
0
  sc_format_asn1_entry(asn1_rsa_priv_coefficients_gids + 7, key->u.rsa.dmq1.data, &key->u.rsa.dmq1.len, 1);
1494
0
  sc_format_asn1_entry(asn1_rsa_priv_coefficients_gids + 8, key->u.rsa.iqmp.data, &key->u.rsa.iqmp.len, 1);
1495
1496
0
  sc_format_asn1_entry(asn1_key_data + 0, asn1_rsa_priv_coefficients_gids, NULL, 1);
1497
1498
0
  sc_format_asn1_entry(asn1_key_value_template + 0, &keytype, NULL, 1);
1499
0
  sc_format_asn1_entry(asn1_key_value_template + 1, &encryptkeyref, NULL, 1);
1500
0
  sc_format_asn1_entry(asn1_key_value_template + 2, asn1_key_data, NULL, 1);
1501
1502
0
  sc_format_asn1_entry(asn1_key_usage_template + 0, &kid, &len, 1);
1503
0
  sc_format_asn1_entry(asn1_key_usage_template + 1, asn1_key_value_template, NULL, 1);
1504
1505
0
  r = sc_asn1_encode(card->ctx, asn1_key_usage_template, &buffer, &buflen);
1506
0
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r, "unable to encode the private key");
1507
1508
0
  r = gids_put_DO(card, GIDS_APPLET_EFID, GIDS_PUT_KEY_DO, buffer, buflen);
1509
0
  SC_TEST_GOTO_ERR(card->ctx, SC_LOG_DEBUG_VERBOSE, r, "unable to put the private key - key greater than 2048 bits ?");
1510
0
  r = SC_SUCCESS;
1511
0
err:
1512
0
  sc_mem_clear(buffer, buflen);
1513
0
  LOG_FUNC_RETURN(card->ctx, r);
1514
0
}
1515
1516
// remove a crt file
1517
0
static int gids_delete_key_file(sc_card_t *card, int containernum) {
1518
0
  int r;
1519
0
  char ch_tmp[10];
1520
0
  sc_path_t cpath;
1521
0
  snprintf(ch_tmp, sizeof(ch_tmp), "3FFFB0%02X", (u8) (0xFF & (containernum + GIDS_FIRST_KEY_IDENTIFIER)));
1522
0
  sc_format_path(ch_tmp, &cpath);
1523
0
  r = gids_select_file(card, &cpath, NULL);
1524
0
  LOG_TEST_RET(card->ctx, r, "unable to select the key file");
1525
  // delete current selected file
1526
0
  memset(&cpath, 0, sizeof(cpath));
1527
0
  r = iso_ops->delete_file(card, &cpath);
1528
0
  LOG_TEST_RET(card->ctx, r, "unable to delete the key file");
1529
0
  return r;
1530
0
}
1531
1532
// encode a certificate using the minidriver compression
1533
0
static int gids_encode_certificate(sc_card_t *card, u8* source, size_t sourcesize, u8* destination, size_t* destinationsize) {
1534
0
  int r;
1535
0
  size_t outlen;
1536
0
  if (*destinationsize < 4) {
1537
0
    return SC_ERROR_BUFFER_TOO_SMALL;
1538
0
  }
1539
0
  if (sourcesize > 0xFFFF) {
1540
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1541
0
  }
1542
  // format is:
1543
  // 2 bytes for compression version
1544
  // 2 bytes for uncompressed file size
1545
  // ZLIB compression of the certificate
1546
0
  destination[0] = 1;
1547
0
  destination[1] = 0;
1548
0
  destination[2] = sourcesize & 0xFF;
1549
0
  destination[3] = (sourcesize & 0xFF00) >> 8;
1550
0
  outlen = *destinationsize - 4;
1551
0
  r = sc_compress(destination + 4, &outlen, source, sourcesize, COMPRESSION_ZLIB);
1552
0
  LOG_TEST_RET(card->ctx, r, "unable to compress the certificate");
1553
0
  *destinationsize = outlen + 4;
1554
0
  return SC_SUCCESS;
1555
0
}
1556
1557
// save a certificate associated to a container to the card
1558
static int gids_save_certificate(sc_card_t *card, sc_pkcs15_object_t *certobject,
1559
0
                sc_pkcs15_object_t *privkeyobject, struct sc_path *path) {
1560
0
  int r;
1561
0
  u8 certbuffer[MAX_GIDS_FILE_SIZE];
1562
0
  size_t certbuffersize = sizeof(certbuffer);
1563
0
  struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *) certobject->data;
1564
0
  struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *) privkeyobject->data;
1565
0
  unsigned char containernum;
1566
0
  char filename[9];
1567
0
  if ((certobject->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_CERT)
1568
0
    return SC_ERROR_INTERNAL;
1569
0
  if ((privkeyobject->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY)
1570
0
    return SC_ERROR_INTERNAL;
1571
1572
  // refresh the cached data in case some thing has been modified
1573
0
  r = gids_read_masterfile(card);
1574
0
  LOG_TEST_RET(card->ctx, r, "gids read masterfile failed");
1575
0
  r= gids_read_cmapfile(card);
1576
0
  LOG_TEST_RET(card->ctx, r, "gids read cmapfile failed");
1577
1578
  // compress the certificate according to the minidriver specification
1579
0
  r = gids_encode_certificate(card, cert_info->value.value, cert_info->value.len, certbuffer, &certbuffersize);
1580
0
  LOG_TEST_RET(card->ctx, r, "unable to encode the certificate");
1581
1582
  // save it to a minidriver file
1583
0
  containernum = prkey_info->key_reference - GIDS_FIRST_KEY_IDENTIFIER;
1584
0
  if (!(prkey_info->usage & SC_PKCS15_PRKEY_USAGE_DECRYPT)) {
1585
0
    snprintf(filename, sizeof(filename), "ksc%02X", containernum);
1586
0
  } else {
1587
0
    snprintf(filename, sizeof(filename), "kxc%02X", containernum);
1588
0
  }
1589
1590
0
  r = gids_does_file_exists(card, "mscp", filename);
1591
0
  if (r == SC_ERROR_FILE_NOT_FOUND) {
1592
0
    r = gids_create_file(card, "mscp", filename);
1593
0
    LOG_TEST_RET(card->ctx, r, "gids unable to create the certificate file");
1594
0
  }
1595
0
  r = gids_write_gidsfile(card, "mscp", filename, certbuffer, certbuffersize);
1596
0
  LOG_TEST_RET(card->ctx, r, "gids unable to write the certificate data");
1597
1598
  // return the path to the DO
1599
0
  r = gids_build_certificate_path(card, containernum, !(prkey_info->usage & SC_PKCS15_PRKEY_USAGE_DECRYPT), path);
1600
0
  LOG_TEST_RET(card->ctx, r, "gids unable to build the certificate path");
1601
1602
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1603
0
}
1604
1605
// remove a container and its registration in the cmapfile
1606
0
static int gids_delete_container_num(sc_card_t *card, size_t containernum) {
1607
0
  int r;
1608
0
  u8 cmapbuffer[MAX_GIDS_FILE_SIZE];
1609
0
  size_t cmapbuffersize = 0;
1610
0
  u8 keymapbuffer[MAX_GIDS_FILE_SIZE];
1611
0
  size_t keymapbuffersize = 0;
1612
0
  size_t keymaprecordnum = 0;
1613
0
  struct gids_private_data *data = (struct gids_private_data *) card->drv_data;
1614
0
  size_t recordnum;
1615
0
  PCONTAINER_MAP_RECORD records = ((PCONTAINER_MAP_RECORD) cmapbuffer) + containernum;
1616
0
  struct gids_keymap_record* keymaprecord = NULL;
1617
1618
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1619
  // masterfile & cmapfile have been refreshed before
1620
1621
0
  recordnum = (data->cmapfilesize / sizeof(CONTAINER_MAP_RECORD));
1622
1623
  // sanity check
1624
0
  if (containernum >= recordnum || recordnum > GIDS_MAX_CONTAINER)
1625
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
1626
1627
  // refresh the key map file
1628
0
  keymapbuffersize = sizeof(keymapbuffer);
1629
0
  r = gids_get_DO(card, KEYMAP_FI, KEYMAP_DO, keymapbuffer, &keymapbuffersize);
1630
0
  if (r<0) {
1631
    // the keymap DO should be present if the cmapfile is not empty
1632
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
1633
0
  }
1634
0
  keymaprecordnum = (keymapbuffersize - 1) / sizeof(struct gids_keymap_record);
1635
0
  if (keymaprecordnum != recordnum) {
1636
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
1637
0
  }
1638
1639
  // update the key map file
1640
0
  memcpy(cmapbuffer, data->cmapfile, data->cmapfilesize);
1641
0
  cmapbuffersize = data->cmapfilesize;
1642
0
  keymaprecord = ((struct gids_keymap_record*)(keymapbuffer +1)) + containernum;
1643
1644
0
  memset(records, 0, sizeof(CONTAINER_MAP_RECORD));
1645
0
  memset(keymaprecord, 0, sizeof(struct gids_keymap_record));
1646
1647
0
  keymaprecord->unknownWithFFFF = (unsigned short) (-1);
1648
0
  keymaprecord->keyref =(unsigned short) (-1);
1649
1650
  // remove the key, update the key map & cmap file and signal the change
1651
0
  r = gids_delete_key_file(card, (int) containernum);
1652
0
  LOG_TEST_RET(card->ctx, r, "unable to delete the key file");
1653
0
  r = gids_update_cardcf(card, 0, 1);
1654
0
  LOG_TEST_RET(card->ctx, r, "unable to update the cardcf file regarding container");
1655
0
  r = gids_put_DO(card, KEYMAP_FI, KEYMAP_DO, keymapbuffer, keymapbuffersize);
1656
0
  LOG_TEST_RET(card->ctx, r, "unable to write the keymap file");
1657
1658
0
  r = gids_write_gidsfile(card, "mscp", "cmapfile", cmapbuffer, cmapbuffersize);
1659
0
  LOG_TEST_RET(card->ctx, r, "unable to write the cmap file after the container creation");
1660
1661
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1662
0
}
1663
1664
// delete a certificate associated to a container
1665
0
static int gids_delete_cert(sc_card_t *card, sc_pkcs15_object_t* object) {
1666
0
  int r;
1667
0
  struct gids_private_data *privatedata = (struct gids_private_data *) card->drv_data;
1668
0
  struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *) object->data;
1669
0
  unsigned short fileIdentifier, DO;
1670
0
  u8 masterfilebuffer[MAX_GIDS_FILE_SIZE];
1671
0
  size_t masterfilebuffersize = 0;
1672
0
  gids_mf_record_t *records = (gids_mf_record_t *) (masterfilebuffer+1);
1673
0
  size_t recordcount, recordnum = (size_t) -1;
1674
0
  size_t i;
1675
1676
0
  if ((object->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_CERT)
1677
0
    return SC_ERROR_INTERNAL;
1678
  // refresh the cached data in case some thing has been modified
1679
0
  r = gids_read_masterfile(card);
1680
0
  LOG_TEST_RET(card->ctx, r, "gids read masterfile failed");
1681
0
  r= gids_read_cmapfile(card);
1682
0
  LOG_TEST_RET(card->ctx, r, "gids read cmapfile failed");
1683
1684
  // remove the file reference from the masterfile
1685
0
  if (cert_info->path.len != 4) {
1686
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
1687
0
  }
1688
0
  fileIdentifier = cert_info->path.value[0] * 0x100 + cert_info->path.value[1];
1689
0
  DO = cert_info->path.value[2] * 0x100 + cert_info->path.value[3];
1690
1691
0
  memcpy(masterfilebuffer, privatedata->masterfile, privatedata->masterfilesize);
1692
0
  masterfilebuffersize = privatedata->masterfilesize;
1693
1694
0
  recordcount = ((masterfilebuffersize-1) / sizeof(gids_mf_record_t));
1695
0
  for (i = 0; i < recordcount; i++) {
1696
0
    if (records[i].fileIdentifier == fileIdentifier && records[i].dataObjectIdentifier == DO) {
1697
0
      recordnum = i;
1698
0
      break;
1699
0
    }
1700
0
  }
1701
0
  if (recordnum == (size_t) -1) {
1702
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND);
1703
0
  }
1704
1705
0
  for (i = 1 + (recordnum+1) * sizeof(gids_mf_record_t); i < masterfilebuffersize; i++) {
1706
0
    masterfilebuffer[i - sizeof(gids_mf_record_t)] = masterfilebuffer[i];
1707
0
  }
1708
0
  masterfilebuffersize -= sizeof(gids_mf_record_t);
1709
1710
  // remove the DO, update the masterfile, and signal the change
1711
0
  r = gids_update_cardcf(card, 1, 0);
1712
0
  LOG_TEST_RET(card->ctx, r, "unable to update the cache file");
1713
1714
0
  r = gids_put_DO(card, fileIdentifier, DO, NULL, 0);
1715
0
  LOG_TEST_RET(card->ctx, r, "gids unable to delete the certificate DO");
1716
1717
0
  r = gids_put_DO(card, MF_FI, MF_DO, masterfilebuffer, masterfilebuffersize);
1718
0
  LOG_TEST_RET(card->ctx, r, "gids unable to update the masterfile");
1719
1720
0
  memcpy(privatedata->masterfile, masterfilebuffer, masterfilebuffersize);
1721
0
  privatedata->masterfilesize = masterfilebuffersize;
1722
1723
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1724
0
}
1725
1726
0
static int gids_delete_key(sc_card_t *card, sc_pkcs15_object_t* object) {
1727
0
  int r;
1728
0
  size_t containernum;
1729
0
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data;
1730
1731
0
  if ((object->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY)
1732
0
    return SC_ERROR_INTERNAL;
1733
  // refresh the cached data in case some thing has been modified
1734
0
  r = gids_read_masterfile(card);
1735
0
  LOG_TEST_RET(card->ctx, r, "gids read masterfile failed");
1736
0
  r = gids_read_cmapfile(card);
1737
0
  LOG_TEST_RET(card->ctx, r, "gids read cmapfile failed");
1738
0
  containernum = key_info->key_reference - GIDS_FIRST_KEY_IDENTIFIER;
1739
1740
0
  r = gids_delete_container_num(card, containernum);
1741
0
  LOG_TEST_RET(card->ctx, r, "gids unable to delete the container");
1742
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1743
0
}
1744
1745
// used by gids_initialize to create the filesystem
1746
0
static int gids_initialize_create_file(sc_card_t *card, u8* command, size_t commandsize) {
1747
0
  int r;
1748
0
  sc_apdu_t apdu;
1749
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, INS_CREATE_FILE, 0x00, 0x00);
1750
0
  apdu.lc = commandsize;
1751
0
  apdu.data = command;
1752
0
  apdu.datalen = commandsize;
1753
1754
0
  r = sc_transmit_apdu(card, &apdu);
1755
0
  LOG_TEST_RET(card->ctx, r, "APDU1 transmit failed");
1756
0
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return");
1757
1758
  // activate file
1759
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_1, INS_ACTIVATE_FILE, 0x00, 0x00);
1760
1761
0
  r = sc_transmit_apdu(card, &apdu);
1762
0
  LOG_TEST_RET(card->ctx, r, "APDU2 transmit failed");
1763
0
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return");
1764
0
  LOG_FUNC_RETURN(card->ctx, r);
1765
0
}
1766
1767
// used by gids_initialize to set the admin key
1768
0
static int gids_set_administrator_key(sc_card_t *card, u8* key) {
1769
0
  int r;
1770
0
  u8 adminKeyData[] = {0x84,0x01,0x80, // key reference
1771
0
             0xA5,0x1F, // key template
1772
             // key value
1773
0
              0x87,0x18,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,
1774
0
                  0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x01,0x02,
1775
0
                  0x03,0x04,0x05,0x06,0x07,0x08,
1776
            // key file
1777
0
              0x88, 0x03,0xB0,0x73,0xDC};
1778
1779
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1780
0
  memcpy(adminKeyData+7, key, 24);
1781
0
  r = gids_put_DO(card, GIDS_APPLET_EFID, GIDS_PUT_KEY_DO, adminKeyData, sizeof(adminKeyData));
1782
0
  sc_mem_clear(adminKeyData, sizeof(adminKeyData));
1783
0
  LOG_TEST_RET(card->ctx, r, "gids unable to set the admin key");
1784
0
  return SC_SUCCESS;
1785
0
}
1786
1787
0
static int gids_check_that_card_is_new(sc_card_t *card) {
1788
0
  int r;
1789
  // retrieve the masterfile
1790
  // if it succeed, the card has already been initialized
1791
0
  r = gids_read_masterfile(card);
1792
0
  if (r == SC_SUCCESS) {
1793
0
    r = SC_ERROR_INVALID_CARD;
1794
0
    LOG_TEST_RET(card->ctx, r, "unable to read the masterfile");
1795
0
  }
1796
0
  return SC_SUCCESS;
1797
0
}
1798
1799
// initialize a card
1800
// see the minidriver specification annex for the details about this
1801
0
static int gids_initialize(sc_card_t *card, sc_cardctl_gids_init_param_t* param) {
1802
0
  sc_apdu_t apdu;
1803
0
  int r;
1804
0
#ifdef ENABLE_OPENSSL
1805
0
  int i;
1806
0
#endif
1807
  // hardcoded file setting
1808
  // File type=39=TLV structure for BER-TLV DOs then ACL varies depending on the file)
1809
  // this DO EF are used like DF file so the permission has to be set only once
1810
0
  u8 UserCreateDeleteDirAc[] = {0x62,0x0C,0x82,0x01,0x39,0x83,0x02,0xA0,0x00,0x8C,0x03,0x03,0x30,0x00};
1811
0
  u8 EveryoneReadUserWriteAc[] = {0x62,0x0C,0x82,0x01,0x39,0x83,0x02,0xA0,0x10,0x8C,0x03,0x03,0x30,0x00};
1812
0
  u8 UserWriteExecuteAc[] = {0x62,0x0C,0x82,0x01,0x39,0x83,0x02,0xA0,0x11,0x8C,0x03,0x03,0x30,0xFF};
1813
0
  u8 EveryoneReadAdminWriteAc[] = {0x62,0x0C,0x82,0x01,0x39,0x83,0x02,0xA0,0x12,0x8C,0x03,0x03,0x20,0x00};
1814
0
  u8 UserReadWriteAc[] = {0x62,0x0C,0x82,0x01,0x39,0x83,0x02,0xA0,0x13,0x8C,0x03,0x03,0x30,0x30};
1815
0
  u8 AdminReadWriteAc[] = {0x62,0x0C,0x82,0x01,0x39,0x83,0x02,0xA0,0x14,0x8C,0x03,0x03,0x20,0x20};
1816
  // File type=18=key file ; type = symmetric key
1817
0
  u8 AdminKey[] = {0x62,0x1A,0x82,0x01,0x18,0x83,0x02,0xB0,0x80,0x8C,0x04,0x87,0x00,0x20,0xFF,0xA5,
1818
0
                      0x0B,0xA4,0x09,0x80,0x01,0x02,0x83,0x01,0x80,0x95,0x01,0xC0};
1819
  // file used to store other file references. Format undocumented.
1820
0
  u8 masterfile[] = {0x01,0x6d,0x73,0x63,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1821
0
             0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1822
0
             0x00,0x00,0x00,0x00,0x63,0x61,0x72,0x64,0x69,0x64,0x00,0x00,0x00,0x00,0x00,0x20,0xdf,
1823
0
             0x00,0x00,0x12,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x61,
1824
0
             0x72,0x64,0x61,0x70,0x70,0x73,0x00,0x00,0x00,0x21,0xdf,0x00,0x00,0x10,0xa0,0x00,0x00,
1825
0
             0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x61,0x72,0x64,0x63,0x66,0x00,0x00,
1826
0
             0x00,0x00,0x00,0x22,0xdf,0x00,0x00,0x10,0xa0,0x00,0x00,0x6d,0x73,0x63,0x70,0x00,0x00,
1827
0
             0x00,0x00,0x00,0x63,0x6d,0x61,0x70,0x66,0x69,0x6c,0x65,0x00,0x00,0x00,0x23,0xdf,0x00,
1828
0
             0x00,0x10,0xa0,0x00,0x00};
1829
  // list the application on the card - defined in the minidriver specification
1830
0
  u8 cardapps[] = {0x6d,0x73,0x63,0x70,0x00,0x00,0x00,0x00};
1831
  // used to detect if modifications have been done outside of the minidriver - defined in the minidriver specification
1832
0
  u8 cardcf[] = {0x00,0x00,0x00,0x00,0x00,0x00};
1833
0
  struct sc_pin_cmd_data pindata;
1834
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1835
1836
  // avoid multiple initialization
1837
0
  r = gids_check_that_card_is_new(card);
1838
0
  LOG_TEST_RET(card->ctx, r, "card seems to have been already initialized");
1839
1840
0
  memset(&pindata, 0, sizeof(pindata));
1841
  // create PIN & PUK
1842
0
  pindata.cmd = SC_PIN_CMD_CHANGE;
1843
0
  pindata.pin_type = SC_AC_CHV;
1844
0
  pindata.pin2.len = param->user_pin_len;
1845
0
  pindata.pin2.data = param->user_pin;
1846
0
  pindata.pin_reference = 0x80;
1847
1848
0
  r = sc_pin_cmd(card, &pindata);
1849
0
  LOG_TEST_RET(card->ctx, r, "gids set pin");
1850
1851
  // create file
1852
0
  r = gids_initialize_create_file(card, UserCreateDeleteDirAc, sizeof(UserCreateDeleteDirAc));
1853
0
  LOG_TEST_RET(card->ctx, r, "gids to create the file UserCreateDeleteDirAc");
1854
0
  r = gids_initialize_create_file(card, EveryoneReadUserWriteAc, sizeof(EveryoneReadUserWriteAc));
1855
0
  LOG_TEST_RET(card->ctx, r, "gids to create the file EveryoneReadUserWriteAc");
1856
0
  r = gids_initialize_create_file(card, UserWriteExecuteAc, sizeof(UserWriteExecuteAc));
1857
0
  LOG_TEST_RET(card->ctx, r, "gids to create the file UserWriteExecuteAc");
1858
0
  r = gids_initialize_create_file(card, EveryoneReadAdminWriteAc, sizeof(EveryoneReadAdminWriteAc));
1859
0
  LOG_TEST_RET(card->ctx, r, "gids to create the file EveryoneReadAdminWriteAc");
1860
0
  r = gids_initialize_create_file(card, UserReadWriteAc, sizeof(UserReadWriteAc));
1861
0
  LOG_TEST_RET(card->ctx, r, "gids to create the file UserReadWriteAc");
1862
0
  r = gids_initialize_create_file(card, AdminReadWriteAc, sizeof(AdminReadWriteAc));
1863
0
  LOG_TEST_RET(card->ctx, r, "gids to create the file AdminReadWriteAc");
1864
1865
  //admin key
1866
0
  r = gids_initialize_create_file(card, AdminKey, sizeof(AdminKey));
1867
0
  LOG_TEST_RET(card->ctx, r, "gids to create the file AdminKey");
1868
1869
0
  r = gids_set_administrator_key(card, param->init_code);
1870
0
  LOG_TEST_RET(card->ctx, r, "gids unable to set the admin key");
1871
1872
  // create the filesystem
1873
0
  r = gids_put_DO(card, MF_FI, MF_DO, masterfile, sizeof(masterfile));
1874
0
  LOG_TEST_RET(card->ctx, r, "gids unable to save the masterfile");
1875
0
  r = gids_put_DO(card, CARDAPPS_FI, CARDAPPS_DO, cardapps, sizeof(cardapps));
1876
0
  LOG_TEST_RET(card->ctx, r, "gids unable to save the cardapps");
1877
0
  r = gids_put_DO(card, CARDCF_FI, CARDCF_DO, cardcf, sizeof(cardcf));
1878
0
  LOG_TEST_RET(card->ctx, r, "gids unable to save the cardcf");
1879
0
  r = gids_put_DO(card, CMAP_FI, CMAP_DO, NULL, 0);
1880
0
  LOG_TEST_RET(card->ctx, r, "gids unable to save the cmapfile");
1881
0
#ifdef ENABLE_OPENSSL
1882
0
  for (i = sizeof(param->cardid) -1; i >= 0; i--) {
1883
0
    if (param->cardid[i]) break;
1884
0
  }
1885
0
  if (i < 0) {
1886
    // set a random cardid if not set
1887
0
    if (RAND_bytes(param->cardid, sizeof(param->cardid)) != 1) {
1888
0
      sc_log_openssl(card->ctx);
1889
0
      LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "unable to set a random serial number");
1890
0
    }
1891
0
  }
1892
0
#endif
1893
0
  r = gids_put_DO(card, CARDID_FI, CARDID_DO, param->cardid, sizeof(param->cardid));
1894
0
  LOG_TEST_RET(card->ctx, r, "gids unable to save the cardid");
1895
1896
  //select applet
1897
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3, INS_SELECT, 0x00, 0x0C);
1898
0
  apdu.lc = 2;
1899
0
  apdu.data = (const unsigned char *) "\x3F\xFF";
1900
0
  apdu.datalen = 2;
1901
1902
0
  r = sc_transmit_apdu(card, &apdu);
1903
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1904
0
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return");
1905
  // activate file
1906
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_1, INS_ACTIVATE_FILE, 0x00, 0x00);
1907
0
  r = sc_transmit_apdu(card, &apdu);
1908
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1909
0
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return");
1910
0
  LOG_FUNC_RETURN(card->ctx, r);
1911
0
}
1912
1913
// execute an admin authentication based on a secret key
1914
// this is a 3DES authentication with a secret key
1915
// the card mechanism is described in the GIDS specification and the computer side on the minidriver specification
1916
// the minidriver specification is incorrect because it is not ECB but CBC
1917
// then the GIDS specification is incorrect because the z1 key should be 8 bytes instead of 7
1918
// this data comes from the reverse of the GIDS minidriver.
1919
0
static int gids_authenticate_admin(sc_card_t *card, u8* key) {
1920
#ifndef ENABLE_OPENSSL
1921
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1922
#else
1923
0
  EVP_CIPHER_CTX *ctx = NULL;
1924
0
  int r;
1925
0
  u8 apduSetRandom[20] = {0x7C,0x12,0x81,0x10,0};
1926
0
  u8* randomR1 = apduSetRandom + 4;
1927
0
  u8 apduSetRandomResponse[256];
1928
0
  u8* randomR2 = apduSetRandomResponse+4;
1929
0
  u8 apduSendReponse[40 + 4] = {0x7C,0x2A,0x82,0x28};
1930
0
  u8 z1[8];
1931
0
  u8 buffer[16+16+8];
1932
0
  u8* buffer2 = apduSendReponse + 4;
1933
0
  int buffer2size = 40;
1934
0
  u8 apduSendResponseResponse[256];
1935
0
  u8 buffer3[16+16+8];
1936
0
  int buffer3size = 40;
1937
0
  sc_apdu_t apdu;
1938
0
  EVP_CIPHER *cipher;
1939
1940
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1941
1942
  // select the admin key
1943
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3, INS_MANAGE_SECURITY_ENVIRONMENT, 0xC1, 0xA4);
1944
0
  apdu.lc = 3;
1945
0
  apdu.data = (const unsigned char *) "\x83\x01\x80";
1946
0
  apdu.datalen = 3;
1947
0
  r = sc_transmit_apdu(card, &apdu);
1948
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1949
0
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return");
1950
1951
  // generate a challenge
1952
0
  if (RAND_bytes(randomR1, 16) != 1) {
1953
0
    sc_log_openssl(card->ctx);
1954
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "unable to set computer random");
1955
0
  }
1956
1957
  // send it to the card
1958
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4, INS_GENERAL_AUTHENTICATE, 0x00, 0x00);
1959
0
  apdu.lc = sizeof(apduSetRandom);
1960
0
  apdu.data = apduSetRandom;
1961
0
  apdu.datalen = sizeof(apduSetRandom);
1962
0
  apdu.resp = apduSetRandomResponse;
1963
0
  apdu.resplen = sizeof(apduSetRandomResponse);
1964
0
  apdu.le = 256;
1965
0
  r = sc_transmit_apdu(card, &apdu);
1966
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1967
0
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return");
1968
1969
  // compute the half size of the mutual authentication secret
1970
0
  if (RAND_bytes(z1, 7) != 1) {
1971
0
    sc_log_openssl(card->ctx);
1972
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "unable to set computer random");
1973
0
  }
1974
1975
  // set the padding
1976
0
  z1[7] = 0x80;
1977
1978
  // Encrypt R2||R1||Z1
1979
0
  memcpy(buffer, randomR2, 16);
1980
0
  memcpy(buffer+16, randomR1, 16);
1981
0
  memcpy(buffer+32, z1, sizeof(z1));
1982
  // init crypto
1983
0
  ctx = EVP_CIPHER_CTX_new();
1984
0
  if (ctx == NULL) {
1985
0
    sc_log_openssl(card->ctx);
1986
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
1987
0
  }
1988
0
  cipher = sc_evp_cipher(card->ctx, "DES-EDE3-CBC");
1989
0
  if (!EVP_EncryptInit(ctx, cipher, key, NULL)) {
1990
0
    sc_log_openssl(card->ctx);
1991
0
    EVP_CIPHER_CTX_free(ctx);
1992
0
    sc_evp_cipher_free(cipher);
1993
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
1994
0
  }
1995
0
  EVP_CIPHER_CTX_set_padding(ctx,0);
1996
0
  if (!EVP_EncryptUpdate(ctx, buffer2, &buffer2size, buffer, sizeof(buffer))) {
1997
0
    sc_log_openssl(card->ctx);
1998
0
    EVP_CIPHER_CTX_free(ctx);
1999
0
    sc_evp_cipher_free(cipher);
2000
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
2001
0
  }
2002
2003
0
  if (!EVP_EncryptFinal(ctx, buffer2 + buffer2size, &buffer2size)) {
2004
0
    sc_log_openssl(card->ctx);
2005
0
    EVP_CIPHER_CTX_free(ctx);
2006
0
    sc_evp_cipher_free(cipher);
2007
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
2008
0
  }
2009
0
  EVP_CIPHER_CTX_free(ctx);
2010
0
  ctx = NULL;
2011
0
  sc_evp_cipher_free(cipher);
2012
0
  cipher = NULL;
2013
  // send it to the card
2014
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4, INS_GENERAL_AUTHENTICATE, 0x00, 0x00);
2015
0
  apdu.lc = sizeof(apduSendReponse);
2016
0
  apdu.data = apduSendReponse;
2017
0
  apdu.datalen = sizeof(apduSendReponse);
2018
0
  apdu.resp = apduSendResponseResponse;
2019
0
  apdu.resplen = sizeof(apduSendResponseResponse);
2020
0
  apdu.le = 256;
2021
0
  r = sc_transmit_apdu(card, &apdu);
2022
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2023
0
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return");
2024
2025
0
  if (apdu.resplen != 44)
2026
0
  {
2027
0
    sc_log(card->ctx, "Expecting a response len of 44 - found %d", (int)apdu.resplen);
2028
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
2029
0
  }
2030
  // init crypto
2031
0
  ctx = EVP_CIPHER_CTX_new();
2032
0
  if (ctx == NULL) {
2033
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
2034
0
  }
2035
0
  cipher = sc_evp_cipher(card->ctx, "DES-EDE3-CBC");
2036
0
  if (!EVP_DecryptInit(ctx, cipher, key, NULL)) {
2037
0
    sc_log_openssl(card->ctx);
2038
0
    sc_evp_cipher_free(cipher);
2039
0
    EVP_CIPHER_CTX_free(ctx);
2040
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
2041
0
  }
2042
0
  EVP_CIPHER_CTX_set_padding(ctx,0);
2043
0
  if (!EVP_DecryptUpdate(ctx, buffer3, &buffer3size, apdu.resp + 4, (int)apdu.resplen - 4)) {
2044
0
    sc_log_openssl(card->ctx);
2045
0
    sc_log(card->ctx, "unable to decrypt data");
2046
0
    sc_evp_cipher_free(cipher);
2047
0
    EVP_CIPHER_CTX_free(ctx);
2048
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
2049
0
  }
2050
0
  if (!EVP_DecryptFinal(ctx, buffer3 + buffer3size, &buffer3size)) {
2051
0
    sc_log_openssl(card->ctx);
2052
0
    sc_log(card->ctx, "unable to decrypt final data");
2053
0
    sc_evp_cipher_free(cipher);
2054
0
    EVP_CIPHER_CTX_free(ctx);
2055
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
2056
0
  }
2057
0
  sc_log(card->ctx, "data has been decrypted using the key");
2058
0
  if (memcmp(buffer3, randomR1, 16) != 0) {
2059
0
    sc_log_openssl(card->ctx);
2060
0
    sc_log(card->ctx, "R1 doesn't match");
2061
0
    sc_evp_cipher_free(cipher);
2062
0
    EVP_CIPHER_CTX_free(ctx);
2063
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
2064
0
  }
2065
0
  if (memcmp(buffer3 + 16, randomR2, 16) != 0) {
2066
0
    sc_log_openssl(card->ctx);
2067
0
    sc_log(card->ctx, "R2 doesn't match");
2068
0
    sc_evp_cipher_free(cipher);
2069
0
    EVP_CIPHER_CTX_free(ctx);
2070
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
2071
0
  }
2072
0
  if (buffer[39] != 0x80) {
2073
0
    sc_log_openssl(card->ctx);
2074
0
    sc_log(card->ctx, "Padding not found");
2075
0
    sc_evp_cipher_free(cipher);
2076
0
    EVP_CIPHER_CTX_free(ctx);
2077
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
2078
0
  }
2079
0
  EVP_CIPHER_CTX_free(ctx);
2080
0
  ctx = NULL;
2081
0
  sc_evp_cipher_free(cipher);
2082
0
  cipher = NULL;
2083
2084
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2085
0
#endif
2086
0
}
2087
2088
static int gids_card_ctl(sc_card_t * card, unsigned long cmd, void *ptr)
2089
1.16k
{
2090
1.16k
  LOG_FUNC_CALLED(card->ctx);
2091
1.16k
  switch (cmd) {
2092
131
    case SC_CARDCTL_GET_SERIALNR:
2093
131
      return gids_get_serialnr(card, (sc_serial_number_t *) ptr);
2094
815
    case SC_CARDCTL_GIDS_GET_ALL_CONTAINERS:
2095
815
      return gids_get_all_containers(card, (size_t*) ptr);
2096
0
    case SC_CARDCTL_GIDS_GET_CONTAINER_DETAIL:
2097
0
      return gids_get_container_detail(card, (sc_cardctl_gids_get_container_t*) ptr);
2098
54
    case SC_CARDCTL_GIDS_SELECT_KEY_REFERENCE:
2099
54
      return gids_select_key_reference(card, (sc_pkcs15_prkey_info_t*) ptr);
2100
0
    case SC_CARDCTL_GIDS_CREATE_KEY:
2101
0
      return gids_create_keyfile(card, (sc_pkcs15_object_t*) ptr);
2102
0
    case SC_CARDCTL_GIDS_GENERATE_KEY:
2103
0
      return gids_generate_key(card, ((struct sc_cardctl_gids_genkey*) ptr)->object, ((struct sc_cardctl_gids_genkey*) ptr)->pubkey);
2104
0
    case SC_CARDCTL_GIDS_IMPORT_KEY:
2105
0
      return gids_import_key(card, ((struct sc_cardctl_gids_importkey*) ptr)->object, ((struct sc_cardctl_gids_importkey*) ptr)->key);
2106
0
    case SC_CARDCTL_GIDS_SAVE_CERT:
2107
0
      return gids_save_certificate(card, ((struct sc_cardctl_gids_save_cert*) ptr)->certobject,
2108
0
                    ((struct sc_cardctl_gids_save_cert*) ptr)->privkeyobject, ((struct sc_cardctl_gids_save_cert*) ptr)->path);
2109
0
    case SC_CARDCTL_GIDS_DELETE_CERT:
2110
0
      return gids_delete_cert(card, (sc_pkcs15_object_t*) ptr);
2111
0
    case SC_CARDCTL_GIDS_DELETE_KEY:
2112
0
      return gids_delete_key(card, (sc_pkcs15_object_t*) ptr);
2113
0
    case SC_CARDCTL_GIDS_INITIALIZE:
2114
0
      return gids_initialize(card, (sc_cardctl_gids_init_param_t*) ptr);
2115
0
    case SC_CARDCTL_GIDS_SET_ADMIN_KEY:
2116
0
      return gids_set_administrator_key(card, (u8*) ptr);
2117
0
    case SC_CARDCTL_GIDS_AUTHENTICATE_ADMIN:
2118
0
      return gids_authenticate_admin(card, (u8*) ptr);
2119
165
    default:
2120
165
      return SC_ERROR_NOT_SUPPORTED;
2121
1.16k
  }
2122
1.16k
}
2123
2124
static int gids_card_reader_lock_obtained(sc_card_t *card, int was_reset)
2125
31.2k
{
2126
31.2k
  int r = SC_SUCCESS;
2127
2128
31.2k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
2129
2130
31.2k
  if (was_reset > 0) {
2131
0
    u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
2132
0
    size_t resplen = sizeof(rbuf);
2133
0
    r = gids_select_aid(card, gids_aid.value, gids_aid.len, rbuf, &resplen);
2134
0
  }
2135
2136
31.2k
  LOG_FUNC_RETURN(card->ctx, r);
2137
31.2k
}
2138
2139
static struct sc_card_driver *sc_get_driver(void)
2140
122k
{
2141
2142
122k
  if (iso_ops == NULL)
2143
10
    iso_ops = sc_get_iso7816_driver()->ops;
2144
2145
122k
  gids_ops.match_card = gids_match_card;
2146
122k
  gids_ops.init = gids_init;
2147
122k
  gids_ops.finish = gids_finish;
2148
122k
  gids_ops.read_binary = gids_read_binary;
2149
122k
  gids_ops.write_binary = NULL;
2150
122k
  gids_ops.update_binary = NULL;
2151
122k
  gids_ops.erase_binary = NULL;
2152
122k
  gids_ops.read_record = NULL;
2153
122k
  gids_ops.write_record = NULL;
2154
122k
  gids_ops.append_record = NULL;
2155
122k
  gids_ops.update_record = NULL;
2156
122k
  gids_ops.select_file = gids_select_file;
2157
122k
  gids_ops.get_response = iso_ops->get_response;
2158
122k
  gids_ops.get_challenge = NULL;
2159
122k
  gids_ops.verify = NULL; // see pin_cmd
2160
122k
  gids_ops.logout = gids_logout;
2161
122k
  gids_ops.restore_security_env = NULL;
2162
122k
  gids_ops.set_security_env = gids_set_security_env;
2163
122k
  gids_ops.decipher = gids_decipher;
2164
122k
  gids_ops.compute_signature = iso_ops->compute_signature;
2165
122k
  gids_ops.change_reference_data = NULL; // see pin_cmd
2166
122k
  gids_ops.reset_retry_counter = NULL; // see pin_cmd
2167
122k
  gids_ops.create_file = iso_ops->create_file;
2168
122k
  gids_ops.delete_file = NULL;
2169
122k
  gids_ops.list_files = NULL;
2170
122k
  gids_ops.check_sw = iso_ops->check_sw;
2171
122k
  gids_ops.card_ctl = gids_card_ctl;
2172
122k
  gids_ops.process_fci = iso_ops->process_fci;
2173
122k
  gids_ops.construct_fci = iso_ops->construct_fci;
2174
122k
  gids_ops.pin_cmd = gids_pin_cmd;
2175
122k
  gids_ops.get_data = NULL;
2176
122k
  gids_ops.put_data = NULL;
2177
122k
  gids_ops.delete_record = NULL;
2178
122k
  gids_ops.read_public_key = gids_read_public_key;
2179
122k
  gids_ops.card_reader_lock_obtained = gids_card_reader_lock_obtained;
2180
2181
122k
  return &gids_drv;
2182
122k
}
2183
2184
struct sc_card_driver *sc_get_gids_driver(void)
2185
122k
{
2186
122k
  return sc_get_driver();
2187
122k
}
2188
2189
#else
2190
2191
struct sc_card_driver *sc_get_gids_driver(void)
2192
{
2193
  return NULL;
2194
}
2195
2196
#endif