Coverage Report

Created: 2026-05-30 06:29

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