Coverage Report

Created: 2025-08-24 06:59

/src/opensc/src/libopensc/pkcs15.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * pkcs15.c: PKCS #15 general functions
3
 *
4
 * Copyright (C) 2001, 2002  Juha Yrjölä <juha.yrjola@iki.fi>
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
#ifdef HAVE_CONFIG_H
22
#include <config.h>
23
#endif
24
25
#include <stdlib.h>
26
#include <string.h>
27
#include <stdio.h>
28
#include <assert.h>
29
#include <ctype.h>
30
31
#include "cardctl.h"
32
#include "internal.h"
33
#include "pkcs15.h"
34
#include "asn1.h"
35
#include "common/libscdl.h"
36
37
#ifdef ENABLE_OPENSSL
38
#include <openssl/sha.h>
39
#endif
40
41
#ifdef HAVE_SYS_TIME_H
42
#include <sys/time.h>
43
#endif
44
45
#ifdef ENABLE_ZLIB
46
#include "compression.h"
47
#endif
48
49
static const struct sc_asn1_entry c_asn1_twlabel[] = {
50
  { "twlabel", SC_ASN1_UTF8STRING, SC_ASN1_TAG_UTF8STRING, 0, NULL, NULL },
51
  { NULL, 0, 0, 0, NULL, NULL }
52
};
53
54
static const struct sc_asn1_entry c_asn1_algorithm_info[7] = {
55
  { "reference",    SC_ASN1_INTEGER,  SC_ASN1_TAG_INTEGER,  0, NULL, NULL },
56
  { "algorithmPKCS#11", SC_ASN1_INTEGER,  SC_ASN1_TAG_INTEGER,  0, NULL, NULL },
57
  { "parameters",   SC_ASN1_CHOICE,   0,      0, NULL, NULL },
58
  { "supportedOperations",SC_ASN1_BIT_FIELD,  SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL },
59
  { "objId",    SC_ASN1_OBJECT,   SC_ASN1_TAG_OBJECT, SC_ASN1_OPTIONAL, NULL, NULL },
60
  { "algRef",   SC_ASN1_INTEGER,  SC_ASN1_TAG_INTEGER,  SC_ASN1_OPTIONAL, NULL, NULL },
61
  { NULL, 0, 0, 0, NULL, NULL }
62
};
63
64
static const struct sc_asn1_entry c_asn1_algorithm_info_parameters[3] = {
65
  { "PKCS15RSAParameters",SC_ASN1_NULL,   SC_ASN1_TAG_NULL, 0, NULL, NULL },
66
  { "PKCS15ECParameters", SC_ASN1_OBJECT,   SC_ASN1_TAG_OBJECT, 0, NULL, NULL },
67
  { NULL, 0, 0, 0, NULL, NULL }
68
};
69
70
/*
71
 * in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS  defined as 16
72
 */
73
static const struct sc_asn1_entry c_asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1] = {
74
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
75
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
76
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
77
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
78
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
79
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
80
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
81
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
82
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
83
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
84
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
85
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
86
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
87
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
88
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
89
  { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
90
  { NULL, 0, 0, 0, NULL, NULL }
91
};
92
93
#define C_ASN1_LAST_UPDATE_SIZE 3
94
static const struct sc_asn1_entry c_asn1_last_update[C_ASN1_LAST_UPDATE_SIZE] = {
95
  { "generalizedTime",  SC_ASN1_GENERALIZEDTIME, SC_ASN1_TAG_GENERALIZEDTIME, SC_ASN1_OPTIONAL, NULL, NULL },
96
  { "referencedTime", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS,  SC_ASN1_OPTIONAL, NULL, NULL },
97
  { NULL, 0, 0, 0, NULL, NULL }
98
};
99
100
#define C_ASN1_PROFILE_INDICATION_SIZE 3
101
static const struct sc_asn1_entry c_asn1_profile_indication[C_ASN1_PROFILE_INDICATION_SIZE] = {
102
  { "profileOID",   SC_ASN1_OBJECT,   SC_ASN1_TAG_OBJECT,     SC_ASN1_OPTIONAL, NULL, NULL },
103
  { "profileName",  SC_ASN1_UTF8STRING, SC_ASN1_TAG_UTF8STRING, SC_ASN1_OPTIONAL, NULL, NULL },
104
  { NULL, 0, 0, 0, NULL, NULL }
105
};
106
107
#define C_ASN1_TOKI_ATTRS_SIZE 15
108
static const struct sc_asn1_entry c_asn1_toki_attrs[C_ASN1_TOKI_ATTRS_SIZE] = {
109
  { "version",      SC_ASN1_INTEGER,    SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
110
  { "serialNumber",   SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
111
  { "manufacturerID", SC_ASN1_UTF8STRING,   SC_ASN1_TAG_UTF8STRING, SC_ASN1_OPTIONAL, NULL, NULL },
112
  { "label",      SC_ASN1_UTF8STRING,   SC_ASN1_CTX | 0, SC_ASN1_OPTIONAL, NULL, NULL },
113
  /* XXX the Taiwanese ID card erroneously uses explicit tagging */
114
  { "label-tw",       SC_ASN1_STRUCT,   SC_ASN1_CTX | 0 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
115
  { "tokenflags",     SC_ASN1_BIT_FIELD,    SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL },
116
  { "seInfo",     SC_ASN1_SE_INFO,    SC_ASN1_CONS | SC_ASN1_TAG_SEQUENCE, SC_ASN1_OPTIONAL, NULL, NULL },
117
  { "recordInfo",     SC_ASN1_STRUCT,   SC_ASN1_CONS | SC_ASN1_CTX | 1, SC_ASN1_OPTIONAL, NULL, NULL },
118
  { "supportedAlgorithms", SC_ASN1_STRUCT,  SC_ASN1_CONS | SC_ASN1_CTX | 2, SC_ASN1_OPTIONAL, NULL, NULL },
119
  { "issuerId",       SC_ASN1_UTF8STRING,   SC_ASN1_CTX | 3, SC_ASN1_OPTIONAL, NULL, NULL },
120
  { "holderId",       SC_ASN1_UTF8STRING,   SC_ASN1_CTX | 4, SC_ASN1_OPTIONAL, NULL, NULL },
121
  { "lastUpdate",     SC_ASN1_STRUCT,   SC_ASN1_CONS | SC_ASN1_CTX | 5, SC_ASN1_OPTIONAL, NULL, NULL },
122
  { "preferredLanguage", SC_ASN1_PRINTABLESTRING, SC_ASN1_TAG_PRINTABLESTRING, SC_ASN1_OPTIONAL, NULL, NULL },
123
  { "profileIndication", SC_ASN1_STRUCT,    SC_ASN1_CONS | SC_ASN1_CTX | 6, SC_ASN1_OPTIONAL, NULL, NULL },
124
  { NULL, 0, 0, 0, NULL, NULL }
125
};
126
127
static const struct sc_asn1_entry c_asn1_tokeninfo[] = {
128
  { "TokenInfo", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_TAG_SEQUENCE, 0, NULL, NULL },
129
  { NULL, 0, 0, 0, NULL, NULL }
130
};
131
132
static void sc_pkcs15_free_unusedspace(struct sc_pkcs15_card *);
133
static void sc_pkcs15_remove_dfs(struct sc_pkcs15_card *);
134
static void sc_pkcs15_remove_objects(struct sc_pkcs15_card *);
135
static int sc_pkcs15_aux_get_md_guid(struct sc_pkcs15_card *, const struct sc_pkcs15_object *,
136
    unsigned, unsigned char *, size_t *);
137
static void sc_pkcs15_clear_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo);
138
139
int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx,
140
  sc_pkcs15_tokeninfo_t *ti, const u8 *buf, size_t blen)
141
841
{
142
841
  int r;
143
841
  size_t ii;
144
841
  u8 serial[128];
145
841
  size_t serial_len = sizeof(serial);
146
841
  u8 mnfid[SC_PKCS15_MAX_LABEL_SIZE];
147
841
  size_t mnfid_len  = sizeof(mnfid) - 1;
148
841
  u8 label[SC_PKCS15_MAX_LABEL_SIZE];
149
841
  size_t label_len = sizeof(label) - 1;
150
841
  u8 last_update[32], profile_indication[SC_PKCS15_MAX_LABEL_SIZE];
151
841
  size_t lupdate_len = sizeof(last_update) - 1, pi_len = sizeof(profile_indication) - 1;
152
841
  size_t flags_len   = sizeof(ti->flags);
153
841
  u8 preferred_language[3];
154
841
  size_t lang_length = sizeof(preferred_language);
155
841
  struct sc_asn1_entry asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1],
156
841
      asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7],
157
841
      asn1_algo_infos_parameters[SC_MAX_SUPPORTED_ALGORITHMS][3];
158
841
  size_t reference_len = sizeof(ti->supported_algos[0].reference);
159
841
  size_t mechanism_len = sizeof(ti->supported_algos[0].mechanism);
160
841
  size_t parameter_len = sizeof(ti->supported_algos[0].parameters);
161
841
  size_t operations_len = sizeof(ti->supported_algos[0].operations);
162
841
  size_t algo_ref_len = sizeof(ti->supported_algos[0].algo_ref);
163
164
841
  struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE];
165
841
  struct sc_asn1_entry asn1_profile_indication[C_ASN1_PROFILE_INDICATION_SIZE];
166
841
  struct sc_asn1_entry asn1_toki_attrs[C_ASN1_TOKI_ATTRS_SIZE], asn1_tokeninfo[3], asn1_twlabel[3];
167
168
841
  memset(last_update, 0, sizeof(last_update));
169
841
  memset(label, 0, sizeof(label));
170
841
  memset(profile_indication, 0, sizeof(profile_indication));
171
841
  memset(mnfid, 0, sizeof(mnfid));
172
173
841
  sc_copy_asn1_entry(c_asn1_twlabel, asn1_twlabel);
174
841
  sc_copy_asn1_entry(c_asn1_toki_attrs, asn1_toki_attrs);
175
841
  sc_copy_asn1_entry(c_asn1_tokeninfo, asn1_tokeninfo);
176
841
  sc_copy_asn1_entry(c_asn1_last_update, asn1_last_update);
177
841
  sc_format_asn1_entry(asn1_twlabel, label, &label_len, 0);
178
841
  sc_copy_asn1_entry(c_asn1_profile_indication, asn1_profile_indication);
179
180
14.2k
  for (ii=0; ii<SC_MAX_SUPPORTED_ALGORITHMS; ii++) {
181
13.4k
    sc_copy_asn1_entry(c_asn1_algorithm_info, asn1_algo_infos[ii]);
182
13.4k
    sc_copy_asn1_entry(c_asn1_algorithm_info_parameters,
183
13.4k
      asn1_algo_infos_parameters[ii]);
184
13.4k
  }
185
841
  sc_copy_asn1_entry(c_asn1_supported_algorithms, asn1_supported_algorithms);
186
187
14.2k
  for (ii=0; ii<SC_MAX_SUPPORTED_ALGORITHMS; ii++)   {
188
13.4k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 0, &ti->supported_algos[ii].reference, &reference_len, 0);
189
13.4k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 1, &ti->supported_algos[ii].mechanism, &mechanism_len, 0);
190
13.4k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 2,
191
13.4k
      asn1_algo_infos_parameters[ii], NULL, 0);
192
13.4k
    sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 0,
193
13.4k
      NULL, NULL, 0);
194
13.4k
    sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 1,
195
13.4k
      &ti->supported_algos[ii].parameters, &parameter_len, 0);
196
13.4k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 3, &ti->supported_algos[ii].operations, &operations_len, 0);
197
13.4k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 4, &ti->supported_algos[ii].algo_id, NULL, 1);
198
13.4k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 5, &ti->supported_algos[ii].algo_ref, &algo_ref_len, 0);
199
13.4k
    sc_format_asn1_entry(asn1_supported_algorithms + ii, asn1_algo_infos[ii], NULL, 0);
200
13.4k
  }
201
202
841
  sc_format_asn1_entry(asn1_last_update + 0, last_update, &lupdate_len, 0);
203
841
  sc_format_asn1_entry(asn1_last_update + 1, &ti->last_update.path, NULL, 0);
204
205
841
  sc_format_asn1_entry(asn1_profile_indication + 0, &ti->profile_indication.oid, NULL, 0);
206
841
  sc_format_asn1_entry(asn1_profile_indication + 1, profile_indication, &pi_len, 0);
207
208
841
  sc_format_asn1_entry(asn1_toki_attrs + 0, &ti->version, NULL, 0);
209
841
  sc_format_asn1_entry(asn1_toki_attrs + 1, serial, &serial_len, 0);
210
841
  sc_format_asn1_entry(asn1_toki_attrs + 2, mnfid, &mnfid_len, 0);
211
841
  sc_format_asn1_entry(asn1_toki_attrs + 3, label, &label_len, 0);
212
841
  sc_format_asn1_entry(asn1_toki_attrs + 4, asn1_twlabel, NULL, 0);
213
841
  sc_format_asn1_entry(asn1_toki_attrs + 5, &ti->flags, &flags_len, 0);
214
841
  sc_format_asn1_entry(asn1_toki_attrs + 6, &ti->seInfo, &ti->num_seInfo, 0);
215
841
  sc_format_asn1_entry(asn1_toki_attrs + 7, NULL, NULL, 0);
216
841
  sc_format_asn1_entry(asn1_toki_attrs + 8, asn1_supported_algorithms, NULL, 0);
217
841
  sc_format_asn1_entry(asn1_toki_attrs + 9, NULL, NULL, 0);
218
841
  sc_format_asn1_entry(asn1_toki_attrs + 10, NULL, NULL, 0);
219
841
  sc_format_asn1_entry(asn1_toki_attrs + 11, asn1_last_update, NULL, 0);
220
841
  sc_format_asn1_entry(asn1_toki_attrs + 12, preferred_language, &lang_length, 0);
221
841
  sc_format_asn1_entry(asn1_toki_attrs + 13, asn1_profile_indication, NULL, 0);
222
841
  sc_format_asn1_entry(asn1_tokeninfo, asn1_toki_attrs, NULL, 0);
223
224
841
  r = sc_asn1_decode(ctx, asn1_tokeninfo, buf, blen, NULL, NULL);
225
841
  if (r != SC_SUCCESS) {
226
    /* The decoding could have allocated something we need to free */
227
429
    sc_pkcs15_clear_tokeninfo(ti);
228
429
    LOG_TEST_RET(ctx, r, "ASN.1 parsing of EF(TokenInfo) failed");
229
429
  }
230
231
412
  if (asn1_toki_attrs[1].flags & SC_ASN1_PRESENT && serial_len > 0)   {
232
216
    free(ti->serial_number);
233
216
    ti->serial_number = malloc(serial_len * 2 + 1);
234
216
    if (ti->serial_number == NULL)
235
0
      return SC_ERROR_OUT_OF_MEMORY;
236
216
    sc_bin_to_hex(serial, serial_len, ti->serial_number, serial_len * 2 + 1, 0);
237
216
    sc_log(ctx, "TokenInfo.serialNunmber '%s'", ti->serial_number);
238
216
  }
239
240
412
  if (ti->manufacturer_id == NULL) {
241
412
    if (asn1_toki_attrs[2].flags & SC_ASN1_PRESENT)
242
104
      ti->manufacturer_id = strdup((char *) mnfid);
243
308
    else
244
308
      ti->manufacturer_id = strdup("(unknown)");
245
412
    if (ti->manufacturer_id == NULL)
246
0
      return SC_ERROR_OUT_OF_MEMORY;
247
412
  }
248
412
  if (ti->label == NULL) {
249
412
    if (asn1_toki_attrs[3].flags & SC_ASN1_PRESENT ||
250
412
        asn1_toki_attrs[4].flags & SC_ASN1_PRESENT)
251
4
      ti->label = strdup((char *) label);
252
408
    else
253
408
      ti->label = strdup("(unknown)");
254
412
    if (ti->label == NULL)
255
0
      return SC_ERROR_OUT_OF_MEMORY;
256
412
  }
257
412
  if (asn1_toki_attrs[11].flags & SC_ASN1_PRESENT) {
258
71
    if (asn1_last_update[0].flags & SC_ASN1_PRESENT)   {
259
9
      sc_log(ctx, "LastUpdate.generalizedTime present");
260
9
      ti->last_update.gtime = strdup((char *)last_update);
261
9
      if (ti->last_update.gtime == NULL)
262
0
        return SC_ERROR_OUT_OF_MEMORY;
263
9
    }
264
62
    else if (asn1_last_update[1].flags & SC_ASN1_PRESENT)  {
265
57
      sc_log(ctx, "LastUpdate.referencedTime present");
266
57
    }
267
71
  }
268
412
  if (asn1_toki_attrs[12].flags & SC_ASN1_PRESENT) {
269
9
    preferred_language[2] = 0;
270
9
    ti->preferred_language = strdup((char *)preferred_language);
271
9
    if (ti->preferred_language == NULL)
272
0
      return SC_ERROR_OUT_OF_MEMORY;
273
9
  }
274
275
412
  sc_init_oid(&ti->profile_indication.oid);
276
412
  if (asn1_toki_attrs[13].flags & SC_ASN1_PRESENT) {
277
184
    if (asn1_profile_indication[0].flags & SC_ASN1_PRESENT)   {
278
6
      sc_log(ctx, "ProfileIndication.oid present");
279
6
    }
280
178
    else if (asn1_profile_indication[1].flags & SC_ASN1_PRESENT)  {
281
175
      sc_log(ctx, "ProfileIndication.name present");
282
175
      ti->profile_indication.name = strdup((char *)profile_indication);
283
175
      if (ti->profile_indication.name == NULL)
284
0
        return SC_ERROR_OUT_OF_MEMORY;
285
175
    }
286
184
  }
287
288
412
  sc_log(ctx, "LastUpdate.path '%s'", sc_print_path(&ti->last_update.path));
289
412
  sc_log(ctx, "ProfileIndication.name '%s'",  ti->profile_indication.name);
290
412
  return SC_SUCCESS;
291
412
}
292
293
294
int
295
sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti,
296
    u8 **buf, size_t *buflen)
