Coverage Report

Created: 2025-10-13 07:02

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