Coverage Report

Created: 2026-03-01 06:54

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