297
0
{
298
0
  int r, ii;
299
0
  size_t serial_len, mnfid_len, label_len, flags_len, last_upd_len, pi_len;
300
301
0
  struct sc_asn1_entry asn1_toki_attrs[C_ASN1_TOKI_ATTRS_SIZE];
302
0
  struct sc_asn1_entry asn1_tokeninfo[2];
303
0
  struct sc_asn1_entry asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1],
304
0
      asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7],
305
0
      asn1_algo_infos_parameters[SC_MAX_SUPPORTED_ALGORITHMS][3];
306
0
  size_t reference_len = sizeof(ti->supported_algos[0].reference);
307
0
  size_t mechanism_len = sizeof(ti->supported_algos[0].mechanism);
308
0
  size_t parameter_len = sizeof(ti->supported_algos[0].parameters);
309
0
  size_t operations_len = sizeof(ti->supported_algos[0].operations);
310
0
  size_t algo_ref_len = sizeof(ti->supported_algos[0].algo_ref);
311
0
  struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE];
312
0
  struct sc_asn1_entry asn1_profile_indication[C_ASN1_PROFILE_INDICATION_SIZE];
313
0
  u8 serial[128];
314
315
0
  sc_copy_asn1_entry(c_asn1_toki_attrs, asn1_toki_attrs);
316
0
  sc_copy_asn1_entry(c_asn1_tokeninfo, asn1_tokeninfo);
317
0
  sc_copy_asn1_entry(c_asn1_last_update, asn1_last_update);
318
0
  sc_copy_asn1_entry(c_asn1_profile_indication, asn1_profile_indication);
319
320
0
  for (ii=0; ii<SC_MAX_SUPPORTED_ALGORITHMS && ti->supported_algos[ii].reference; ii++) {
321
0
    sc_copy_asn1_entry(c_asn1_algorithm_info, asn1_algo_infos[ii]);
322
0
    sc_copy_asn1_entry(c_asn1_algorithm_info_parameters,
323
0
      asn1_algo_infos_parameters[ii]);
324
0
  }
325
0
  sc_copy_asn1_entry(c_asn1_supported_algorithms, asn1_supported_algorithms);
326
327
0
  for (ii=0; ii<SC_MAX_SUPPORTED_ALGORITHMS && ti->supported_algos[ii].reference; ii++)   {
328
0
    sc_format_asn1_entry(asn1_algo_infos[ii] + 0, &ti->supported_algos[ii].reference, &reference_len, 1);
329
0
    sc_format_asn1_entry(asn1_algo_infos[ii] + 1, &ti->supported_algos[ii].mechanism, &mechanism_len, 1);
330
0
    sc_format_asn1_entry(asn1_algo_infos[ii] + 2,
331
0
      asn1_algo_infos_parameters[ii], NULL, 1);
332
0
    if (!sc_valid_oid(&ti->supported_algos[ii].parameters)) {
333
0
      sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 0,
334
0
        NULL, NULL, 1);
335
0
    }
336
0
    else {
337
0
      sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 1,
338
0
        &ti->supported_algos[ii].parameters, &parameter_len, 0);
339
0
    }
340
0
    sc_format_asn1_entry(asn1_algo_infos[ii] + 3, &ti->supported_algos[ii].operations, &operations_len, 1);
341
0
    sc_format_asn1_entry(asn1_algo_infos[ii] + 4, &ti->supported_algos[ii].algo_id, NULL, 1);
342
0
    sc_format_asn1_entry(asn1_algo_infos[ii] + 5, &ti->supported_algos[ii].algo_ref, &algo_ref_len, 1);
343
0
    sc_format_asn1_entry(asn1_supported_algorithms + ii, asn1_algo_infos[ii], NULL, 1);
344
0
  }
345
346
0
  sc_format_asn1_entry(asn1_toki_attrs + 0, &ti->version, NULL, 1);
347
0
  if (ti->serial_number != NULL) {
348
0
    serial_len = 0;
349
0
    if (strlen(ti->serial_number)/2 > sizeof(serial))
350
0
      return SC_ERROR_BUFFER_TOO_SMALL;
351
0
    serial_len = sizeof(serial);
352
0
    if (sc_hex_to_bin(ti->serial_number, serial, &serial_len) < 0)
353
0
      return SC_ERROR_INVALID_ARGUMENTS;
354
0
    sc_format_asn1_entry(asn1_toki_attrs + 1, serial, &serial_len, 1);
355
0
  }
356
0
  else   {
357
0
    sc_format_asn1_entry(asn1_toki_attrs + 1, NULL, NULL, 0);
358
0
  }
359
360
0
  if (ti->manufacturer_id != NULL) {
361
0
    mnfid_len = strlen(ti->manufacturer_id);
362
0
    sc_format_asn1_entry(asn1_toki_attrs + 2, ti->manufacturer_id, &mnfid_len, 1);
363
0
  }
364
0
  else    {
365
0
    sc_format_asn1_entry(asn1_toki_attrs + 2, NULL, NULL, 0);
366
0
  }
367
368
0
  if (ti->label != NULL) {
369
0
    label_len = strlen(ti->label);
370
0
    sc_format_asn1_entry(asn1_toki_attrs + 3, ti->label, &label_len, 1);
371
0
  }
372
0
  else   {
373
0
    sc_format_asn1_entry(asn1_toki_attrs + 3, NULL, NULL, 0);
374
0
  }
375
376
0
  if (ti->flags) {
377
0
    flags_len = sizeof(ti->flags);
378
0
    sc_format_asn1_entry(asn1_toki_attrs + 5, &ti->flags, &flags_len, 1);
379
0
  }
380
0
  else   {
381
0
    sc_format_asn1_entry(asn1_toki_attrs + 5, NULL, NULL, 0);
382
0
  }
383
384
0
  if (ti->num_seInfo)
385
0
    sc_format_asn1_entry(asn1_toki_attrs + 6, ti->seInfo, &ti->num_seInfo, 1);
386
0
  else
387
0
    sc_format_asn1_entry(asn1_toki_attrs + 6, NULL, NULL, 0);
388
389
0
  sc_format_asn1_entry(asn1_toki_attrs + 7, NULL, NULL, 0);
390
391
0
  if (ti->supported_algos[0].reference)
392
0
    sc_format_asn1_entry(asn1_toki_attrs + 8, asn1_supported_algorithms, NULL, 1);
393
0
  else
394
0
    sc_format_asn1_entry(asn1_toki_attrs + 8, NULL, NULL, 0);
395
396
0
  sc_format_asn1_entry(asn1_toki_attrs + 9, NULL, NULL, 0);
397
0
  sc_format_asn1_entry(asn1_toki_attrs + 10, NULL, NULL, 0);
398
399
0
  if (ti->last_update.path.len) {
400
0
    sc_format_asn1_entry(asn1_last_update + 0, &ti->last_update.path, NULL, 1);
401
0
    sc_format_asn1_entry(asn1_toki_attrs + 11, asn1_last_update, NULL, 1);
402
0
  }
403
0
  else if (ti->last_update.gtime != NULL) {
404
0
    last_upd_len = strlen(ti->last_update.gtime);
405
0
    sc_format_asn1_entry(asn1_last_update + 0, ti->last_update.gtime, &last_upd_len, 1);
406
0
    sc_format_asn1_entry(asn1_toki_attrs + 11, asn1_last_update, NULL, 1);
407
0
  }
408
0
  else   {
409
0
    sc_format_asn1_entry(asn1_toki_attrs + 11, NULL, NULL, 0);
410
0
  }
411
0
  sc_format_asn1_entry(asn1_toki_attrs + 12, NULL, NULL, 0);
412
413
0
  if (sc_valid_oid(&ti->profile_indication.oid))   {
414
0
    sc_format_asn1_entry(asn1_profile_indication + 0, &ti->profile_indication.oid, NULL, 1);
415
0
    sc_format_asn1_entry(asn1_toki_attrs + 13, asn1_profile_indication, NULL, 1);
416
0
  }
417
0
  else if (ti->profile_indication.name)   {
418
0
    pi_len = strlen(ti->profile_indication.name);
419
0
    sc_format_asn1_entry(asn1_profile_indication + 1, ti->profile_indication.name, &pi_len, 1);
420
0
    sc_format_asn1_entry(asn1_toki_attrs + 13, asn1_profile_indication, NULL, 1);
421
0
  }
422
0
  else    {
423
0
    sc_format_asn1_entry(asn1_toki_attrs + 13, NULL, NULL, 0);
424
0
  }
425
426
0
  sc_format_asn1_entry(asn1_tokeninfo, asn1_toki_attrs, NULL, 1);
427
428
0
  r = sc_asn1_encode(ctx, asn1_tokeninfo, buf, buflen);
429
0
  LOG_TEST_RET(ctx, r, "sc_asn1_encode() failed");
430
431
0
  return SC_SUCCESS;
432
0
}
433
434
static const struct sc_asn1_entry c_asn1_ddo[] = {
435
  { "oid",     SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_OPTIONAL, NULL, NULL },
436
  { "odfPath",     SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_TAG_SEQUENCE, SC_ASN1_OPTIONAL, NULL, NULL },
437
  { "tokenInfoPath", SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_CTX | 0, SC_ASN1_OPTIONAL, NULL, NULL },
438
  { "unusedPath",    SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_CTX | 1, SC_ASN1_OPTIONAL, NULL, NULL },
439
/* According to PKCS#15 v1.1 here is the place for the future extensions.
440
 * The following data are used when ODF record points to the xDF files in a different application.
441
 */
442
  { "ddoIIN",    SC_ASN1_OCTET_STRING, SC_ASN1_APP | 0x02, SC_ASN1_OPTIONAL, NULL, NULL },
443
  { "ddoAID",    SC_ASN1_OCTET_STRING, SC_ASN1_APP | 0x0F, SC_ASN1_OPTIONAL, NULL, NULL },
444
  { NULL, 0, 0, 0, NULL, NULL }
445
};
446
447
static void
448
fix_authentic_ddo(struct sc_pkcs15_card *p15card)
449
30
{
450
  /* AuthentIC v3.2 card has invalid ODF and tokenInfo paths encoded into DDO.
451
   * Cleanup this attributes -- default values must be OK.
452
   */
453
30
  if (p15card->card->type == SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2)   {
454
0
    sc_file_free(p15card->file_odf);
455
0
    p15card->file_odf = NULL;
456
0
    sc_file_free(p15card->file_tokeninfo);
457
0
    p15card->file_tokeninfo = NULL;
458
0
  }
459
30
}
460
461
static int
462
parse_ddo(struct sc_pkcs15_card *p15card, const u8 * buf, size_t buflen)
463
36
{
464
36
  struct sc_context *ctx = p15card->card->ctx;
465
36
  struct sc_asn1_entry asn1_ddo[7];
466
36
  sc_path_t odf_path, ti_path, us_path;
467
36
  struct sc_iid iid;
468
36
  struct sc_aid aid;
469
36
  int r;
470
471
36
  LOG_FUNC_CALLED(ctx);
472
473
36
  iid.len = sizeof(iid.value);
474
36
  aid.len = sizeof(aid.value);
475
476
36
  sc_copy_asn1_entry(c_asn1_ddo, asn1_ddo);
477
36
  sc_format_asn1_entry(asn1_ddo + 1, &odf_path, NULL, 0);
478
36
  sc_format_asn1_entry(asn1_ddo + 2, &ti_path, NULL, 0);
479
36
  sc_format_asn1_entry(asn1_ddo + 3, &us_path, NULL, 0);
480
36
  sc_format_asn1_entry(asn1_ddo + 4, iid.value, &iid.len, 0);
481
36
  sc_format_asn1_entry(asn1_ddo + 5, aid.value, &aid.len, 0);
482
483
36
  r = sc_asn1_decode(ctx, asn1_ddo, buf, buflen, NULL, NULL);
484
36
  LOG_TEST_RET(ctx, r, "DDO parsing failed");
485
486
30
  if (asn1_ddo[1].flags & SC_ASN1_PRESENT) {
487
8
    sc_file_free(p15card->file_odf);
488
8
    p15card->file_odf = sc_file_new();
489
8
    if (p15card->file_odf == NULL)
490
0
      goto mem_err;
491
8
    p15card->file_odf->path = odf_path;
492
8
  }
493
30
  if (asn1_ddo[2].flags & SC_ASN1_PRESENT) {
494
3
    sc_file_free(p15card->file_tokeninfo);
495
3
    p15card->file_tokeninfo = sc_file_new();
496
3
    if (p15card->file_tokeninfo == NULL)
497
0
      goto mem_err;
498
3
    p15card->file_tokeninfo->path = ti_path;
499
3
  }
500
30
  if (asn1_ddo[3].flags & SC_ASN1_PRESENT) {
501
3
    sc_file_free(p15card->file_unusedspace);
502
3
    p15card->file_unusedspace = sc_file_new();
503
3
    if (p15card->file_unusedspace == NULL)
504
0
      goto mem_err;
505
3
    p15card->file_unusedspace->path = us_path;
506
3
  }
507
30
  if (asn1_ddo[4].flags & SC_ASN1_PRESENT) {
508
3
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "DDO.IID '%s'", sc_dump_hex(iid.value, iid.len));
509
3
    memcpy(&p15card->app->ddo.iid, &iid, sizeof(struct sc_iid));
510
3
  }
511
30
  if (asn1_ddo[5].flags & SC_ASN1_PRESENT) {
512
3
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "DDO.AID '%s'", sc_dump_hex(aid.value, aid.len));
513
3
    memcpy(&p15card->app->ddo.aid, &aid, sizeof(struct sc_aid));
514
3
  }
515
516
30
  fix_authentic_ddo(p15card);
517
30
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
518
0
mem_err:
519
0
  sc_file_free(p15card->file_odf);
520
0
  p15card->file_odf = NULL;
521
0
  sc_file_free(p15card->file_tokeninfo);
522
0
  p15card->file_tokeninfo = NULL;
523
0
  sc_file_free(p15card->file_unusedspace);
524
0
  p15card->file_unusedspace = NULL;
525
0
  LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
526
0
}
527
528
529
char *
530
sc_pkcs15_get_lastupdate(struct sc_pkcs15_card *p15card)
531
3.56k
{
532
3.56k
  struct sc_context *ctx  = p15card->card->ctx;
533
3.56k
  struct sc_file *file = NULL;
534
3.56k
  struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE];
535
3.56k
  unsigned char *content, last_update[32] = {0};
536
3.56k
  size_t lupdate_len = sizeof(last_update) - 1;
537
3.56k
  int r, content_len;
538
3.56k
  size_t size;
539
540
3.56k
  if (p15card->tokeninfo->last_update.gtime)
541
40
    goto done;
542
543
3.52k
  if (!p15card->tokeninfo->last_update.path.len)
544
3.02k
    return NULL;
545
546
504
  r = sc_select_file(p15card->card, &p15card->tokeninfo->last_update.path, &file);
547
504
  if (r < 0)
548
446
    return NULL;
549
550
58
  size = file->size ? file->size : 1024;
551
58
  sc_file_free(file);
552
553
58
  content = calloc(1, size);
554
58
  if (!content)
555
0
    return NULL;
556
557
58
  r = sc_read_binary(p15card->card, 0, content, size, 0);
558
58
  if (r < 0) {
559
23
    free(content);
560
23
    return NULL;
561
23
  }
562
35
  content_len = r;
563
564
35
  sc_copy_asn1_entry(c_asn1_last_update, asn1_last_update);
565
35
  sc_format_asn1_entry(asn1_last_update + 0, last_update, &lupdate_len, 0);
566
567
35
  r = sc_asn1_decode(ctx, asn1_last_update, content, content_len, NULL, NULL);
568
35
  free(content);
569
35
  if (r < 0)
570
3
    return NULL;
571
572
32
  if (asn1_last_update[0].flags & SC_ASN1_PRESENT) {
573
2
    p15card->tokeninfo->last_update.gtime = strdup((char *)last_update);
574
2
    if (!p15card->tokeninfo->last_update.gtime)
575
0
      return NULL;
576
2
  }
577
72
done:
578
72
  sc_log(ctx, "lastUpdate.gtime '%s'", p15card->tokeninfo->last_update.gtime);
579
72
  return p15card->tokeninfo->last_update.gtime;
580
32
}
581
582
583
static const struct sc_asn1_entry c_asn1_odf[] = {
584
  { "privateKeys",   SC_ASN1_STRUCT, SC_ASN1_CTX | 0 | SC_ASN1_CONS, 0, NULL, NULL },
585
  { "publicKeys",    SC_ASN1_STRUCT, SC_ASN1_CTX | 1 | SC_ASN1_CONS, 0, NULL, NULL },
586
  { "trustedPublicKeys",   SC_ASN1_STRUCT, SC_ASN1_CTX | 2 | SC_ASN1_CONS, 0, NULL, NULL },
587
  { "secretKeys",    SC_ASN1_STRUCT, SC_ASN1_CTX | 3 | SC_ASN1_CONS, 0, NULL, NULL },
588
  { "certificates",  SC_ASN1_STRUCT, SC_ASN1_CTX | 4 | SC_ASN1_CONS, 0, NULL, NULL },
589
  { "trustedCertificates", SC_ASN1_STRUCT, SC_ASN1_CTX | 5 | SC_ASN1_CONS, 0, NULL, NULL },
590
  { "usefulCertificates",  SC_ASN1_STRUCT, SC_ASN1_CTX | 6 | SC_ASN1_CONS, 0, NULL, NULL },
591
  { "dataObjects",   SC_ASN1_STRUCT, SC_ASN1_CTX | 7 | SC_ASN1_CONS, 0, NULL, NULL },
592
  { "authObjects",   SC_ASN1_STRUCT, SC_ASN1_CTX | 8 | SC_ASN1_CONS, 0, NULL, NULL },
593
  { NULL, 0, 0, 0, NULL, NULL }
594
};
595
596
static const unsigned int odf_indexes[] = {
597
  SC_PKCS15_PRKDF,
598
  SC_PKCS15_PUKDF,
599
  SC_PKCS15_PUKDF_TRUSTED,
600
  SC_PKCS15_SKDF,
601
  SC_PKCS15_CDF,
602
  SC_PKCS15_CDF_TRUSTED,
603
  SC_PKCS15_CDF_USEFUL,
604
  SC_PKCS15_DODF,
605
  SC_PKCS15_AODF,
606
};
607
608
609
static int
610
parse_odf(const unsigned char * buf, size_t buflen, struct sc_pkcs15_card *p15card)
611
424
{
612
424
  const unsigned char *p = buf;
613
424
  size_t left = buflen;
614
424
  int r, i, type;
615
424
  struct sc_path path;
616
424
  struct sc_asn1_entry asn1_obj_or_path[] = {
617
424
    { "path", SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_SEQUENCE, 0, &path, NULL },
618
424
    { NULL, 0, 0, 0, NULL, NULL }
619
424
  };
620
424
  struct sc_asn1_entry asn1_odf[10];
621
622
424
  sc_copy_asn1_entry(c_asn1_odf, asn1_odf);
623
4.24k
  for (i = 0; asn1_odf[i].name != NULL; i++)
624
3.81k
    sc_format_asn1_entry(asn1_odf + i, asn1_obj_or_path, NULL, 0);
625
4.56k
  while (left > 0) {
626
4.49k
    r = sc_asn1_decode_choice(p15card->card->ctx, asn1_odf, p, left, &p, &left);
627
4.49k
    if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
628
169
      break;
629
4.32k
    if (r < 0)
630
186
      return r;
631
4.14k
    type = r;
632
4.14k
    if (p15card->file_app) {
633
4.14k
      r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &path);
634
4.14k
      if (r < 0)
635
2
        return r;
636
4.13k
      r = sc_pkcs15_add_df(p15card, odf_indexes[type], &path);
637
4.13k
      if (r)
638
0
        return r;
639
4.13k
    }
640
4.14k
  }
641
236
  return 0;
642
424
}
643
644
645
int
646
sc_pkcs15_encode_odf(struct sc_context *ctx, struct sc_pkcs15_card *p15card,
647
       unsigned char **buf, size_t *buflen)
648
0
{
649
0
  struct sc_path path;
650
0
  struct sc_asn1_entry asn1_obj_or_path[] = {
651
0
    { "path", SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_SEQUENCE, 0, &path, NULL },
652
0
    { NULL, 0, 0, 0, NULL, NULL }
653
0
  };
654
0
  struct sc_asn1_entry *asn1_paths = NULL;
655
0
  struct sc_asn1_entry *asn1_odf = NULL;
656
0
  int df_count = 0, r, c = 0;
657
0
  const int nr_indexes = sizeof(odf_indexes)/sizeof(odf_indexes[0]);
658
0
  struct sc_pkcs15_df *df;
659
660
0
  df = p15card->df_list;
661
0
  while (df != NULL) {
662
0
    df_count++;
663
0
    df = df->next;
664
0
  };
665
0
  if (df_count == 0)
666
0
    LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "No DF's found.");
667
668
0
  asn1_odf = malloc(sizeof(struct sc_asn1_entry) * (df_count + 1));
669
0
  if (asn1_odf == NULL) {
670
0
    r = SC_ERROR_OUT_OF_MEMORY;
671
0
    goto err;
672
0
  }
673
0
  asn1_paths = malloc(sizeof(struct sc_asn1_entry) * (df_count * 2));
674
0
  if (asn1_paths == NULL) {
675
0
    r = SC_ERROR_OUT_OF_MEMORY;
676
0
    goto err;
677
0
  }
678
0
  for (df = p15card->df_list; df != NULL; df = df->next) {
679
0
    int j, type = -1;
680
681
0
    for (j = 0; j < nr_indexes; j++)
682
0
      if (odf_indexes[j] == df->type) {
683
0
        type = j;
684
0
        break;
685
0
      }
686
0
    if (type == -1) {
687
0
      sc_log(ctx, "Unsupported DF type.");
688
0
      continue;
689
0
    }
690
0
    asn1_odf[c] = c_asn1_odf[type];
691
0
    sc_format_asn1_entry(asn1_odf + c, asn1_paths + 2*c, NULL, 1);
692
0
    sc_copy_asn1_entry(asn1_obj_or_path, asn1_paths + 2*c);
693
0
    sc_format_asn1_entry(asn1_paths + 2*c, &df->path, NULL, 1);
694
0
    c++;
695
0
  }
696
0
  asn1_odf[c].name = NULL;
697
0
  r = sc_asn1_encode(ctx, asn1_odf, buf, buflen);
698
0
err:
699
0
  if (asn1_paths != NULL)
700
0
    free(asn1_paths);
701
0
  if (asn1_odf != NULL)
702
0
    free(asn1_odf);
703
0
  return r;
704
0
}
705
706
707
struct sc_pkcs15_card *
708
sc_pkcs15_card_new(void)
709
12.6k
{
710
12.6k
  struct sc_pkcs15_card *p15card;
711
712
12.6k
  p15card = calloc(1, sizeof(struct sc_pkcs15_card));
713
12.6k
  if (p15card == NULL)
714
0
    return NULL;
715
716
12.6k
  p15card->tokeninfo = calloc(1, sizeof(struct sc_pkcs15_tokeninfo));
717
12.6k
  if (p15card->tokeninfo == NULL) {
718
0
    free(p15card);
719
0
    return NULL;
720
0
  }
721
722
12.6k
  p15card->magic = SC_PKCS15_CARD_MAGIC;
723
12.6k
  return p15card;
724
12.6k
}
725
726
727
struct sc_pkcs15_tokeninfo *
728
sc_pkcs15_tokeninfo_new(void)
729
8.91k
{
730
8.91k
  struct sc_pkcs15_tokeninfo *tokeninfo;
731
732
8.91k
  tokeninfo = calloc(1, sizeof(struct sc_pkcs15_tokeninfo));
733
8.91k
  if (tokeninfo == NULL) {
734
0
    return NULL;
735
0
  }
736
737
8.91k
  sc_init_oid(&tokeninfo->profile_indication.oid);
738
739
8.91k
  return tokeninfo;
740
8.91k
}
741
742
static void
743
sc_pkcs15_clear_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo)
744
22.0k
{
745
22.0k
  if (!tokeninfo)
746
0
    return;
747
748
22.0k
  free(tokeninfo->label);
749
22.0k
  tokeninfo->label = NULL;
750
22.0k
  free(tokeninfo->serial_number);
751
22.0k
  tokeninfo->serial_number = NULL;
752
22.0k
  free(tokeninfo->manufacturer_id);
753
22.0k
  tokeninfo->manufacturer_id = NULL;
754
22.0k
  free(tokeninfo->last_update.gtime);
755
22.0k
  tokeninfo->last_update.gtime = NULL;
756
22.0k
  free(tokeninfo->preferred_language);
757
22.0k
  tokeninfo->preferred_language = NULL;
758
22.0k
  free(tokeninfo->profile_indication.name);
759
22.0k
  tokeninfo->profile_indication.name = NULL;
760
22.0k
  if (tokeninfo->seInfo != NULL) {
761
8
    unsigned i;
762
11
    for (i = 0; i < tokeninfo->num_seInfo; i++)
763
3
      free(tokeninfo->seInfo[i]);
764
8
    free(tokeninfo->seInfo);
765
8
    tokeninfo->seInfo = NULL;
766
8
  }
767
22.0k
}
768
769
void
770
sc_pkcs15_free_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo)
771
23.0k
{
772
23.0k
  if (!tokeninfo)
773
1.49k
    return;
774
775
21.6k
  sc_pkcs15_clear_tokeninfo(tokeninfo);
776
21.6k
  free(tokeninfo);
777
21.6k
}
778
779
void
780
sc_pkcs15_free_app(struct sc_pkcs15_card *p15card)
781
41.2k
{
782
41.2k
  if (p15card && p15card->app) {
783
683
    free(p15card->app->label);
784
683
    free(p15card->app->ddo.value);
785
683
    free(p15card->app);
786
683
    p15card->app = NULL;
787
683
  }
788
41.2k
}
789
790
791
void
792
sc_pkcs15_card_free(struct sc_pkcs15_card *p15card)
793
12.6k
{
794
12.6k
  if (p15card == NULL || p15card->magic != SC_PKCS15_CARD_MAGIC)
795
0
    return;
796
797
12.6k
  if (p15card->ops.clear)
798
861
    p15card->ops.clear(p15card);
799
800
  /* For more complicated MD data a dedicated release procedure
801
   * has to be implemented. */
802
12.6k
  if (p15card->md_data)
803
0
    free(p15card->md_data);
804
805
12.6k
  sc_pkcs15_free_app(p15card);
806
12.6k
  sc_pkcs15_remove_objects(p15card);
807
12.6k
  sc_pkcs15_remove_dfs(p15card);
808
12.6k
  sc_pkcs15_free_unusedspace(p15card);
809
12.6k
  p15card->unusedspace_read = 0;
810
811
12.6k
  sc_file_free(p15card->file_app);
812
12.6k
  sc_file_free(p15card->file_tokeninfo);
813
12.6k
  sc_file_free(p15card->file_odf);
814
12.6k
  sc_file_free(p15card->file_unusedspace);
815
816
12.6k
  p15card->magic = 0;
817
12.6k
  sc_pkcs15_free_tokeninfo(p15card->tokeninfo);
818
12.6k
  sc_pkcs15_free_app(p15card);
819
12.6k
  free(p15card);
820
12.6k
}
821
822
823
void
824
sc_pkcs15_card_clear(struct sc_pkcs15_card *p15card)
825
15.4k
{
826
15.4k
  if (p15card == NULL)
827
0
    return;
828
829
15.4k
  if (p15card->ops.clear)
830
747
    p15card->ops.clear(p15card);
831
832
15.4k
  p15card->flags = 0;
833
15.4k
  p15card->tokeninfo->version = 0;
834
15.4k
  p15card->tokeninfo->flags   = 0;
835
836
15.4k
  sc_pkcs15_remove_objects(p15card);
837
15.4k
  sc_pkcs15_remove_dfs(p15card);
838
839
15.4k
  p15card->df_list = NULL;
840
15.4k
  sc_file_free(p15card->file_app);
841
15.4k
  p15card->file_app = NULL;
842
15.4k
  sc_file_free(p15card->file_tokeninfo);
843
15.4k
  p15card->file_tokeninfo = NULL;
844
15.4k
  sc_file_free(p15card->file_odf);
845
15.4k
  p15card->file_odf = NULL;
846
15.4k
  sc_file_free(p15card->file_unusedspace);
847
15.4k
  p15card->file_unusedspace = NULL;
848
849
15.4k
  free(p15card->tokeninfo->label);
850
15.4k
  p15card->tokeninfo->label = NULL;
851
15.4k
  free(p15card->tokeninfo->serial_number);
852
15.4k
  p15card->tokeninfo->serial_number = NULL;
853
15.4k
  free(p15card->tokeninfo->manufacturer_id);
854
15.4k
  p15card->tokeninfo->manufacturer_id = NULL;
855
15.4k
  free(p15card->tokeninfo->last_update.gtime);
856
15.4k
  p15card->tokeninfo->last_update.gtime = NULL;
857
15.4k
  free(p15card->tokeninfo->preferred_language);
858
15.4k
  p15card->tokeninfo->preferred_language = NULL;
859
15.4k
  free(p15card->tokeninfo->profile_indication.name);
860
15.4k
  p15card->tokeninfo->profile_indication.name = NULL;
861
15.4k
  if (p15card->tokeninfo->seInfo != NULL) {
862
43
    size_t i;
863
43
    for (i = 0; i < p15card->tokeninfo->num_seInfo; i++)
864
0
      free(p15card->tokeninfo->seInfo[i]);
865
43
    free(p15card->tokeninfo->seInfo);
866
43
    p15card->tokeninfo->seInfo     = NULL;
867
43
    p15card->tokeninfo->num_seInfo = 0;
868
43
  }
869
870
15.4k
  sc_pkcs15_free_app(p15card);
871
15.4k
}
872
873
874
struct sc_app_info *
875
sc_find_app(struct sc_card *card, struct sc_aid *aid)
876
12.3k
{
877
12.3k
  int ii;
878
879
12.3k
  if (card->app_count <= 0)
880
11.9k
    return NULL;
881
882
382
  if (!aid || !aid->len)
883
382
    return card->app[0];
884
885
0
  for (ii=0; ii < card->app_count; ii++) {
886
0
    if (card->app[ii]->aid.len != aid->len)
887
0
      continue;
888
0
    if (memcmp(card->app[ii]->aid.value, aid->value, aid->len))
889
0
      continue;
890
0
    return card->app[ii];
891
0
  }
892
0
  return NULL;
893
0
}
894
895
896
static struct sc_app_info *
897
sc_dup_app_info(const struct sc_app_info *info)
898
382
{
899
382
  struct sc_app_info *out = calloc(1, sizeof(struct sc_app_info));
900
901
382
  if (!out)
902
0
    return NULL;
903
904
382
  memcpy(out, info, sizeof(struct sc_app_info));
905
906
382
  if (info->label) {
907
15
    out->label = strdup(info->label);
908
15
    if (!out->label) {
909
0
      free(out);
910
0
      return NULL;
911
0
    }
912
15
  } else
913
367
    out->label = NULL;
914
915
382
  out->ddo.value = malloc(info->ddo.len);
916
382
  if (!out->ddo.value) {
917
0
    free(out->label);
918
0
    free(out);
919
0
    return NULL;
920
0
  }
921
382
  memcpy(out->ddo.value, info->ddo.value, info->ddo.len);
922
382
  out->ddo.len = info->ddo.len;
923
924
382
  return out;
925
382
}
926
927
928
struct sc_app_info *
929
sc_pkcs15_get_application_by_type(struct sc_card * card, char *app_type)
930
0
{
931
0
  struct sc_app_info *out = NULL;
932
0
  scconf_block *conf_block = NULL;
933
0
  int i, rv;
934
935
0
  if (!card)
936
0
    return NULL;
937
938
0
  if (card->app_count < 0)   {
939
0
    rv = sc_enum_apps(card);
940
0
    if (rv < 0 && rv != SC_ERROR_FILE_NOT_FOUND)
941
0
      return NULL;
942
0
  }
943
944
0
  conf_block = sc_get_conf_block(card->ctx, "framework", "pkcs15", 1);
945
0
  if (!conf_block)
946
0
    return NULL;
947
948
0
  for (i = 0; i < card->app_count; i++)   {
949
0
    struct sc_app_info *app_info = card->app[i];
950
0
    scconf_block **blocks = NULL;
951
0
    char str_path[SC_MAX_AID_STRING_SIZE];
952
953
0
    sc_bin_to_hex(app_info->aid.value, app_info->aid.len, str_path, sizeof(str_path), 0);
954
0
    blocks = scconf_find_blocks(card->ctx->conf, conf_block, "application", str_path);
955
0
    if (blocks)   {
956
0
      if (blocks[0])   {
957
0
        char *type = (char *)scconf_get_str(blocks[0], "type", app_type);
958
0
        if (!strcmp(type, app_type))   {
959
0
          out = app_info;
960
0
          free(blocks);
961
0
          break;
962
0
        }
963
0
      }
964
0
      free(blocks);
965
0
    }
966
0
  }
967
968
0
  return out;
969
0
}
970
971
972
int
973
sc_pkcs15_bind_internal(struct sc_pkcs15_card *p15card, struct sc_aid *aid)
974
12.3k
{
975
12.3k
  struct sc_path tmppath;
976
12.3k
  struct sc_card    *card = p15card->card;
977
12.3k
  struct sc_context *ctx  = card->ctx;
978
12.3k
  struct sc_pkcs15_tokeninfo tokeninfo;
979
12.3k
  struct sc_pkcs15_df *df;
980
12.3k
  const struct sc_app_info *info = NULL;
981
12.3k
  unsigned char *buf = NULL;
982
12.3k
  size_t len;
983
12.3k
  int    err, ok = 0;
984
985
12.3k
  LOG_FUNC_CALLED(ctx);
986
  /* Enumerate apps now */
987
12.3k
  if (card->app_count < 0) {
988
11.4k
    err = sc_enum_apps(card);
989
11.4k
    if (err != SC_SUCCESS)
990
11.1k
      sc_log(ctx, "unable to enumerate apps: %s", sc_strerror(err));
991
11.4k
  }
992
12.3k
  sc_file_free(p15card->file_app);
993
12.3k
  p15card->file_app = sc_file_new();
994
12.3k
  if (p15card->file_app == NULL) {
995
0
    err = SC_ERROR_OUT_OF_MEMORY;
996
0
    goto end;
997
0
  }
998
999
12.3k
  sc_format_path("3F005015", &p15card->file_app->path);
1000
1001
12.3k
  info = sc_find_app(card, aid);
1002
12.3k
  if (info)   {
1003
382
    sc_log(ctx, "bind to application('%s',aid:'%s')", info->label, sc_dump_hex(info->aid.value, info->aid.len));
1004
382
    sc_pkcs15_free_app(p15card);
1005
382
    p15card->app = sc_dup_app_info(info);
1006
382
    if (!p15card->app)   {
1007
0
      err = SC_ERROR_OUT_OF_MEMORY;
1008
0
      goto end;
1009
0
    }
1010
1011
382
    if (info->path.len)
1012
348
      p15card->file_app->path = info->path;
1013
1014
382
    if (info->ddo.value && info->ddo.len)
1015
36
      parse_ddo(p15card, info->ddo.value, info->ddo.len);
1016
1017
382
  }
1018
11.9k
  else if (aid)   {
1019
0
    sc_log(ctx, "Application '%s' not found", sc_dump_hex(aid->value, aid->len));
1020
0
    err = SC_ERROR_INVALID_ARGUMENTS;
1021
0
    goto end;
1022
0
  }
1023
12.3k
  sc_log(ctx, "application path '%s'", sc_print_path(&p15card->file_app->path));
1024
1025
  /* Check if pkcs15 directory exists */
1026
12.3k
  err = sc_select_file(card, &p15card->file_app->path, NULL);
1027
1028
  /* If the above test failed on cards without EF(DIR),
1029
   * try to continue read ODF from 3F005031. -aet
1030
   */
1031
12.3k
  if ((err != SC_SUCCESS) && (card->app_count < 1)) {
1032
10.2k
    sc_format_path("3F00", &p15card->file_app->path);
1033
10.2k
    err = SC_SUCCESS;
1034
10.2k
  }
1035
1036
12.3k
  if (err < 0)   {
1037
297
    sc_log (ctx, "Cannot select application path");
1038
297
    goto end;
1039
297
  }
1040
1041
12.0k
  if (p15card->file_odf == NULL) {
1042
    /* check if an ODF is present; we don't know yet whether we have a pkcs15 card */
1043
12.0k
    sc_format_path("5031", &tmppath);
1044
12.0k
    err = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &tmppath);
1045
12.0k
    if (err != SC_SUCCESS)   {
1046
3
      sc_log(ctx, "Cannot make absolute path to EF(ODF); error:%i", err);
1047
3
      goto end;
1048
3
    }
1049
12.0k
    sc_log(ctx, "absolute path to EF(ODF) %s", sc_print_path(&tmppath));
1050
12.0k
    err = sc_select_file(card, &tmppath, &p15card->file_odf);
1051
12.0k
  }
1052
4
  else {
1053
4
    tmppath = p15card->file_odf->path;
1054
4
    sc_file_free(p15card->file_odf);
1055
4
    p15card->file_odf = NULL;
1056
4
    err = sc_select_file(card, &tmppath, &p15card->file_odf);
1057
4
  }
1058
1059
12.0k
  if (err != SC_SUCCESS) {
1060
11.1k
    sc_log(ctx, "EF(ODF) not found in '%s'", sc_print_path(&tmppath));
1061
11.1k
    goto end;
1062
11.1k
  }
1063
1064
970
  len = p15card->file_odf->size;
1065
970
  if (!len) {
1066
125
    sc_log(ctx, "EF(ODF) is empty");
1067
125
    goto end;
1068
125
  }
1069
845
  if (len > MAX_FILE_SIZE) {
1070
21
    sc_log(ctx, "EF(ODF) too large");
1071
21
    goto end;
1072
21
  }
1073
824
  buf = malloc(len);
1074
824
  if(buf == NULL) {
1075
0
    err = SC_ERROR_OUT_OF_MEMORY;
1076
0
    goto end;
1077
0
  }
1078
1079
824
  err = -1; /* file state: not in cache */
1080
824
  if (p15card->opts.use_file_cache) {
1081
134
    err = sc_pkcs15_read_cached_file(p15card, &tmppath, &buf, &len);
1082
134
    if (err == SC_SUCCESS)
1083
1
      err = (int)len;
1084
134
  }
1085
824
  if (err < 0) {
1086
823
    err = sc_read_binary(card, 0, buf, len, 0);
1087
823
    if (err < 2) {
1088
400
      if (err < 0) {
1089
365
        sc_log(ctx, "read EF(ODF) file error: %s", sc_strerror(err));
1090
365
      } else {
1091
35
        err = SC_ERROR_PKCS15_APP_NOT_FOUND;
1092
35
        sc_log(ctx, "Invalid content of EF(ODF): %s", sc_strerror(err));
1093
35
      }
1094
400
      goto end;
1095
400
    }
1096
    /* sc_read_binary may return less than requested */
1097
423
    len = err;
1098
1099
423
    if (p15card->opts.use_file_cache) {
1100
69
      sc_pkcs15_cache_file(p15card, &tmppath, buf, len);
1101
69
    }
1102
423
  }
1103
1104
424
  if (parse_odf(buf, len, p15card)) {
1105
188
    err = SC_ERROR_PKCS15_APP_NOT_FOUND;
1106
188
    sc_log(ctx, "Unable to parse ODF");
1107
188
    goto end;
1108
188
  }
1109
236
  free(buf);
1110
236
  buf = NULL;
1111
1112
236
  sc_log(ctx, "The following DFs were found:");
1113
1.29k
  for (df = p15card->df_list; df; df = df->next)
1114
1.05k
    sc_log(ctx, "  DF type %u, path %s, index %u, count %d", df->type,
1115
236
        sc_print_path(&df->path), df->path.index, df->path.count);
1116
1117
236
  if (p15card->file_tokeninfo == NULL) {
1118
236
    sc_format_path("5032", &tmppath);
1119
236
    err = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &tmppath);
1120
236
    if (err != SC_SUCCESS)   {
1121
0
      sc_log(ctx, "Cannot make absolute path to EF(TokenInfo); error:%i", err);
1122
0
      goto end;
1123
0
    }
1124
236
    sc_log(ctx, "absolute path to EF(TokenInfo) %s", sc_print_path(&tmppath));
1125
236
  }
1126
0
  else {
1127
0
    tmppath = p15card->file_tokeninfo->path;
1128
0
    sc_file_free(p15card->file_tokeninfo);
1129
0
    p15card->file_tokeninfo = NULL;
1130
0
  }
1131
1132
236
  err = sc_select_file(card, &tmppath, &p15card->file_tokeninfo);
1133
236
  if (err)   {
1134
127
    sc_log(ctx, "cannot select EF(TokenInfo) file: %s", sc_strerror(err));
1135
127
    goto end;
1136
127
  }
1137
1138
109
  len = p15card->file_tokeninfo->size;
1139
109
  if (!len) {
1140
4
    sc_log(ctx, "EF(TokenInfo) is empty");
1141
4
    goto end;
1142
4
  }
1143
105
  if (len > MAX_FILE_SIZE) {
1144
19
    sc_log(ctx, "EF(TokenInfo) too large");
1145
19
    goto end;
1146
19
  }
1147
86
  buf = malloc(len);
1148
86
  if(buf == NULL) {
1149
0
    err = SC_ERROR_OUT_OF_MEMORY;
1150
0
    goto end;
1151
0
  }
1152
1153
86
  err = -1; /* file state: not in cache */
1154
86
  if (p15card->opts.use_file_cache) {
1155
24
    err = sc_pkcs15_read_cached_file(p15card, &tmppath, &buf, &len);
1156
24
    if (err == SC_SUCCESS)
1157
0
      err = (int)len;
1158
24
  }
1159
86
  if (err < 0) {
1160
86
    err = sc_read_binary(card, 0, buf, len, 0);
1161
86
    if (err <= 2) {
1162
42
      if (err < 0)   {
1163
33
        sc_log(ctx, "read EF(TokenInfo) file error: %s", sc_strerror(err));
1164
33
      } else {
1165
9
        err = SC_ERROR_PKCS15_APP_NOT_FOUND;
1166
9
        sc_log(ctx, "Invalid content of EF(TokenInfo): %s", sc_strerror(err));
1167
9
      }
1168
42
      goto end;
1169
42
    }
1170
    /* sc_read_binary may return less than requested */
1171
44
    len = err;
1172
1173
44
    if (p15card->opts.use_file_cache) {
1174
8
      sc_pkcs15_cache_file(p15card, &tmppath, buf, len);
1175
8
    }
1176
44
  }
1177
1178
44
  memset(&tokeninfo, 0, sizeof(tokeninfo));
1179
44
  err = sc_pkcs15_parse_tokeninfo(ctx, &tokeninfo, buf, (size_t)err);
1180
44
  if (err != SC_SUCCESS)   {
1181
29
    sc_log(ctx, "cannot parse TokenInfo content: %s", sc_strerror(err));
1182
29
    goto end;
1183
29
  }
1184
1185
15
  sc_pkcs15_clear_tokeninfo(p15card->tokeninfo);
1186
15
  *(p15card->tokeninfo) = tokeninfo;
1187
1188
15
  if (!p15card->tokeninfo->serial_number && 0 == card->serialnr.len) {
1189
13
    sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &card->serialnr);
1190
13
  }
1191
1192
15
  if (!p15card->tokeninfo->serial_number && card->serialnr.len)   {
1193
11
    char *serial = calloc(1, card->serialnr.len*2 + 1);
1194
11
    size_t ii;
1195
11
    if (!serial) {
1196
0
      err = SC_ERROR_OUT_OF_MEMORY;
1197
0
      goto end;
1198
0
    }
1199
1200
180
    for(ii=0;ii<card->serialnr.len;ii++)
1201
169
      sprintf(serial + ii*2, "%02X", *(card->serialnr.value + ii));
1202
1203
11
    p15card->tokeninfo->serial_number = serial;
1204
11
    sc_log(ctx, "p15card->tokeninfo->serial_number %s", p15card->tokeninfo->serial_number);
1205
11
  }
1206
1207
15
  ok = 1;
1208
12.3k
end:
1209
12.3k
  if(buf != NULL)
1210
674
    free(buf);
1211
12.3k
  if (!ok) {
1212
12.3k
    sc_pkcs15_card_clear(p15card);
1213
12.3k
    if (err == SC_ERROR_FILE_NOT_FOUND)
1214
1.43k
      err = SC_ERROR_WRONG_CARD;
1215
12.3k
    LOG_FUNC_RETURN(ctx, err);
1216
12.3k
  }
1217
1218
15
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1219
15
}
1220
1221
1222
const char *pkcs15_get_default_use_file_cache(struct sc_card *card)
1223
12.6k
{
1224
  /* enable file caching by default for cards with static content to avoid
1225
   * synchronization problems.
1226
   *
1227
   * The following list was initialized with the cards that can't be modified
1228
   * with OpenSC i.e. which don't have a profile/driver for pkcs15-init. */
1229
12.6k
  const char *card_drivers_with_file_cache[] = {
1230
12.6k
      "atrust-acos",
1231
12.6k
      "belpic",
1232
12.6k
      "cac1",
1233
12.6k
      "cac",
1234
12.6k
      "coolkey",
1235
12.6k
      "edo",
1236
12.6k
      "esteid2018",
1237
12.6k
      "esteid2025",
1238
12.6k
      "flex",
1239
12.6k
      "cyberflex",
1240
12.6k
      "gemsafeV1",
1241
12.6k
      "idprime",
1242
12.6k
      "itacns",
1243
12.6k
      "jpki",
1244
12.6k
      "MaskTech",
1245
12.6k
      "mcrd",
1246
12.6k
      "myeid",
1247
12.6k
      "npa",
1248
12.6k
      "nqapplet",
1249
12.6k
      "tcos",
1250
12.6k
      "dtrust",
1251
12.6k
  };
1252
1253
12.6k
  if (NULL == card || NULL == card->driver || NULL == card->driver->short_name)
1254
0
    return "no";
1255
227k
  for (size_t i = 0; i < (sizeof card_drivers_with_file_cache / sizeof *card_drivers_with_file_cache); i++) {
1256
219k
    if (0 == strcmp(card->driver->short_name, card_drivers_with_file_cache[i]))
1257
4.93k
      return "public";
1258
219k
  }
1259
1260
7.75k
  return "no";
1261
12.6k
}
1262
1263
int
1264
sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid,
1265
    struct sc_pkcs15_card **p15card_out)
1266
12.6k
{
1267
12.6k
  struct sc_pkcs15_card *p15card = NULL;
1268
12.6k
  struct sc_context *ctx;
1269
12.6k
  scconf_block *conf_block = NULL;
1270
12.6k
  int r, emu_first, enable_emu;
1271
12.6k
  const char *use_file_cache;
1272
12.6k
  const char *pin_protected_certificate, *private_certificate;
1273
1274
12.6k
  if (card == NULL || p15card_out == NULL) {
1275
0
    return SC_ERROR_INVALID_ARGUMENTS;
1276
0
  }
1277
12.6k
  ctx = card->ctx;
1278
1279
12.6k
  LOG_FUNC_CALLED(ctx);
1280
12.6k
  sc_log(ctx, "application(aid:'%s')", aid ? sc_dump_hex(aid->value, aid->len) : "empty");
1281
1282
12.6k
  p15card = sc_pkcs15_card_new();
1283
12.6k
  if (p15card == NULL)
1284
12.6k
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1285
1286
12.6k
  p15card->card = card;
1287
12.6k
  p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_NO_FILES;
1288
12.6k
  use_file_cache = pkcs15_get_default_use_file_cache(card);
1289
12.6k
  p15card->opts.use_pin_cache = 1;
1290
12.6k
  p15card->opts.pin_cache_counter = 10;
1291
12.6k
  p15card->opts.pin_cache_ignore_user_consent = 0;
1292
12.6k
  pin_protected_certificate = "protect";
1293
12.6k
  private_certificate = "";
1294
1295
12.6k
  conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);
1296
12.6k
  if (conf_block) {
1297
0
    use_file_cache = scconf_get_str(conf_block, "use_file_caching", use_file_cache);
1298
0
    p15card->opts.use_pin_cache = scconf_get_bool(conf_block, "use_pin_caching", p15card->opts.use_pin_cache);
1299
0
    p15card->opts.pin_cache_counter = scconf_get_int(conf_block, "pin_cache_counter", p15card->opts.pin_cache_counter);
1300
0
    p15card->opts.pin_cache_ignore_user_consent = scconf_get_bool(conf_block, "pin_cache_ignore_user_consent",
1301
0
        p15card->opts.pin_cache_ignore_user_consent);
1302
0
    pin_protected_certificate = scconf_get_str(conf_block, "pin_protected_certificate", pin_protected_certificate);
1303
    /* read also the old value to keep backward compatibility */
1304
0
    private_certificate = scconf_get_str(conf_block, "private_certificate", private_certificate);
1305
0
  }
1306
1307
12.6k
  if (0 == strcmp(use_file_cache, "yes")) {
1308
0
    p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_ALL_FILES;
1309
12.6k
  } else if (0 == strcmp(use_file_cache, "public")) {
1310
4.93k
    p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_PUBLIC_FILES;
1311
7.75k
  } else if (0 == strcmp(use_file_cache, "no")) {
1312
7.75k
    p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_NO_FILES;
1313
7.75k
  }
1314
1315
12.6k
  if (0 == strcmp(pin_protected_certificate, "protect")) {
1316
12.6k
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT;
1317
12.6k
  } else if (0 == strcmp(pin_protected_certificate, "ignore")) {
1318
0
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE;
1319
0
  } else if (0 == strcmp(pin_protected_certificate, "declassify")) {
1320
0
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY;
1321
0
  }
1322
  /* overwrite pin_protected_certificate when private_certificate set */
1323
12.6k
  if (0 == strcmp(private_certificate, "protect")) {
1324
0
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT;
1325
12.6k
  } else if (0 == strcmp(private_certificate, "ignore")) {
1326
0
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE;
1327
12.6k
  } else if (0 == strcmp(private_certificate, "declassify")) {
1328
0
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY;
1329
0
  }
1330
12.6k
  sc_log(ctx, "PKCS#15 options: use_file_cache=%d use_pin_cache=%d pin_cache_counter=%d pin_cache_ignore_user_consent=%d pin_protected_certificate=%d",
1331
12.6k
      p15card->opts.use_file_cache, p15card->opts.use_pin_cache, p15card->opts.pin_cache_counter,
1332
12.6k
      p15card->opts.pin_cache_ignore_user_consent, p15card->opts.pin_protected_certificate);
1333
1334
12.6k
  r = sc_lock(card);
1335
12.6k
  if (r) {
1336
0
    sc_log(ctx, "sc_lock() failed: %s", sc_strerror(r));
1337
0
    sc_pkcs15_card_free(p15card);
1338
0
    LOG_FUNC_RETURN(ctx, r);
1339
0
  }
1340
1341
12.6k
  enable_emu = scconf_get_bool(conf_block, "enable_pkcs15_emulation", 1);
1342
12.6k
  if (enable_emu) {
1343
12.6k
    sc_log(ctx, "PKCS#15 emulation enabled");
1344
12.6k
    emu_first = scconf_get_bool(conf_block, "try_emulation_first", 0);
1345
12.6k
    if (emu_first || sc_pkcs15_is_emulation_only(card)) {
1346
2.85k
      r = sc_pkcs15_bind_synthetic(p15card, aid);
1347
2.85k
      if (r == SC_SUCCESS)
1348
1.30k
        goto done;
1349
1.55k
      r = sc_pkcs15_bind_internal(p15card, aid);
1350
1.55k
      if (r < 0)
1351
1.54k
        goto error;
1352
9.83k
    } else {
1353
9.83k
      r = sc_pkcs15_bind_internal(p15card, aid);
1354
9.83k
      if (r == SC_SUCCESS)
1355
153
        goto done;
1356
9.68k
      r = sc_pkcs15_bind_synthetic(p15card, aid);
1357
9.68k
      if (r < 0)
1358
5.21k
        goto error;
1359
9.68k
    }
1360
12.6k
  }
1361
0
  else {
1362
0
    r = sc_pkcs15_bind_internal(p15card, aid);
1363
0
    if (r < 0)
1364
0
      goto error;
1365
0
  }
1366
5.93k
done:
1367
5.93k
  *p15card_out = p15card;
1368
5.93k
  sc_unlock(card);
1369
5.93k
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1370
6.75k
error:
1371
6.75k
  sc_unlock(card);
1372
6.75k
  sc_pkcs15_card_free(p15card);
1373
6.75k
  LOG_FUNC_RETURN(ctx, r);
1374
6.75k
}
1375
1376
1377
int
1378
sc_pkcs15_unbind(struct sc_pkcs15_card *p15card)
1379
0
{
1380
0
  if (p15card == NULL || p15card->magic != SC_PKCS15_CARD_MAGIC) {
1381
0
    return SC_ERROR_INVALID_ARGUMENTS;
1382
0
  }
1383
1384
0
  LOG_FUNC_CALLED(p15card->card->ctx);
1385
0
  if (p15card->dll_handle)
1386
0
    sc_dlclose(p15card->dll_handle);
1387
0
  sc_pkcs15_pincache_clear(p15card);
1388
0
  sc_pkcs15_card_free(p15card);
1389
0
  return 0;
1390
0
}
1391
1392
1393
static int
1394
__sc_pkcs15_search_objects(struct sc_pkcs15_card *p15card, unsigned int class_mask, unsigned int type,
1395
      int (*func)(sc_pkcs15_object_t *, void *), void *func_arg,
1396
      sc_pkcs15_object_t **ret, size_t ret_size)
1397
1.98k
{
1398
1.98k
  struct sc_pkcs15_object *obj = NULL;
1399
1.98k
  struct sc_pkcs15_df *df = NULL;
1400
1.98k
  unsigned int  df_mask = 0;
1401
1.98k
  size_t    match_count = 0;
1402
1.98k
  int r;
1403
1404
1.98k
  if (type)
1405
1.98k
    class_mask |= SC_PKCS15_TYPE_TO_CLASS(type);
1406
1407
  /* Make sure the class mask we have makes sense */
1408
1.98k
  if (class_mask == 0
1409
1.98k
      || (class_mask & ~(
1410
1.98k
          SC_PKCS15_SEARCH_CLASS_PRKEY |
1411
1.98k
          SC_PKCS15_SEARCH_CLASS_PUBKEY |
1412
1.98k
          SC_PKCS15_SEARCH_CLASS_SKEY |
1413
1.98k
          SC_PKCS15_SEARCH_CLASS_CERT |
1414
1.98k
          SC_PKCS15_SEARCH_CLASS_DATA |
1415
1.98k
          SC_PKCS15_SEARCH_CLASS_AUTH))) {
1416
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1417
0
  }
1418
1419
1.98k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_PRKEY)
1420
0
    df_mask |= (1 << SC_PKCS15_PRKDF);
1421
1.98k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_PUBKEY)
1422
0
    df_mask |= (1 << SC_PKCS15_PUKDF) | (1 << SC_PKCS15_PUKDF_TRUSTED);
1423
1.98k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_CERT)
1424
1.12k
    df_mask |= (1 << SC_PKCS15_CDF) | (1 << SC_PKCS15_CDF_TRUSTED) | (1 << SC_PKCS15_CDF_USEFUL);
1425
1.98k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_DATA)
1426
177
    df_mask |= (1 << SC_PKCS15_DODF);
1427
1.98k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_AUTH)
1428
681
    df_mask |= (1 << SC_PKCS15_AODF);
1429
1.98k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_SKEY)
1430
0
    df_mask |= (1 << SC_PKCS15_SKDF);
1431
1432
  /* Make sure all the DFs we want to search have been
1433
   * enumerated. */
1434
7.14k
  for (df = p15card->df_list; df != NULL; df = df->next) {
1435
5.16k
    if (!(df_mask & (1 << df->type)))   {
1436
3.76k
      continue;
1437
3.76k
    }
1438
1.39k
    if (df->enumerated)
1439
1.39k
      continue;
1440
    /* Enumerate the DF's, so p15card->obj_list is populated. */
1441
0
    if (p15card->ops.parse_df)
1442
0
      r = p15card->ops.parse_df(p15card, df);
1443
0
    else
1444
0
      r = sc_pkcs15_parse_df(p15card, df);
1445
0
    if (r != SC_SUCCESS)
1446
0
      continue;
1447
0
  }
1448
1449
  /* And now loop over all objects */
1450
15.8k
  for (obj = p15card->obj_list; obj != NULL; obj = obj->next) {
1451
    /* Check object type */
1452
14.7k
    if (!(class_mask & SC_PKCS15_TYPE_TO_CLASS(obj->type)))
1453
10.9k
      continue;
1454
3.83k
    if (type != 0
1455
3.83k
     && obj->type != type
1456
3.83k
     && (obj->type & SC_PKCS15_TYPE_CLASS_MASK) != type)
1457
0
      continue;
1458
1459
    /* Potential candidate, apply search function */
1460
3.83k
    if (func != NULL && func(obj, func_arg) <= 0)
1461
806
      continue;
1462
    /* Okay, we have a match. */
1463
3.03k
    match_count++;
1464
3.03k
    if (!ret || ret_size <= 0)
1465
0
      continue;
1466
3.03k
    ret[match_count-1] = obj;
1467
3.03k
    if (ret_size <= match_count)
1468
948
      break;
1469
3.03k
  }
1470
1471
1.98k
  return (int)match_count;
1472
1.98k
}
1473
1474
1475
int
1476
sc_pkcs15_get_objects(struct sc_pkcs15_card *p15card, unsigned int type,
1477
    struct sc_pkcs15_object **ret, size_t ret_size)
1478
194
{
1479
194
  return sc_pkcs15_get_objects_cond(p15card, type, NULL, NULL, ret, ret_size);
1480
194
}
1481
1482
1483
static int
1484
compare_obj_id(struct sc_pkcs15_object *obj, const struct sc_pkcs15_id *id)
1485
1.75k
{
1486
1.75k
  void *data = obj->data;
1487
1488
1.75k
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
1489
826
  case SC_PKCS15_TYPE_CERT:
1490
826
    return sc_pkcs15_compare_id(&((struct sc_pkcs15_cert_info *) data)->id, id);
1491
0
  case SC_PKCS15_TYPE_PRKEY:
1492
0
    return sc_pkcs15_compare_id(&((struct sc_pkcs15_prkey_info *) data)->id, id);
1493
0
  case SC_PKCS15_TYPE_PUBKEY:
1494
0
    return sc_pkcs15_compare_id(&((struct sc_pkcs15_pubkey_info *) data)->id, id);
1495
0
  case SC_PKCS15_TYPE_SKEY:
1496
0
    return sc_pkcs15_compare_id(&((struct sc_pkcs15_skey_info *) data)->id, id);
1497
928
  case SC_PKCS15_TYPE_AUTH:
1498
928
    return sc_pkcs15_compare_id(&((struct sc_pkcs15_auth_info *) data)->auth_id, id);
1499
0
  case SC_PKCS15_TYPE_DATA_OBJECT:
1500
0
    return sc_pkcs15_compare_id(&((struct sc_pkcs15_data_info *) data)->id, id);
1501
1.75k
  }
1502
0
  return 0;
1503
1.75k
}
1504
1505
1506
static int
1507
sc_obj_app_oid(struct sc_pkcs15_object *obj, const struct sc_object_id *app_oid)
1508
0
{
1509
0
  if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_DATA_OBJECT)
1510
0
    return sc_compare_oid(&((struct sc_pkcs15_data_info *) obj->data)->app_oid, app_oid);
1511
0
  return 0;
1512
0
}
1513
1514
1515
static int
1516
compare_obj_usage(struct sc_pkcs15_object *obj, unsigned int mask, unsigned int value)
1517
0
{
1518
0
  void    *data = obj->data;
1519
0
  unsigned int  usage;
1520
1521
0
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
1522
0
  case SC_PKCS15_TYPE_PRKEY:
1523
0
    usage = ((struct sc_pkcs15_prkey_info *) data)->usage;
1524
0
    break;
1525
0
  case SC_PKCS15_TYPE_PUBKEY:
1526
0
    usage = ((struct sc_pkcs15_pubkey_info *) data)->usage;
1527
0
    break;
1528
0
  default:
1529
0
    return 0;
1530
0
  }
1531
0
  return (usage & mask & value) != 0;
1532
0
}
1533
1534
1535
static int
1536
compare_obj_flags(struct sc_pkcs15_object *obj, unsigned int mask, unsigned int value)
1537
0
{
1538
0
  struct sc_pkcs15_auth_info *auth_info;
1539
0
  unsigned int  flags;
1540
1541
0
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
1542
0
  case SC_PKCS15_TYPE_AUTH:
1543
0
    auth_info = (struct sc_pkcs15_auth_info *) obj->data;
1544
0
    if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1545
0
      return 0;
1546
0
    flags = auth_info->attrs.pin.flags;
1547
0
    break;
1548
0
  default:
1549
0
    return 0;
1550
0
  }
1551
0
  return !((flags ^ value) & mask);
1552
0
}
1553
1554
1555
static int
1556
compare_obj_reference(struct sc_pkcs15_object *obj, int value)
1557
0
{
1558
0
  struct sc_pkcs15_auth_info *auth_info;
1559
0
  void    *data = obj->data;
1560
0
  int   reference;
1561
1562
0
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
1563
0
  case SC_PKCS15_TYPE_AUTH:
1564
0
    auth_info = (struct sc_pkcs15_auth_info *) obj->data;
1565
0
    if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1566
0
      return 0;
1567
0
    reference = auth_info->attrs.pin.reference;
1568
0
    break;
1569
0
  case SC_PKCS15_TYPE_PRKEY:
1570
0
    reference = ((struct sc_pkcs15_prkey_info *) data)->key_reference;
1571
0
    break;
1572
0
  default:
1573
0
    return 0;
1574
0
  }
1575
0
  return reference == value;
1576
0
}
1577
1578
1579
static int
1580
compare_obj_path(struct sc_pkcs15_object *obj, const struct sc_path *path)
1581
0
{
1582
0
  void *data = obj->data;
1583
1584
0
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
1585
0
  case SC_PKCS15_TYPE_PRKEY:
1586
0
    return sc_compare_path(&((struct sc_pkcs15_prkey_info *) data)->path, path);
1587
0
  case SC_PKCS15_TYPE_PUBKEY:
1588
0
    return sc_compare_path(&((struct sc_pkcs15_pubkey_info *) data)->path, path);
1589
0
  case SC_PKCS15_TYPE_SKEY:
1590
0
    return sc_compare_path(&((struct sc_pkcs15_skey_info *) data)->path, path);
1591
0
  case SC_PKCS15_TYPE_CERT:
1592
0
    return sc_compare_path(&((struct sc_pkcs15_cert_info *) data)->path, path);
1593
0
  case SC_PKCS15_TYPE_AUTH:
1594
0
    return sc_compare_path(&((struct sc_pkcs15_auth_info *) data)->path, path);
1595
0
  case SC_PKCS15_TYPE_DATA_OBJECT:
1596
0
    return sc_compare_path(&((struct sc_pkcs15_data_info *) data)->path, path);
1597
0
  }
1598
0
  return 0;
1599
0
}
1600
1601
1602
static int
1603
compare_obj_data_name(struct sc_pkcs15_object *obj, const char *app_label, const char *label)
1604
0
{
1605
0
  struct sc_pkcs15_data_info *cinfo = (struct sc_pkcs15_data_info *) obj->data;
1606
1607
0
  if (obj->type != SC_PKCS15_TYPE_DATA_OBJECT)
1608
0
    return 0;
1609
1610
0
  return !strncmp(cinfo->app_label, app_label, sizeof cinfo->app_label) &&
1611
0
    !strncmp(obj->label, label, sizeof obj->label);
1612
0
}
1613
1614
1615
static int
1616
compare_obj_key(struct sc_pkcs15_object *obj, void *arg)
1617
1.75k
{
1618
1.75k
  struct sc_pkcs15_search_key *sk = (struct sc_pkcs15_search_key *) arg;
1619
1620
1.75k
  if (sk->id && !compare_obj_id(obj, sk->id))
1621
806
    return 0;
1622
948
  if (sk->app_oid && !sc_obj_app_oid(obj, sk->app_oid))
1623
0
    return 0;
1624
948
  if (sk->usage_mask && !compare_obj_usage(obj, sk->usage_mask, sk->usage_value))
1625
0
    return 0;
1626
948
  if (sk->flags_mask && !compare_obj_flags(obj, sk->flags_mask, sk->flags_value))
1627
0
    return 0;
1628
948
  if (sk->match_reference && !compare_obj_reference(obj, sk->reference))
1629
0
    return 0;
1630
948
  if (sk->path && !compare_obj_path(obj, sk->path))
1631
0
    return 0;
1632
948
  if (
1633
948
    sk->app_label && sk->label &&
1634
948
    !compare_obj_data_name(obj, sk->app_label, sk->label)
1635
948
  ) {
1636
0
    return 0;
1637
0
  }
1638
1639
948
  return 1;
1640
948
}
1641
1642
1643
static int
1644
find_by_key(struct sc_pkcs15_card *p15card, unsigned int type, struct sc_pkcs15_search_key *sk,
1645
    struct sc_pkcs15_object **out)
1646
0
{
1647
0
  int r;
1648
1649
0
  r = sc_pkcs15_get_objects_cond(p15card, type, compare_obj_key, sk, out, 1);
1650
0
  if (r < 0)
1651
0
    return r;
1652
0
  if (r == 0)
1653
0
    return SC_ERROR_OBJECT_NOT_FOUND;
1654
0
  return 0;
1655
0
}
1656
1657
1658
int
1659
sc_pkcs15_search_objects(struct sc_pkcs15_card *p15card, struct sc_pkcs15_search_key *sk,
1660
      struct sc_pkcs15_object **ret, size_t ret_size)
1661
0
{
1662
0
  return __sc_pkcs15_search_objects(p15card,
1663
0
      sk->class_mask, sk->type,
1664
0
      compare_obj_key, sk,
1665
0
      ret, ret_size);
1666
0
}
1667
1668
1669
int
1670
sc_pkcs15_get_objects_cond(struct sc_pkcs15_card *p15card, unsigned int type,
1671
    int (* func)(struct sc_pkcs15_object *, void *),
1672
    void *func_arg, struct sc_pkcs15_object **ret, size_t ret_size)
1673
194
{
1674
194
  return __sc_pkcs15_search_objects(p15card, 0, type,
1675
194
      func, func_arg, ret, ret_size);
1676
194
}
1677
1678
1679
int sc_pkcs15_find_object_by_id(struct sc_pkcs15_card *p15card,
1680
        unsigned int type, const struct sc_pkcs15_id *id,
1681
        struct sc_pkcs15_object **out)
1682
1.78k
{
1683
1.78k
  struct sc_pkcs15_search_key sk;
1684
1.78k
  int r;
1685
1686
1.78k
  memset(&sk, 0, sizeof(sk));
1687
1.78k
  sk.id = id;
1688
1689
1.78k
  r = __sc_pkcs15_search_objects(p15card, 0, type, compare_obj_key, &sk, out, 1);
1690
1.78k
  if (r < 0)
1691
0
    return r;
1692
1.78k
  if (r == 0)
1693
838
    return SC_ERROR_OBJECT_NOT_FOUND;
1694
948
  return 0;
1695
1.78k
}
1696
1697
1698
int
1699
sc_pkcs15_find_cert_by_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
1700
    struct sc_pkcs15_object **out)
1701
1.10k
{
1702
1.10k
  return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_CERT, id, out);
1703
1.10k
}
1704
1705
1706
int
1707
sc_pkcs15_find_prkey_by_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
1708
    struct sc_pkcs15_object **out)
1709
0
{
1710
0
  return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_PRKEY, id, out);
1711
0
}
1712
1713
1714
int
1715
sc_pkcs15_find_pubkey_by_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
1716
    struct sc_pkcs15_object **out)
1717
0
{
1718
0
  return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_PUBKEY, id, out);
1719
0
}
1720
1721
1722
int
1723
sc_pkcs15_find_skey_by_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
1724
    struct sc_pkcs15_object **out)
1725
0
{
1726
0
  return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_SKEY, id, out);
1727
0
}
1728
1729
1730
int
1731
sc_pkcs15_find_pin_by_auth_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
1732
    struct sc_pkcs15_object **out)
1733
678
{
1734
678
  return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_AUTH, id, out);
1735
678
}
1736
1737
1738
int
1739
sc_pkcs15_find_pin_by_reference(struct sc_pkcs15_card *p15card, const sc_path_t *path, int reference,
1740
    struct sc_pkcs15_object **out)
1741
0
{
1742
0
  struct sc_pkcs15_search_key sk;
1743
1744
0
  memset(&sk, 0, sizeof(sk));
1745
0
  sk.match_reference = 1;
1746
0
  sk.reference = reference;
1747
0
  sk.path = path;
1748
1749
0
  return find_by_key(p15card, SC_PKCS15_TYPE_AUTH_PIN, &sk, out);
1750
0
}
1751
1752
1753
int
1754
sc_pkcs15_find_pin_by_type_and_reference(struct sc_pkcs15_card *p15card, const struct sc_path *path,
1755
        unsigned auth_method, int reference,
1756
        struct sc_pkcs15_object **out)
1757
0
{
1758
0
  struct sc_context *ctx = p15card->card->ctx;
1759
0
  struct sc_pkcs15_object *auth_objs[0x10];
1760
0
  size_t nn_objs, ii;
1761
0
  int r;
1762
1763
  /* Get all existing pkcs15 AUTH objects */
1764
0
  r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, auth_objs, 0x10);
1765
0
  LOG_TEST_RET(ctx, r, "Get PKCS#15 AUTH objects error");
1766
0
  nn_objs = r;
1767
1768
0
  for (ii=0; ii<nn_objs; ii++)   {
1769
0
    struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *)auth_objs[ii]->data;
1770
1771
0
    if (auth_info->auth_method != auth_method)
1772
0
      continue;
1773
0
    if (auth_info->auth_type == SC_PKCS15_PIN_AUTH_TYPE_PIN)
1774
0
      if (auth_info->attrs.pin.reference != reference)
1775
0
        continue;
1776
1777
0
    if (path && !sc_compare_path(&auth_info->path, path))
1778
0
      continue;
1779
1780
0
    if (out)
1781
0
      *out = auth_objs[ii];
1782
1783
0
    return SC_SUCCESS;
1784
0
  }
1785
1786
0
  return SC_ERROR_OBJECT_NOT_FOUND;
1787
0
}
1788
1789
1790
int
1791
sc_pkcs15_find_so_pin(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object **out)
1792
0
{
1793
0
  struct sc_pkcs15_search_key sk;
1794
1795
0
  memset(&sk, 0, sizeof(sk));
1796
0
  sk.flags_mask = sk.flags_value = SC_PKCS15_PIN_FLAG_SO_PIN;
1797
1798
0
  return find_by_key(p15card, SC_PKCS15_TYPE_AUTH_PIN, &sk, out);
1799
0
}
1800
1801
1802
int
1803
sc_pkcs15_find_pin_by_flags(struct sc_pkcs15_card *p15card,
1804
    unsigned flags, unsigned mask, int *index,
1805
    struct sc_pkcs15_object **out)
1806
0
{
1807
0
  struct sc_context *ctx = p15card->card->ctx;
1808
0
  struct sc_pkcs15_object *auths[SC_PKCS15_MAX_PINS];
1809
0
  int r, i, num, idx = 0;
1810
1811
0
  LOG_FUNC_CALLED(ctx);
1812
0
  sc_log(ctx, "Find PIN flags:0x%X, mask:0x%X, index:%i", flags, mask, index ? *index : -1);
1813
0
  if (index)
1814
0
    idx = *index;
1815
  /* Get authentication PKCS#15 objects that are present in the given application */
1816
0
  r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, auths, SC_PKCS15_MAX_PINS);
1817
0
  if (r < 0)
1818
0
    return r;
1819
0
  num = r;
1820
1821
0
  for (i=idx; i<num; i++)   {
1822
0
    struct sc_pkcs15_auth_info *pin_info = (struct sc_pkcs15_auth_info *)(*(auths + i))->data;
1823
1824
0
    if (!pin_info || pin_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1825
0
      continue;
1826
1827
0
    if ((pin_info->attrs.pin.flags & mask) != flags)
1828
0
      continue;
1829
1830
0
    if (out)
1831
0
      *out = *(auths + i);
1832
0
    if (index)
1833
0
      *index = i;
1834
1835
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1836
0
  }
1837
1838
0
  LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_FOUND);
1839
0
}
1840
1841
1842
int
1843
sc_pkcs15_find_data_object_by_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
1844
    struct sc_pkcs15_object **out)
1845
0
{
1846
0
  return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_DATA_OBJECT, id, out);
1847
0
}
1848
1849
1850
int
1851
sc_pkcs15_find_data_object_by_app_oid(struct sc_pkcs15_card *p15card, const struct sc_object_id *app_oid,
1852
    struct sc_pkcs15_object **out)
1853
0
{
1854
0
  struct sc_pkcs15_search_key sk;
1855
0
  int r;
1856
1857
0
  memset(&sk, 0, sizeof(sk));
1858
0
  sk.app_oid = app_oid;
1859
1860
0
  r = __sc_pkcs15_search_objects(p15card, 0, SC_PKCS15_TYPE_DATA_OBJECT,
1861
0
        compare_obj_key, &sk,
1862
0
        out, 1);
1863
0
  if (r < 0)
1864
0
    return r;
1865
0
  if (r == 0)
1866
0
    return SC_ERROR_OBJECT_NOT_FOUND;
1867
0
  return 0;
1868
0
}
1869
1870
1871
int
1872
sc_pkcs15_find_data_object_by_name(struct sc_pkcs15_card *p15card, const char *app_label, const char *label,
1873
    struct sc_pkcs15_object **out)
1874
0
{
1875
0
  struct sc_pkcs15_search_key sk;
1876
0
  int r;
1877
1878
0
  memset(&sk, 0, sizeof(sk));
1879
0
  sk.app_label = app_label;
1880
0
  sk.label = label;
1881
1882
0
  r = __sc_pkcs15_search_objects(p15card, 0, SC_PKCS15_TYPE_DATA_OBJECT,
1883
0
        compare_obj_key, &sk,
1884
0
        out, 1);
1885
0
  if (r < 0)
1886
0
    return r;
1887
0
  if (r == 0)
1888
0
    return SC_ERROR_OBJECT_NOT_FOUND;
1889
0
  return 0;
1890
0
}
1891
1892
1893
int
1894
sc_pkcs15_find_prkey_by_id_usage(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
1895
    unsigned int usage, struct sc_pkcs15_object **out)
1896
0
{
1897
0
  struct sc_pkcs15_search_key sk;
1898
1899
0
  memset(&sk, 0, sizeof(sk));
1900
0
  sk.usage_mask = sk.usage_value = usage;
1901
0
  sk.id = id;
1902
1903
0
  return find_by_key(p15card, SC_PKCS15_TYPE_PRKEY, &sk, out);
1904
0
}
1905
1906
1907
int
1908
sc_pkcs15_find_prkey_by_reference(struct sc_pkcs15_card *p15card, const struct sc_path *path,
1909
        int reference,
1910
        struct sc_pkcs15_object **out)
1911
0
{
1912
0
  struct sc_pkcs15_search_key sk;
1913
1914
0
  memset(&sk, 0, sizeof(sk));
1915
0
  sk.match_reference = 1;
1916
0
  sk.reference = reference;
1917
0
  sk.path = path;
1918
1919
0
  return find_by_key(p15card, SC_PKCS15_TYPE_PRKEY, &sk, out);
1920
0
}
1921
1922
1923
int
1924
sc_pkcs15_add_object(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj)
1925
40.5k
{
1926
40.5k
  struct sc_pkcs15_object *p = p15card->obj_list;
1927
1928
40.5k
  if (!obj)
1929
0
    return 0;
1930
40.5k
  obj->next = obj->prev = NULL;
1931
40.5k
  if (p15card->obj_list == NULL) {
1932
5.48k
    p15card->obj_list = obj;
1933
5.48k
    return 0;
1934
5.48k
  }
1935
555k
  while (p->next != NULL)
1936
520k
    p = p->next;
1937
35.0k
  p->next = obj;
1938
35.0k
  obj->prev = p;
1939
1940
35.0k
  return 0;
1941
40.5k
}
1942
1943
1944
void
1945
sc_pkcs15_remove_object(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj)
1946
0
{
1947
0
  if (!obj)
1948
0
    return;
1949
0
  else if (obj->prev == NULL)
1950
0
    p15card->obj_list = obj->next;
1951
0
  else
1952
0
    obj->prev->next = obj->next;
1953
0
  if (obj->next != NULL)
1954
0
    obj->next->prev = obj->prev;
1955
0
}
1956
1957
1958
static void
1959
sc_pkcs15_remove_objects(struct sc_pkcs15_card *p15card)
1960
28.1k
{
1961
28.1k
  struct sc_pkcs15_object *cur = NULL, *next = NULL;
1962
1963
28.1k
  if (!p15card || !p15card->obj_list)
1964
22.6k
    return;
1965
45.9k
  for (cur = p15card->obj_list; cur; cur = next)   {
1966
40.5k
    next = cur->next;
1967
40.5k
    sc_pkcs15_free_object(cur);
1968
40.5k
  }
1969
1970
5.48k
  p15card->obj_list = NULL;
1971
5.48k
}
1972
1973
1974
void
1975
sc_pkcs15_free_object(struct sc_pkcs15_object *obj)
1976
40.5k
{
1977
40.5k
  if (!obj)
1978
0
    return;
1979
40.5k
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
1980
4.47k
  case SC_PKCS15_TYPE_PRKEY:
1981
4.47k
    sc_pkcs15_free_prkey_info((sc_pkcs15_prkey_info_t *)obj->data);
1982
4.47k
    break;
1983
1.59k
  case SC_PKCS15_TYPE_PUBKEY:
1984
    /* This is normally passed to framework-pkcs15,
1985
     * but if something fails on the way, it would not get freed */
1986
1.59k
    if (obj->emulated) {
1987
1.50k
      sc_pkcs15_free_pubkey(obj->emulated);
1988
1.50k
    }
1989
1.59k
    sc_pkcs15_free_pubkey_info((sc_pkcs15_pubkey_info_t *)obj->data);
1990
1.59k
    break;
1991
3.35k
  case SC_PKCS15_TYPE_CERT:
1992
3.35k
    sc_pkcs15_free_cert_info((sc_pkcs15_cert_info_t *)obj->data);
1993
3.35k
    break;
1994
0
  case SC_PKCS15_TYPE_SKEY:
1995
0
    sc_pkcs15_free_skey_info((sc_pkcs15_skey_info_t *)obj->data);
1996
0
    break;
1997
24.1k
  case SC_PKCS15_TYPE_DATA_OBJECT:
1998
24.1k
    sc_pkcs15_free_data_info((sc_pkcs15_data_info_t *)obj->data);
1999
24.1k
    break;
2000
6.90k
  case SC_PKCS15_TYPE_AUTH:
2001
6.90k
    sc_pkcs15_free_auth_info((sc_pkcs15_auth_info_t *)obj->data);
2002
6.90k
    break;
2003
0
  default:
2004
0
    free(obj->data);
2005
40.5k
  }
2006
2007
40.5k
  sc_pkcs15_free_object_content(obj);
2008
2009
40.5k
  free(obj);
2010
40.5k
}
2011
2012
2013
int
2014
sc_pkcs15_add_df(struct sc_pkcs15_card *p15card, unsigned int type, const sc_path_t *path)
2015
16.8k
{
2016
16.8k
  struct sc_pkcs15_df *p, *newdf;
2017
2018
16.8k
  newdf = calloc(1, sizeof(struct sc_pkcs15_df));
2019
16.8k
  if (newdf == NULL)
2020
0
    return SC_ERROR_OUT_OF_MEMORY;
2021
16.8k
  newdf->path = *path;
2022
16.8k
  newdf->type = type;
2023
2024
16.8k
  if (p15card->df_list == NULL) {
2025
5.63k
    p15card->df_list = newdf;
2026
5.63k
    return 0;
2027
5.63k
  }
2028
2029
11.1k
  p = p15card->df_list;
2030
487k
  while (p->next != NULL)
2031
476k
    p = p->next;
2032
11.1k
  p->next = newdf;
2033
11.1k
  newdf->prev = p;
2034
2035
11.1k
  return 0;
2036
16.8k
}
2037
2038
2039
static void
2040
sc_pkcs15_remove_dfs(struct sc_pkcs15_card *p15card)
2041
28.1k
{
2042
28.1k
  struct sc_pkcs15_df *cur = NULL, *next = NULL;
2043
2044
28.1k
  if (!p15card || !p15card->df_list)
2045
22.5k
    return;
2046
2047
22.4k
  for (cur = p15card->df_list; cur; cur = next)   {
2048
16.8k
    next = cur->next;
2049
16.8k
    free(cur);
2050
16.8k
  }
2051
2052
5.63k
  p15card->df_list = NULL;
2053
5.63k
}
2054
2055
2056
int
2057
sc_pkcs15_encode_df(struct sc_context *ctx, struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df,
2058
    unsigned char **buf_out, size_t *bufsize_out)
2059
0
{
2060
0
  unsigned char *buf = NULL, *tmp = NULL, *p;
2061
0
  size_t bufsize = 0, tmpsize;
2062
0
  const struct sc_pkcs15_object *obj;
2063
0
  int (* func)(struct sc_context *, const struct sc_pkcs15_object *nobj,
2064
0
         unsigned char **nbuf, size_t *nbufsize) = NULL;
2065
0
  int r;
2066
2067
0
  if (p15card == NULL || p15card->magic != SC_PKCS15_CARD_MAGIC) {
2068
0
    return SC_ERROR_INVALID_ARGUMENTS;
2069
0
  }
2070
0
  switch (df->type) {
2071
0
  case SC_PKCS15_PRKDF:
2072
0
    func = sc_pkcs15_encode_prkdf_entry;
2073
0
    break;
2074
0
  case SC_PKCS15_PUKDF:
2075
0
  case SC_PKCS15_PUKDF_TRUSTED:
2076
0
    func = sc_pkcs15_encode_pukdf_entry;
2077
0
    break;
2078
0
  case SC_PKCS15_SKDF:
2079
0
    func = sc_pkcs15_encode_skdf_entry;
2080
0
    break;
2081
0
  case SC_PKCS15_CDF:
2082
0
  case SC_PKCS15_CDF_TRUSTED:
2083
0
  case SC_PKCS15_CDF_USEFUL:
2084
0
    func = sc_pkcs15_encode_cdf_entry;
2085
0
    break;
2086
0
  case SC_PKCS15_DODF:
2087
0
    func = sc_pkcs15_encode_dodf_entry;
2088
0
    break;
2089
0
  case SC_PKCS15_AODF:
2090
0
    func = sc_pkcs15_encode_aodf_entry;
2091
0
    break;
2092
0
  }
2093
0
  if (func == NULL) {
2094
0
    sc_log(ctx, "unknown DF type: %d", df->type);
2095
0
    *buf_out = NULL;
2096
0
    *bufsize_out = 0;
2097
0
    return 0;
2098
0
  }
2099
0
  for (obj = p15card->obj_list; obj != NULL; obj = obj->next) {
2100
0
    if (obj->df != df)
2101
0
      continue;
2102
0
    r = func(ctx, obj, &tmp, &tmpsize);
2103
0
    if (r) {
2104
0
      free(tmp);
2105
0
      free(buf);
2106
0
      return r;
2107
0
    }
2108
0
    if (!tmpsize)
2109
0
      continue;
2110
0
    p = (u8 *) realloc(buf, bufsize + tmpsize);
2111
0
    if (!p) {
2112
0
      free(tmp);
2113
0
      free(buf);
2114
0
      return SC_ERROR_OUT_OF_MEMORY;
2115
0
    }
2116
0
    buf = p;
2117
0
    memcpy(buf + bufsize, tmp, tmpsize);
2118
0
    free(tmp);
2119
0
    tmp = NULL;
2120
0
    bufsize += tmpsize;
2121
0
  }
2122
0
  *buf_out = buf;
2123
0
  *bufsize_out = bufsize;
2124
2125
0
  return 0;
2126
0
}
2127
2128
2129
int
2130
sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df)
2131
1.61k
{
2132
1.61k
  struct sc_context *ctx = p15card->card->ctx;
2133
1.61k
  unsigned char *buf;
2134
1.61k
  const unsigned char *p;
2135
1.61k
  size_t bufsize;
2136
1.61k
  int r;
2137
1.61k
  struct sc_pkcs15_object *obj = NULL;
2138
1.61k
  int (* func)(struct sc_pkcs15_card *, struct sc_pkcs15_object *,
2139
1.61k
         const u8 **nbuf, size_t *nbufsize) = NULL;
2140
2141
1.61k
  sc_log(ctx, "called; path=%s, type=%d, enum=%d", sc_print_path(&df->path), df->type, df->enumerated);
2142
2143
1.61k
  if (df->enumerated)
2144
1.61k
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2145
2146
1.61k
  switch (df->type) {
2147
63
  case SC_PKCS15_PRKDF:
2148
63
    func = sc_pkcs15_decode_prkdf_entry;
2149
63
    break;
2150
1.21k
  case SC_PKCS15_PUKDF:
2151
1.21k
    func = sc_pkcs15_decode_pukdf_entry;
2152
1.21k
    break;
2153
0
  case SC_PKCS15_SKDF:
2154
0
    func = sc_pkcs15_decode_skdf_entry;
2155
0
    break;
2156
270
  case SC_PKCS15_CDF:
2157
270
  case SC_PKCS15_CDF_TRUSTED:
2158
270
  case SC_PKCS15_CDF_USEFUL:
2159
270
    func = sc_pkcs15_decode_cdf_entry;
2160
270
    break;
2161
0
  case SC_PKCS15_DODF:
2162
0
    func = sc_pkcs15_decode_dodf_entry;
2163
0
    break;
2164
62
  case SC_PKCS15_AODF:
2165
62
    func = sc_pkcs15_decode_aodf_entry;
2166
62
    break;
2167
1.61k
  }
2168
1.61k
  if (func == NULL) {
2169
0
    sc_log(ctx, "unknown DF type: %d", df->type);
2170
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
2171
0
  }
2172
1.61k
  r = sc_pkcs15_read_file(p15card, &df->path, &buf, &bufsize, 0);
2173
1.61k
  LOG_TEST_RET(ctx, r, "pkcs15 read file failed");
2174
2175
517
  p = buf;
2176
517
  while (bufsize && *p != 0x00) {
2177
2178
478
    obj = calloc(1, sizeof(struct sc_pkcs15_object));
2179
478
    if (obj == NULL) {
2180
0
      r = SC_ERROR_OUT_OF_MEMORY;
2181
0
      goto ret;
2182
0
    }
2183
478
    r = func(p15card, obj, &p, &bufsize);
2184
478
    if (r) {
2185
478
      free(obj);
2186
478
      if (r == SC_ERROR_ASN1_END_OF_CONTENTS) {
2187
28
        r = 0;
2188
28
        break;
2189
28
      }
2190
450
      sc_log(ctx, "%s: Error decoding DF entry", sc_strerror(r));
2191
450
      goto ret;
2192
478
    }
2193
2194
0
    obj->df = df;
2195
0
    r = sc_pkcs15_add_object(p15card, obj);
2196
0
    if (r) {
2197
0
      if (obj->data)
2198
0
        free(obj->data);
2199
0
      free(obj);
2200
0
      sc_log(ctx, "%s: Error adding object", sc_strerror(r));
2201
0
      goto ret;
2202
0
    }
2203
0
    while (bufsize > 0 && *p == 00) {
2204
0
      bufsize--;
2205
0
      p++;
2206
0
    }
2207
67
  };
2208
2209
67
  if (r > 0)
2210
0
    r = 0;
2211
517
ret:
2212
517
  df->enumerated = 1;
2213
517
  free(buf);
2214
517
  LOG_FUNC_RETURN(ctx, r);
2215
517
}
2216
2217
2218
int
2219
sc_pkcs15_add_unusedspace(struct sc_pkcs15_card *p15card, const struct sc_path *path,
2220
    const struct sc_pkcs15_id *auth_id)
2221
0
{
2222
0
  struct sc_context *ctx = p15card->card->ctx;
2223
0
  struct sc_pkcs15_unusedspace *p = p15card->unusedspace_list, *new_unusedspace;
2224
2225
0
  if (path->count == -1) {
2226
0
    char pbuf[SC_MAX_PATH_STRING_SIZE];
2227
2228
0
    int r = sc_path_print(pbuf, sizeof(pbuf), path);
2229
0
    if (r != SC_SUCCESS)
2230
0
      pbuf[0] = '\0';
2231
2232
0
    sc_log(ctx, "No offset and length present in path %s", pbuf);
2233
0
    return SC_ERROR_INVALID_ARGUMENTS;
2234
0
  }
2235
2236
0
  new_unusedspace = calloc(1, sizeof(sc_pkcs15_unusedspace_t));
2237
0
  if (new_unusedspace == NULL)
2238
0
    return SC_ERROR_OUT_OF_MEMORY;
2239
0
  new_unusedspace->path = *path;
2240
0
  if (auth_id != NULL)
2241
0
    new_unusedspace->auth_id = *auth_id;
2242
2243
0
  if (p15card->unusedspace_list == NULL) {
2244
0
    p15card->unusedspace_list = new_unusedspace;
2245
0
    return 0;
2246
0
  }
2247
0
  while (p->next != NULL)
2248
0
    p = p->next;
2249
0
  p->next = new_unusedspace;
2250
0
  new_unusedspace->prev = p;
2251
2252
0
  return 0;
2253
0
}
2254
2255
2256
void
2257
sc_pkcs15_remove_unusedspace(struct sc_pkcs15_card *p15card, struct sc_pkcs15_unusedspace *unusedspace)
2258
0
{
2259
0
  if (!unusedspace)
2260
0
    return;
2261
2262
0
  if (!unusedspace->prev)
2263
0
    p15card->unusedspace_list = unusedspace->next;
2264
0
  else
2265
0
    unusedspace->prev->next = unusedspace->next;
2266
2267
0
  if (unusedspace->next)
2268
0
    unusedspace->next->prev = unusedspace->prev;
2269
2270
0
  free(unusedspace);
2271
0
}
2272
2273
2274
static void
2275
sc_pkcs15_free_unusedspace(struct sc_pkcs15_card *p15card)
2276
12.6k
{
2277
12.6k
  struct sc_pkcs15_unusedspace *cur = NULL, *next = NULL;
2278
2279
12.6k
  if (!p15card || !p15card->unusedspace_list)
2280
12.6k
    return;
2281
0
  for (cur = p15card->unusedspace_list; cur; cur = next)   {
2282
0
    next = cur->next;
2283
0
    free(cur);
2284
0
  }
2285
2286
0
  p15card->unusedspace_list = NULL;
2287
0
}
2288
2289
2290
int
2291
sc_pkcs15_encode_unusedspace(struct sc_context *ctx, struct sc_pkcs15_card *p15card,
2292
       unsigned char **buf, size_t *buflen)
2293
0
{
2294
0
  struct sc_path dummy_path;
2295
0
  static const struct sc_asn1_entry c_asn1_unusedspace[] = {
2296
0
    { "UnusedSpace", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
2297
0
    { NULL, 0, 0, 0, NULL, NULL }
2298
0
  };
2299
0
  static const struct sc_asn1_entry c_asn1_unusedspace_values[] = {
2300
0
    { "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
2301
0
    { "authId", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
2302
0
    { NULL, 0, 0, 0, NULL, NULL }
2303
0
  };
2304
0
  struct sc_asn1_entry *asn1_unusedspace = NULL;
2305
0
  struct sc_asn1_entry *asn1_values = NULL;
2306
0
  int unusedspace_count = 0, r, c = 0;
2307
0
  struct sc_pkcs15_unusedspace *unusedspace = NULL;
2308
2309
0
  sc_format_path("3F00", &dummy_path);
2310
0
  dummy_path.index = dummy_path.count = 0;
2311
2312
0
  unusedspace = p15card->unusedspace_list;
2313
0
  for ( ; unusedspace != NULL; unusedspace = unusedspace->next)
2314
0
    unusedspace_count++;
2315
0
  if (unusedspace_count == 0) {
2316
    /* The standard says there has to be at least 1 entry,
2317
     * so we use a path with a length of 0 bytes */
2318
0
    r = sc_pkcs15_add_unusedspace(p15card, &dummy_path, NULL);
2319
0
    if (r)
2320
0
      return r;
2321
0
    unusedspace_count = 1;
2322
0
  }
2323
2324
0
  asn1_unusedspace = (struct sc_asn1_entry *)
2325
0
    malloc(sizeof(struct sc_asn1_entry) * (unusedspace_count + 1));
2326
0
  if (asn1_unusedspace == NULL) {
2327
0
    r = SC_ERROR_OUT_OF_MEMORY;
2328
0
    goto err;
2329
0
  }
2330
0
  asn1_values = (struct sc_asn1_entry *)
2331
0
    malloc(sizeof(struct sc_asn1_entry) * (unusedspace_count * 3));
2332
0
  if (asn1_values == NULL) {
2333
0
    r = SC_ERROR_OUT_OF_MEMORY;
2334
0
    goto err;
2335
0
  }
2336
2337
0
  for (unusedspace = p15card->unusedspace_list; unusedspace != NULL; unusedspace = unusedspace->next) {
2338
0
    sc_copy_asn1_entry(c_asn1_unusedspace, asn1_unusedspace + c);
2339
0
    sc_format_asn1_entry(asn1_unusedspace + c, asn1_values + 3*c, NULL, 1);
2340
0
    sc_copy_asn1_entry(c_asn1_unusedspace_values, asn1_values + 3*c);
2341
0
    sc_format_asn1_entry(asn1_values + 3*c, &unusedspace->path, NULL, 1);
2342
0
    sc_format_asn1_entry(asn1_values + 3*c+1, &unusedspace->auth_id, NULL,
2343
0
         unusedspace->auth_id.len > 0 ? 1 : 0);
2344
0
    c++;
2345
0
  }
2346
0
  asn1_unusedspace[c].name = NULL;
2347
2348
0
  r = sc_asn1_encode(ctx, asn1_unusedspace, buf, buflen);
2349
2350
0
err:
2351
0
  if (asn1_values != NULL)
2352
0
    free(asn1_values);
2353
0
  if (asn1_unusedspace != NULL)
2354
0
    free(asn1_unusedspace);
2355
2356
  /* If we added the dummy entry, remove it now */
2357
0
  if (unusedspace_count == 1 && sc_compare_path(&p15card->unusedspace_list->path, &dummy_path))
2358
0
    sc_pkcs15_remove_unusedspace(p15card, p15card->unusedspace_list);
2359
2360
0
  return r;
2361
0
}
2362
2363
2364
int
2365
sc_pkcs15_parse_unusedspace(const unsigned char *buf, size_t buflen, struct sc_pkcs15_card *p15card)
2366
0
{
2367
0
  const unsigned char *p = buf;
2368
0
  size_t left = buflen;
2369
0
  int r;
2370
0
  struct sc_path path;
2371
0
  struct sc_pkcs15_id auth_id;
2372
0
  struct sc_asn1_entry asn1_unusedspace[] = {
2373
0
    { "UnusedSpace", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
2374
0
    { NULL, 0, 0, 0, NULL, NULL }
2375
0
  };
2376
0
  struct sc_asn1_entry asn1_unusedspace_values[] = {
2377
0
    { "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
2378
0
    { "authId", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
2379
0
    { NULL, 0, 0, 0, NULL, NULL }
2380
0
  };
2381
2382
  /* Clean the list if already present */
2383
0
  sc_pkcs15_free_unusedspace(p15card);
2384
2385
0
  sc_format_asn1_entry(asn1_unusedspace, asn1_unusedspace_values, NULL, 1);
2386
0
  sc_format_asn1_entry(asn1_unusedspace_values, &path, NULL, 1);
2387
0
  sc_format_asn1_entry(asn1_unusedspace_values+1, &auth_id, NULL, 0);
2388
2389
0
  while (left > 0) {
2390
0
    memset(&auth_id, 0, sizeof(auth_id));
2391
0
    r = sc_asn1_decode(p15card->card->ctx, asn1_unusedspace, p, left, &p, &left);
2392
0
    if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
2393
0
      break;
2394
0
    if (r < 0)
2395
0
      return r;
2396
    /* If the path length is 0, it's a dummy path then don't add it.
2397
     * If the path length isn't included (-1) then it's against the standard
2398
     *   but we'll just ignore it instead of returning an error. */
2399
0
    if (path.count > 0 && p15card->file_app) {
2400
0
      r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &path);
2401
0
      if (r < 0)
2402
0
        return r;
2403
0
      r = sc_pkcs15_add_unusedspace(p15card, &path, &auth_id);
2404
0
      if (r)
2405
0
        return r;
2406
0
    }
2407
0
  }
2408
2409
0
  p15card->unusedspace_read = 1;
2410
2411
0
  return 0;
2412
0
}
2413
2414
static int decompress_file(sc_card_t *card, unsigned char *buf, size_t buflen,
2415
    unsigned char **out, size_t *outlen, unsigned long flags)
2416
329
{
2417
329
  LOG_FUNC_CALLED(card->ctx);
2418
329
#ifdef ENABLE_ZLIB
2419
329
  int rv = SC_SUCCESS;
2420
329
  int method = 0;
2421
2422
329
  if (flags & SC_FILE_FLAG_COMPRESSED_GZIP) {
2423
0
    method = COMPRESSION_GZIP;
2424
329
  } else if (flags & SC_FILE_FLAG_COMPRESSED_ZLIB) {
2425
0
    method = COMPRESSION_ZLIB;
2426
329
  } else {
2427
329
    method = COMPRESSION_AUTO;
2428
329
  }
2429
2430
329
  rv = sc_decompress_alloc(out, outlen, buf, buflen, method);
2431
329
  if (rv != SC_SUCCESS) {
2432
197
    sc_log(card->ctx,  "Decompression failed: %d", rv);
2433
197
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
2434
197
  }
2435
132
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2436
#else
2437
  sc_log(card->ctx, "Compression not supported, no zlib");
2438
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2439
#endif
2440
132
}
2441
2442
int
2443
sc_decode_do53(sc_context_t *ctx, u8 **data, size_t *data_len,
2444
    const u8 *buf, size_t buflen)
2445
0
{
2446
0
  struct sc_asn1_entry c_asn1_do53[] = {
2447
0
    { "do53", SC_ASN1_OCTET_STRING, SC_ASN1_APP|0x13, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL },
2448
0
    { NULL, 0, 0, 0, NULL, NULL }
2449
0
  };
2450
0
  struct sc_asn1_entry asn1_do53[2];
2451
0
  int r;
2452
2453
0
  LOG_FUNC_CALLED(ctx);
2454
0
  sc_copy_asn1_entry(c_asn1_do53, asn1_do53);
2455
0
  sc_format_asn1_entry(asn1_do53, data, data_len, 0);
2456
2457
0
  r = sc_asn1_decode(ctx, asn1_do53, buf, buflen, NULL, NULL);
2458
0
  LOG_TEST_RET(ctx, r, "ASN.1 parsing of do-53 failed");
2459
2460
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2461
0
}
2462
2463
2464
int
2465
sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_path,
2466
    unsigned char **buf, size_t *buflen, int private_data)
2467
14.3k
{
2468
14.3k
  struct sc_context *ctx;
2469
14.3k
  struct sc_file *file = NULL;
2470
14.3k
  unsigned char *data = NULL;
2471
14.3k
  size_t  len = 0, offset = 0;
2472
14.3k
  int r;
2473
2474
14.3k
  if (p15card == NULL || p15card->card == NULL || in_path == NULL || buf == NULL) {
2475
0
    return SC_ERROR_INVALID_ARGUMENTS;
2476
0
  }
2477
14.3k
  ctx = p15card->card->ctx;
2478
2479
14.3k
  LOG_FUNC_CALLED(ctx);
2480
14.3k
  sc_log(ctx, "path=%s, index=%u, count=%d", sc_print_path(in_path), in_path->index, in_path->count);
2481
2482
14.3k
  r = -1; /* file state: not in cache */
2483
14.3k
  if (p15card->opts.use_file_cache
2484
14.3k
      && ((p15card->opts.use_file_cache & SC_PKCS15_OPTS_CACHE_ALL_FILES) || !private_data)) {
2485
6.55k
    r = sc_pkcs15_read_cached_file(p15card, in_path, &data, &len);
2486
2487
6.55k
    if (!r && in_path->aid.len > 0 && in_path->len >= 2)   {
2488
46
      struct sc_path parent = *in_path;
2489
2490
46
      parent.len -= 2;
2491
46
      parent.type = SC_PATH_TYPE_PATH;
2492
46
      r = sc_select_file(p15card->card, &parent, NULL);
2493
46
    }
2494
6.55k
  }
2495
2496
14.3k
  if (r) {
2497
13.6k
    r = sc_lock(p15card->card);
2498
13.6k
    if (r)
2499
0
      goto fail;
2500
13.6k
    r = sc_select_file(p15card->card, in_path, &file);
2501
13.6k
    if (r)
2502
9.75k
      goto fail_unlock;
2503
2504
    /* Handle the case where the ASN.1 Path object specified
2505
     * index and length values */
2506
2507
3.90k
    if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) {
2508
2509
      // in_path->index: record_no
2510
      // in_path->count: ignored!
2511
2512
101
      if(file->record_length > 0) {
2513
86
        if(file->record_length > MAX_FILE_SIZE) {
2514
0
          len = MAX_FILE_SIZE;
2515
0
          sc_log(ctx, "  record size truncated, encoded length: %"SC_FORMAT_LEN_SIZE_T"u", file->record_length);
2516
86
        } else {
2517
86
          len = file->record_length;
2518
86
        }
2519
86
      } else {
2520
15
        len = MAX_FILE_SIZE;
2521
15
      }
2522
2523
101
      if ((in_path->index <= 0) || (in_path->index > (int)(file->record_count))) {
2524
61
        sc_log(ctx, "  record number out of bounds: %d", in_path->index);
2525
61
        r = SC_ERROR_RECORD_NOT_FOUND;
2526
61
        goto fail_unlock;
2527
61
      }
2528
2529
3.80k
    } else {
2530
2531
3.80k
      if (in_path->count < 0) {
2532
2.19k
        if (file->size)
2533
1.98k
          len = (file->size > MAX_FILE_SIZE)? MAX_FILE_SIZE:file->size;
2534
203
        else
2535
203
          len = 1024;
2536
2.19k
        offset = 0;
2537
2.19k
      }
2538
1.61k
      else {
2539
1.61k
        offset = in_path->index;
2540
1.61k
        len = in_path->count;
2541
        /* Make sure we're within proper bounds */
2542
1.61k
        if (offset >= file->size || offset + len > file->size) {
2543
37
          r = SC_ERROR_INVALID_ASN1_OBJECT;
2544
37
          goto fail_unlock;
2545
37
        }
2546
1.61k
      }
2547
3.80k
    }
2548
2549
3.80k
    free(data);
2550
3.80k
    data = malloc(len);
2551
3.80k
    if (data == NULL) {
2552
0
      r = SC_ERROR_OUT_OF_MEMORY;
2553
0
      goto fail_unlock;
2554
0
    }
2555
2556
3.80k
    if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE_TLV) {
2557
59
      unsigned int i;
2558
59
      size_t l, record_len;
2559
59
      unsigned char *head = data;
2560
2561
842
      for (i=1; ; i++) {
2562
842
        l = len - (head - data);
2563
842
        if (l > 256) {
2564
630
          l = 256;
2565
630
        }
2566
842
        r = sc_read_record(p15card->card, i, 0, head, l, SC_RECORD_BY_REC_NR);
2567
842
        if (r == SC_ERROR_RECORD_NOT_FOUND)
2568
1
          break;
2569
841
        if (r < 0) {
2570
53
          goto fail_unlock;
2571
53
        }
2572
788
        if (r < 2)
2573
4
          break;
2574
784
        record_len = head[1];
2575
784
        if (record_len != 0xff) {
2576
637
          memmove(head, head+2, r-2);
2577
637
          head += (r-2);
2578
637
        }
2579
147
        else {
2580
147
          if (r < 4)
2581
1
            break;
2582
146
          memmove(head, head+4, r-4);
2583
146
          head += (r-4);
2584
146
        }
2585
784
      }
2586
6
      len = head-data;
2587
6
    }
2588
3.74k
    else if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) {
2589
40
      r = sc_read_record(p15card->card, in_path->index, (unsigned)offset, data, len, SC_RECORD_BY_REC_NR);
2590
40
      if (r < 0) {
2591
6
        goto fail_unlock;
2592
6
      }
2593
      /* sc_read_record may return less than requested */
2594
34
      len = r;
2595
34
    }
2596
3.70k
    else {
2597
3.70k
      unsigned long flags = 0;
2598
3.70k
      r = sc_read_binary(p15card->card, (unsigned)offset, data, len, &flags);
2599
3.70k
      if (r < 0) {
2600
1.01k
        goto fail_unlock;
2601
1.01k
      }
2602
      /* sc_read_binary may return less than requested */
2603
2.68k
      len = r;
2604
2605
2.68k
      if (flags & SC_FILE_FLAG_COMPRESSED_AUTO
2606
2.68k
          || flags & SC_FILE_FLAG_COMPRESSED_ZLIB
2607
2.68k
          || flags & SC_FILE_FLAG_COMPRESSED_GZIP) {
2608
329
        unsigned char *decompressed_buf = NULL;
2609
329
        size_t decompressed_len = 0;
2610
329
        r = decompress_file(p15card->card, data, len, &decompressed_buf, &decompressed_len, flags);
2611
329
        if (r != SC_SUCCESS) {
2612
197
          goto fail_unlock;
2613
197
        }
2614
132
        free(data);
2615
132
        data = decompressed_buf;
2616
132
        len = decompressed_len;
2617
132
      }
2618
2.68k
    }
2619
2.53k
    sc_unlock(p15card->card);
2620
2621
2.53k
    sc_file_free(file);
2622
2623
2.53k
    if (len && p15card->opts.use_file_cache
2624
2.53k
        && ((p15card->opts.use_file_cache & SC_PKCS15_OPTS_CACHE_ALL_FILES) || !private_data)) {
2625
443
      sc_pkcs15_cache_file(p15card, in_path, data, len);
2626
443
    }
2627
2.53k
    if (len == 0) {
2628
266
      free(data);
2629
266
      data = NULL;
2630
266
    }
2631
2.53k
  }
2632
3.22k
  *buf = data;
2633
3.22k
  *buflen = len;
2634
3.22k
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2635
2636
11.1k
fail_unlock:
2637
11.1k
  sc_unlock(p15card->card);
2638
11.1k
fail:
2639
11.1k
  free(data);
2640
11.1k
  sc_file_free(file);
2641
11.1k
  LOG_FUNC_RETURN(ctx, r);
2642
11.1k
}
2643
2644
2645
int
2646
sc_pkcs15_compare_id(const struct sc_pkcs15_id *id1, const struct sc_pkcs15_id *id2)
2647
5.81k
{
2648
5.81k
  if (id1 == NULL || id2 == NULL)
2649
0
    return 0;
2650
5.81k
  if (id1->len != id2->len)
2651
3.05k
    return 0;
2652
2.76k
  return memcmp(id1->value, id2->value, id1->len) == 0;
2653
5.81k
}
2654
2655
2656
void
2657
sc_pkcs15_format_id(const char *str, struct sc_pkcs15_id *id)
2658
100k
{
2659
100k
  size_t len;
2660
2661
100k
  if (!id)
2662
0
    return;
2663
100k
  len = sizeof(id->value);
2664
2665
100k
  if (sc_hex_to_bin(str, id->value, &len) != SC_SUCCESS)
2666
0
    id->len = 0;
2667
100k
  else
2668
100k
    id->len = len;
2669
100k
}
2670
2671
2672
const char *
2673
sc_pkcs15_print_id(const struct sc_pkcs15_id *id)
2674
512
{
2675
512
  static char buffer[256];
2676
2677
512
  sc_bin_to_hex(id->value, id->len, buffer, sizeof(buffer), '\0');
2678
512
  return buffer;
2679
512
}
2680
2681
2682
int
2683
sc_pkcs15_hex_string_to_id(const char *in, struct sc_pkcs15_id *out)
2684
0
{
2685
0
  out->len = sizeof(out->value);
2686
0
  return sc_hex_to_bin(in, out->value, &out->len);
2687
0
}
2688
2689
2690
int
2691
sc_pkcs15_make_absolute_path(const struct sc_path *parent, struct sc_path *child)
2692
18.1k
{
2693
  /* nothing to do if child has valid 'aid' */
2694
18.1k
  if (child->aid.len)
2695
0
    return SC_SUCCESS;
2696
2697
18.1k
  if (parent->aid.len)   {
2698
0
    sc_path_t ppath;
2699
2700
    /* child inherits parent's 'aid' */
2701
0
    child->aid = parent->aid;
2702
0
    if (!parent->len)
2703
0
      return SC_SUCCESS;
2704
2705
    /* parent has valid 'path' -- concatenate it with the child's one */
2706
0
    memcpy(&ppath, parent, sizeof(sc_path_t));
2707
0
    ppath.aid.len = 0;
2708
0
    ppath.type = SC_PATH_TYPE_FROM_CURRENT;
2709
0
    return sc_concatenate_path(child, &ppath, child);
2710
2711
0
  }
2712
18.1k
  else if (parent->type == SC_PATH_TYPE_DF_NAME)   {
2713
    /* child inherits parent's 'DF NAME' as 'aid' */
2714
101
    if (parent->len > sizeof(child->aid.value))
2715
0
      return SC_ERROR_WRONG_LENGTH;
2716
2717
101
    memcpy(child->aid.value, parent->value, parent->len);
2718
101
    child->aid.len = parent->len;
2719
2720
101
    return SC_SUCCESS;
2721
101
  }
2722
2723
  /* a 0 length path stays a 0 length path */
2724
18.0k
  if (child->len == 0)
2725
86
    return SC_SUCCESS;
2726
2727
17.9k
  if (sc_compare_path_prefix(sc_get_mf_path(), child))
2728
68
    return SC_SUCCESS;
2729
2730
17.8k
  return sc_concatenate_path(child, parent, child);
2731
17.9k
}
2732
2733
2734
void sc_pkcs15_free_object_content(struct sc_pkcs15_object *obj)
2735
41.1k
{
2736
41.1k
  if (obj->content.value && obj->content.len) {
2737
658
    if (obj->content_free) {
2738
658
      obj->content_free(obj->content.value, obj->content.len);
2739
658
    } else {
2740
0
      free(obj->content.value);
2741
0
    }
2742
658
  }
2743
41.1k
  obj->content.value = NULL;
2744
41.1k
  obj->content.len = 0;
2745
41.1k
}
2746
2747
2748
int
2749
sc_pkcs15_allocate_object_content(struct sc_context *ctx, struct sc_pkcs15_object *obj,
2750
    const unsigned char *value, size_t len)
2751
658
{
2752
658
  unsigned char *tmp_buf;
2753
2754
658
  if (!obj)
2755
0
    return SC_ERROR_INVALID_ARGUMENTS;
2756
2757
658
  if (!value || !len)   {
2758
0
    sc_pkcs15_free_object_content(obj);
2759
0
    return SC_SUCCESS;
2760
0
  }
2761
2762
  /* Need to pass by temporary variable,
2763
   * because 'value' and 'content.value' pointers can be the sames.
2764
   */
2765
658
  if (SC_PKCS15_TYPE_AUTH & obj->type
2766
658
      || SC_PKCS15_TYPE_SKEY & obj->type
2767
658
      || SC_PKCS15_TYPE_PRKEY & obj->type) {
2768
658
    tmp_buf = sc_mem_secure_alloc(len);
2769
658
    obj->content_free = sc_mem_secure_free;
2770
658
  } else {
2771
0
    tmp_buf = malloc(len);
2772
0
  }
2773
658
  if (!tmp_buf)
2774
0
    return SC_ERROR_OUT_OF_MEMORY;
2775
2776
658
  memcpy(tmp_buf, value, len);
2777
2778
658
  sc_pkcs15_free_object_content(obj);
2779
2780
658
  obj->content.value = tmp_buf;
2781
658
  obj->content.len = len;
2782
2783
658
  return SC_SUCCESS;
2784
658
}
2785
2786
2787
struct sc_supported_algo_info *
2788
sc_pkcs15_get_supported_algo(struct sc_pkcs15_card *p15card, unsigned operation, unsigned mechanism)
2789
0
{
2790
0
  struct sc_context *ctx = p15card->card->ctx;
2791
0
  struct sc_supported_algo_info *info = NULL;
2792
0
  int ii;
2793
2794
0
  for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference; ii++)
2795
0
    if ((p15card->tokeninfo->supported_algos[ii].operations & operation)
2796
0
        && (p15card->tokeninfo->supported_algos[ii].mechanism == mechanism))
2797
0
      break;
2798
2799
0
  if (ii < SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference)   {
2800
0
    info = &p15card->tokeninfo->supported_algos[ii];
2801
0
    sc_log(ctx, "found supported algorithm (ref:%X,mech:%X,ops:%X,algo_ref:%X)",
2802
0
        info->reference, info->mechanism, info->operations, info->algo_ref);
2803
0
  }
2804
2805
0
  return info;
2806
0
}
2807
2808
struct sc_supported_algo_info *
2809
sc_pkcs15_get_specific_supported_algo(struct sc_pkcs15_card *p15card, unsigned operation, unsigned mechanism, const struct sc_object_id *algo_oid)
2810
0
{
2811
0
  struct sc_context *ctx = p15card->card->ctx;
2812
0
  struct sc_supported_algo_info *info = NULL;
2813
0
  int ii;
2814
2815
0
  if (algo_oid == NULL)
2816
0
    return NULL;
2817
2818
0
  for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference; ii++)
2819
0
    if ((p15card->tokeninfo->supported_algos[ii].operations & operation)
2820
0
        && (p15card->tokeninfo->supported_algos[ii].mechanism == mechanism)
2821
0
        && sc_compare_oid(algo_oid, &p15card->tokeninfo->supported_algos[ii].algo_id) == 1)
2822
0
      break;
2823
2824
0
  if (ii < SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference)   {
2825
0
    info = &p15card->tokeninfo->supported_algos[ii];
2826
0
    sc_log(ctx, "found supported algorithm (ref:%X,mech:%X,ops:%X,algo_ref:%X)",
2827
0
        info->reference, info->mechanism, info->operations, info->algo_ref);
2828
0
  }
2829
2830
0
  return info;
2831
0
}
2832
2833
int
2834
sc_pkcs15_get_generalized_time(struct sc_context *ctx, char **out)
2835
0
{
2836
0
#ifdef HAVE_GETTIMEOFDAY
2837
0
  struct timeval tv;
2838
0
#endif
2839
0
  struct tm tm;
2840
0
  time_t t;
2841
2842
0
  if (!ctx || !out)
2843
0
    return SC_ERROR_INVALID_ARGUMENTS;
2844
0
  *out = NULL;
2845
2846
0
#ifdef HAVE_GETTIMEOFDAY
2847
0
  gettimeofday(&tv, NULL);
2848
0
  t = tv.tv_sec;
2849
#else
2850
  t = time(NULL);
2851
#endif
2852
2853
#ifdef _WIN32
2854
  if (0 != gmtime_s(&tm, &t))
2855
    LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
2856
#else
2857
0
  if (NULL == gmtime_r(&t, &tm))
2858
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
2859
0
#endif
2860
2861
0
  *out = calloc(1, 16);
2862
0
  if (*out == NULL)
2863
0
    LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "memory failure");
2864
2865
  /* print time in generalized time format */
2866
0
  if (!strftime(*out, 16, "%Y%m%d%H%M%SZ", &tm)) {
2867
0
    free(*out);
2868
0
    LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "strftime failed");
2869
0
  }
2870
2871
0
  return SC_SUCCESS;
2872
0
}
2873
2874
2875
int
2876
sc_pkcs15_add_supported_algo_ref(struct sc_pkcs15_object *obj, struct sc_supported_algo_info *algo)
2877
0
{
2878
0
  unsigned int ii, *algo_refs = NULL;
2879
2880
0
  if (!algo)
2881
0
    return SC_SUCCESS;
2882
2883
0
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
2884
0
  case SC_PKCS15_TYPE_PRKEY:
2885
0
    algo_refs = ((struct sc_pkcs15_prkey_info *)obj->data)->algo_refs;
2886
0
    break;
2887
0
  case SC_PKCS15_TYPE_PUBKEY:
2888
0
    algo_refs = ((struct sc_pkcs15_pubkey_info *)obj->data)->algo_refs;
2889
0
    break;
2890
0
  case SC_PKCS15_TYPE_SKEY:
2891
0
    algo_refs = ((struct sc_pkcs15_skey_info *)obj->data)->algo_refs;
2892
0
    break;
2893
0
  }
2894
0
  if (!algo_refs)
2895
0
    return SC_ERROR_NOT_SUPPORTED;
2896
2897
0
  for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS && *(algo_refs + ii);ii++)
2898
0
    if (*(algo_refs + ii) == algo->reference)
2899
0
      return SC_SUCCESS;
2900
2901
0
  for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS;ii++)   {
2902
0
    if (*(algo_refs + ii) == 0)   {
2903
0
      *(algo_refs + ii) = algo->reference;
2904
0
      return SC_SUCCESS;
2905
0
    }
2906
0
  }
2907
2908
0
  return SC_ERROR_TOO_MANY_OBJECTS;
2909
0
}
2910
2911
2912
int
2913
sc_pkcs15_get_object_id(const struct sc_pkcs15_object *obj, struct sc_pkcs15_id *out)
2914
0
{
2915
0
  if (!obj || !out)
2916
0
    return SC_ERROR_INVALID_ARGUMENTS;
2917
2918
0
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
2919
0
  case SC_PKCS15_TYPE_CERT:
2920
0
    *out = ((struct sc_pkcs15_cert_info *) obj->data)->id;
2921
0
    break;
2922
0
  case SC_PKCS15_TYPE_PRKEY:
2923
0
    *out = ((struct sc_pkcs15_prkey_info *) obj->data)->id;
2924
0
    break;
2925
0
  case SC_PKCS15_TYPE_PUBKEY:
2926
0
    *out = ((struct sc_pkcs15_pubkey_info *) obj->data)->id;
2927
0
    break;
2928
0
  case SC_PKCS15_TYPE_SKEY:
2929
0
    *out = ((struct sc_pkcs15_skey_info *) obj->data)->id;
2930
0
    break;
2931
0
  case SC_PKCS15_TYPE_AUTH:
2932
0
    *out = ((struct sc_pkcs15_auth_info *) obj->data)->auth_id;
2933
0
    break;
2934
0
  case SC_PKCS15_TYPE_DATA_OBJECT:
2935
0
    *out = ((struct sc_pkcs15_data_info *) obj->data)->id;
2936
0
    break;
2937
0
  default:
2938
0
    return SC_ERROR_NOT_SUPPORTED;
2939
0
  }
2940
2941
0
  return SC_SUCCESS;
2942
0
}
2943
2944
/*
2945
 * Simplified GUID serializing.
2946
 * Ex. {3F2504E0-4F89-11D3-9A0C-0305E82C3301}
2947
 *
2948
 * There is no variant, version number and other special meaning fields
2949
 *  that are described in RFC-4122 .
2950
 */
2951
int
2952
sc_pkcs15_serialize_guid(unsigned char *in, size_t in_size, unsigned flags,
2953
    char *out, size_t out_size)
2954
0
{
2955
0
  int ii, jj, offs = 0;
2956
2957
0
  if (in_size < 16)
2958
0
    return SC_ERROR_BUFFER_TOO_SMALL;
2959
0
  if (out_size < 39)
2960
0
    return SC_ERROR_BUFFER_TOO_SMALL;
2961
2962
0
  *out = '\0';
2963
0
  if (!flags)
2964
0
    strcpy(out, "{");
2965
0
  for (ii=0; ii<4; ii++)
2966
0
    sprintf(out + strlen(out), "%02x", *(in + offs++));
2967
0
  for (jj=0; jj<3; jj++)   {
2968
0
    strcat(out, "-");
2969
0
    for (ii=0; ii<2; ii++)
2970
0
      sprintf(out + strlen(out), "%02x", *(in + offs++));
2971
0
  }
2972
0
  strcat(out, "-");
2973
0
  for (ii=0; ii<6; ii++)
2974
0
    sprintf(out + strlen(out), "%02x", *(in + offs++));
2975
0
  if (!flags)
2976
0
    strcat(out, "}");
2977
2978
0
  return SC_SUCCESS;
2979
0
}
2980
2981
2982
int
2983
sc_pkcs15_get_object_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj,
2984
    unsigned flags, unsigned char *out, size_t *out_size)
2985
0
{
2986
0
  struct sc_context *ctx = p15card->card->ctx;
2987
0
  struct sc_serial_number serialnr;
2988
0
  struct sc_pkcs15_id  id;
2989
0
  unsigned char guid_bin[SC_PKCS15_MAX_ID_SIZE + SC_MAX_SERIALNR];
2990
0
  int rv;
2991
0
  size_t guid_bin_size;
2992
2993
0
  LOG_FUNC_CALLED(ctx);
2994
0
  if(!out || !out_size)
2995
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
2996
2997
0
  if (p15card->ops.get_guid)   {
2998
0
    rv = p15card->ops.get_guid(p15card, obj, out, out_size);
2999
0
    LOG_FUNC_RETURN(ctx, rv);
3000
0
  }
3001
3002
0
  rv = sc_pkcs15_aux_get_md_guid(p15card, obj, flags, out, out_size);
3003
0
  if (rv == SC_SUCCESS)
3004
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
3005
0
  else if (rv != SC_ERROR_NOT_SUPPORTED)
3006
0
    LOG_TEST_RET(ctx, rv, "Failed to get alternative object GUID");
3007
3008
0
  memset(out, 0, *out_size);
3009
3010
0
  rv = sc_pkcs15_get_object_id(obj, &id);
3011
0
  LOG_TEST_RET(ctx, rv, "Cannot get object's ID");
3012
3013
0
  if (p15card->tokeninfo && p15card->tokeninfo->serial_number)   {
3014
    /* The serial from EF(TokenInfo) is preferred because of the
3015
     * "--serial" parameter of pkcs15-init. */
3016
0
    serialnr.len = SC_MAX_SERIALNR;
3017
0
    rv = sc_hex_to_bin(p15card->tokeninfo->serial_number, serialnr.value, &serialnr.len);
3018
0
    if (rv) {
3019
      /* Fallback in case hex_to_bin fails due to unexpected characters */
3020
0
      serialnr.len = strlen(p15card->tokeninfo->serial_number);
3021
0
      if (serialnr.len > SC_MAX_SERIALNR)
3022
0
        serialnr.len = SC_MAX_SERIALNR;
3023
3024
0
      memcpy(serialnr.value, p15card->tokeninfo->serial_number, serialnr.len);
3025
0
    }
3026
0
  } else if (p15card->card->serialnr.len)   {
3027
0
    serialnr = p15card->card->serialnr;
3028
0
  } else   {
3029
0
    rv = sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &serialnr);
3030
0
    LOG_TEST_RET(ctx, rv, "'GET_SERIALNR' CTL failed and other serial numbers not present");
3031
0
  }
3032
3033
0
  memset(guid_bin, 0, sizeof(guid_bin));
3034
0
  memcpy(guid_bin, id.value, id.len);
3035
0
  memcpy(guid_bin + id.len, serialnr.value, serialnr.len);
3036
0
  guid_bin_size = id.len + serialnr.len;
3037
3038
  /*
3039
   * If OpenSSL is available (SHA1), then rather use the hash of the data
3040
   * - this also protects against data being too short
3041
   */
3042
0
#ifdef ENABLE_OPENSSL
3043
0
  SHA1(guid_bin, guid_bin_size, guid_bin);
3044
0
  guid_bin_size = SHA_DIGEST_LENGTH;
3045
#else
3046
  /* If guid_bin has a size larger than 16 bytes
3047
   * force the remaining bytes up to 16 bytes to be zero
3048
   * so sc_pkcs15_serialize_guid won't fail because the size is less than 16
3049
   */
3050
  if (guid_bin_size < 16)
3051
    guid_bin_size = 16;
3052
#endif
3053
3054
0
  rv = sc_pkcs15_serialize_guid(guid_bin, guid_bin_size, flags, (char *)out, *out_size);
3055
0
  LOG_TEST_RET(ctx, rv, "Serialize GUID error");
3056
3057
0
  *out_size = strlen((char *)out);
3058
0
  LOG_FUNC_RETURN(ctx, rv);
3059
0
}
3060
3061
3062
static int
3063
sc_pkcs15_aux_get_md_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj,
3064
    unsigned flags,
3065
    unsigned char *out, size_t *out_size)
3066
0
{
3067
0
  struct sc_context *ctx = p15card->card->ctx;
3068
0
  struct sc_pkcs15_prkey_info *prkey_info = NULL;
3069
0
  int rv;
3070
3071
0
  LOG_FUNC_CALLED(ctx);
3072
0
  if(!out || !out_size)
3073
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
3074
3075
0
  if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY)
3076
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
3077
3078
0
  prkey_info = (struct sc_pkcs15_prkey_info *)obj->data;
3079
0
  if (!prkey_info->aux_data || prkey_info->aux_data->type != SC_AUX_DATA_TYPE_MD_CMAP_RECORD)
3080
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
3081
3082
0
  rv = sc_aux_data_get_md_guid(ctx, prkey_info->aux_data, flags, out, out_size);
3083
0
  LOG_FUNC_RETURN(ctx, rv);
3084
0
}
3085
3086
3087
void
3088
sc_pkcs15_free_key_params(struct sc_pkcs15_key_params *params)
3089
6.46k
{
3090
6.46k
  if (!params)
3091
0
    return;
3092
6.46k
  if (params->data && params->free_params)
3093
0
    params->free_params(params->data);
3094
6.46k
  else if (params->data)
3095
0
    free(params->data);
3096
3097
6.46k
  params->data = NULL;
3098
6.46k
}
3099