Coverage Report

Created: 2025-10-13 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/pkcs15.c
Line
Count
Source
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
708
{
142
708
  int r;
143
708
  size_t ii;
144
708
  u8 serial[128];
145
708
  size_t serial_len = sizeof(serial);
146
708
  u8 mnfid[SC_PKCS15_MAX_LABEL_SIZE];
147
708
  size_t mnfid_len  = sizeof(mnfid) - 1;
148
708
  u8 label[SC_PKCS15_MAX_LABEL_SIZE];
149
708
  size_t label_len = sizeof(label) - 1;
150
708
  u8 last_update[32], profile_indication[SC_PKCS15_MAX_LABEL_SIZE];
151
708
  size_t lupdate_len = sizeof(last_update) - 1, pi_len = sizeof(profile_indication) - 1;
152
708
  size_t flags_len   = sizeof(ti->flags);
153
708
  u8 preferred_language[3];
154
708
  size_t lang_length = sizeof(preferred_language);
155
708
  struct sc_asn1_entry asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1],
156
708
      asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7],
157
708
      asn1_algo_infos_parameters[SC_MAX_SUPPORTED_ALGORITHMS][3];
158
708
  size_t reference_len = sizeof(ti->supported_algos[0].reference);
159
708
  size_t mechanism_len = sizeof(ti->supported_algos[0].mechanism);
160
708
  size_t parameter_len = sizeof(ti->supported_algos[0].parameters);
161
708
  size_t operations_len = sizeof(ti->supported_algos[0].operations);
162
708
  size_t algo_ref_len = sizeof(ti->supported_algos[0].algo_ref);
163
164
708
  struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE];
165
708
  struct sc_asn1_entry asn1_profile_indication[C_ASN1_PROFILE_INDICATION_SIZE];
166
708
  struct sc_asn1_entry asn1_toki_attrs[C_ASN1_TOKI_ATTRS_SIZE], asn1_tokeninfo[3], asn1_twlabel[3];
167
168
708
  memset(last_update, 0, sizeof(last_update));
169
708
  memset(label, 0, sizeof(label));
170
708
  memset(profile_indication, 0, sizeof(profile_indication));
171
708
  memset(mnfid, 0, sizeof(mnfid));
172
173
708
  sc_copy_asn1_entry(c_asn1_twlabel, asn1_twlabel);
174
708
  sc_copy_asn1_entry(c_asn1_toki_attrs, asn1_toki_attrs);
175
708
  sc_copy_asn1_entry(c_asn1_tokeninfo, asn1_tokeninfo);
176
708
  sc_copy_asn1_entry(c_asn1_last_update, asn1_last_update);
177
708
  sc_format_asn1_entry(asn1_twlabel, label, &label_len, 0);
178
708
  sc_copy_asn1_entry(c_asn1_profile_indication, asn1_profile_indication);
179
180
12.0k
  for (ii=0; ii<SC_MAX_SUPPORTED_ALGORITHMS; ii++) {
181
11.3k
    sc_copy_asn1_entry(c_asn1_algorithm_info, asn1_algo_infos[ii]);
182
11.3k
    sc_copy_asn1_entry(c_asn1_algorithm_info_parameters,
183
11.3k
      asn1_algo_infos_parameters[ii]);
184
11.3k
  }
185
708
  sc_copy_asn1_entry(c_asn1_supported_algorithms, asn1_supported_algorithms);
186
187
12.0k
  for (ii=0; ii<SC_MAX_SUPPORTED_ALGORITHMS; ii++)   {
188
11.3k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 0, &ti->supported_algos[ii].reference, &reference_len, 0);
189
11.3k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 1, &ti->supported_algos[ii].mechanism, &mechanism_len, 0);
190
11.3k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 2,
191
11.3k
      asn1_algo_infos_parameters[ii], NULL, 0);
192
11.3k
    sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 0,
193
11.3k
      NULL, NULL, 0);
194
11.3k
    sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 1,
195
11.3k
      &ti->supported_algos[ii].parameters, &parameter_len, 0);
196
11.3k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 3, &ti->supported_algos[ii].operations, &operations_len, 0);
197
11.3k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 4, &ti->supported_algos[ii].algo_id, NULL, 1);
198
11.3k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 5, &ti->supported_algos[ii].algo_ref, &algo_ref_len, 0);
199
11.3k
    sc_format_asn1_entry(asn1_supported_algorithms + ii, asn1_algo_infos[ii], NULL, 0);
200
11.3k
  }
201
202
708
  sc_format_asn1_entry(asn1_last_update + 0, last_update, &lupdate_len, 0);
203
708
  sc_format_asn1_entry(asn1_last_update + 1, &ti->last_update.path, NULL, 0);
204
205
708
  sc_format_asn1_entry(asn1_profile_indication + 0, &ti->profile_indication.oid, NULL, 0);
206
708
  sc_format_asn1_entry(asn1_profile_indication + 1, profile_indication, &pi_len, 0);
207
208
708
  sc_format_asn1_entry(asn1_toki_attrs + 0, &ti->version, NULL, 0);
209
708
  sc_format_asn1_entry(asn1_toki_attrs + 1, serial, &serial_len, 0);
210
708
  sc_format_asn1_entry(asn1_toki_attrs + 2, mnfid, &mnfid_len, 0);
211
708
  sc_format_asn1_entry(asn1_toki_attrs + 3, label, &label_len, 0);
212
708
  sc_format_asn1_entry(asn1_toki_attrs + 4, asn1_twlabel, NULL, 0);
213
708
  sc_format_asn1_entry(asn1_toki_attrs + 5, &ti->flags, &flags_len, 0);
214
708
  sc_format_asn1_entry(asn1_toki_attrs + 6, &ti->seInfo, &ti->num_seInfo, 0);
215
708
  sc_format_asn1_entry(asn1_toki_attrs + 7, NULL, NULL, 0);
216
708
  sc_format_asn1_entry(asn1_toki_attrs + 8, asn1_supported_algorithms, NULL, 0);
217
708
  sc_format_asn1_entry(asn1_toki_attrs + 9, NULL, NULL, 0);
218
708
  sc_format_asn1_entry(asn1_toki_attrs + 10, NULL, NULL, 0);
219
708
  sc_format_asn1_entry(asn1_toki_attrs + 11, asn1_last_update, NULL, 0);
220
708
  sc_format_asn1_entry(asn1_toki_attrs + 12, preferred_language, &lang_length, 0);
221
708
  sc_format_asn1_entry(asn1_toki_attrs + 13, asn1_profile_indication, NULL, 0);
222
708
  sc_format_asn1_entry(asn1_tokeninfo, asn1_toki_attrs, NULL, 0);
223
224
708
  r = sc_asn1_decode(ctx, asn1_tokeninfo, buf, blen, NULL, NULL);
225
708
  if (r != SC_SUCCESS) {
226
    /* The decoding could have allocated something we need to free */
227
393
    sc_pkcs15_clear_tokeninfo(ti);
228
393
    LOG_TEST_RET(ctx, r, "ASN.1 parsing of EF(TokenInfo) failed");
229
393
  }
230
231
315
  if (asn1_toki_attrs[1].flags & SC_ASN1_PRESENT && serial_len > 0)   {
232
112
    free(ti->serial_number);
233
112
    ti->serial_number = malloc(serial_len * 2 + 1);
234
112
    if (ti->serial_number == NULL)
235
0
      return SC_ERROR_OUT_OF_MEMORY;
236
112
    sc_bin_to_hex(serial, serial_len, ti->serial_number, serial_len * 2 + 1, 0);
237
112
    sc_log(ctx, "TokenInfo.serialNunmber '%s'", ti->serial_number);
238
112
  }
239
240
315
  if (ti->manufacturer_id == NULL) {
241
315
    if (asn1_toki_attrs[2].flags & SC_ASN1_PRESENT)
242
113
      ti->manufacturer_id = strdup((char *) mnfid);
243
202
    else
244
202
      ti->manufacturer_id = strdup("(unknown)");
245
315
    if (ti->manufacturer_id == NULL)
246
0
      return SC_ERROR_OUT_OF_MEMORY;
247
315
  }
248
315
  if (ti->label == NULL) {
249
315
    if (asn1_toki_attrs[3].flags & SC_ASN1_PRESENT ||
250
240
        asn1_toki_attrs[4].flags & SC_ASN1_PRESENT)
251
75
      ti->label = strdup((char *) label);
252
240
    else
253
240
      ti->label = strdup("(unknown)");
254
315
    if (ti->label == NULL)
255
0
      return SC_ERROR_OUT_OF_MEMORY;
256
315
  }
257
315
  if (asn1_toki_attrs[11].flags & SC_ASN1_PRESENT) {
258
37
    if (asn1_last_update[0].flags & SC_ASN1_PRESENT)   {
259
5
      sc_log(ctx, "LastUpdate.generalizedTime present");
260
5
      ti->last_update.gtime = strdup((char *)last_update);
261
5
      if (ti->last_update.gtime == NULL)
262
0
        return SC_ERROR_OUT_OF_MEMORY;
263
5
    }
264
32
    else if (asn1_last_update[1].flags & SC_ASN1_PRESENT)  {
265
23
      sc_log(ctx, "LastUpdate.referencedTime present");
266
23
    }
267
37
  }
268
315
  if (asn1_toki_attrs[12].flags & SC_ASN1_PRESENT) {
269
3
    preferred_language[2] = 0;
270
3
    ti->preferred_language = strdup((char *)preferred_language);
271
3
    if (ti->preferred_language == NULL)
272
0
      return SC_ERROR_OUT_OF_MEMORY;
273
3
  }
274
275
315
  sc_init_oid(&ti->profile_indication.oid);
276
315
  if (asn1_toki_attrs[13].flags & SC_ASN1_PRESENT) {
277
174
    if (asn1_profile_indication[0].flags & SC_ASN1_PRESENT)   {
278
1
      sc_log(ctx, "ProfileIndication.oid present");
279
1
    }
280
173
    else if (asn1_profile_indication[1].flags & SC_ASN1_PRESENT)  {
281
172
      sc_log(ctx, "ProfileIndication.name present");
282
172
      ti->profile_indication.name = strdup((char *)profile_indication);
283
172
      if (ti->profile_indication.name == NULL)
284
0
        return SC_ERROR_OUT_OF_MEMORY;
285
172
    }
286
174
  }
287
288
315
  sc_log(ctx, "LastUpdate.path '%s'", sc_print_path(&ti->last_update.path));
289
315
  sc_log(ctx, "ProfileIndication.name '%s'",  ti->profile_indication.name);
290
315
  return SC_SUCCESS;
291
315
}
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
96
{
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
96
  if (p15card->card->type == SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2)   {
454
1
    sc_file_free(p15card->file_odf);
455
1
    p15card->file_odf = NULL;
456
1
    sc_file_free(p15card->file_tokeninfo);
457
1
    p15card->file_tokeninfo = NULL;
458
1
  }
459
96
}
460
461
static int
462
parse_ddo(struct sc_pkcs15_card *p15card, const u8 * buf, size_t buflen)
463
107
{
464
107
  struct sc_context *ctx = p15card->card->ctx;
465
107
  struct sc_asn1_entry asn1_ddo[7];
466
107
  sc_path_t odf_path, ti_path, us_path;
467
107
  struct sc_iid iid;
468
107
  struct sc_aid aid;
469
107
  int r;
470
471
107
  LOG_FUNC_CALLED(ctx);
472
473
107
  iid.len = sizeof(iid.value);
474
107
  aid.len = sizeof(aid.value);
475
476
107
  sc_copy_asn1_entry(c_asn1_ddo, asn1_ddo);
477
107
  sc_format_asn1_entry(asn1_ddo + 1, &odf_path, NULL, 0);
478
107
  sc_format_asn1_entry(asn1_ddo + 2, &ti_path, NULL, 0);
479
107
  sc_format_asn1_entry(asn1_ddo + 3, &us_path, NULL, 0);
480
107
  sc_format_asn1_entry(asn1_ddo + 4, iid.value, &iid.len, 0);
481
107
  sc_format_asn1_entry(asn1_ddo + 5, aid.value, &aid.len, 0);
482
483
107
  r = sc_asn1_decode(ctx, asn1_ddo, buf, buflen, NULL, NULL);
484
107
  LOG_TEST_RET(ctx, r, "DDO parsing failed");
485
486
96
  if (asn1_ddo[1].flags & SC_ASN1_PRESENT) {
487
63
    sc_file_free(p15card->file_odf);
488
63
    p15card->file_odf = sc_file_new();
489
63
    if (p15card->file_odf == NULL)
490
0
      goto mem_err;
491
63
    p15card->file_odf->path = odf_path;
492
63
  }
493
96
  if (asn1_ddo[2].flags & SC_ASN1_PRESENT) {
494
5
    sc_file_free(p15card->file_tokeninfo);
495
5
    p15card->file_tokeninfo = sc_file_new();
496
5
    if (p15card->file_tokeninfo == NULL)
497
0
      goto mem_err;
498
5
    p15card->file_tokeninfo->path = ti_path;
499
5
  }
500
96
  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
96
  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
96
  if (asn1_ddo[5].flags & SC_ASN1_PRESENT) {
512
7
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "DDO.AID '%s'", sc_dump_hex(aid.value, aid.len));
513
7
    memcpy(&p15card->app->ddo.aid, &aid, sizeof(struct sc_aid));
514
7
  }
515
516
96
  fix_authentic_ddo(p15card);
517
96
  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
1.79k
{
532
1.79k
  struct sc_context *ctx  = p15card->card->ctx;
533
1.79k
  struct sc_file *file = NULL;
534
1.79k
  struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE];
535
1.79k
  unsigned char *content, last_update[32] = {0};
536
1.79k
  size_t lupdate_len = sizeof(last_update) - 1;
537
1.79k
  int r, content_len;
538
1.79k
  size_t size;
539
540
1.79k
  if (p15card->tokeninfo->last_update.gtime)
541
3
    goto done;
542
543
1.79k
  if (!p15card->tokeninfo->last_update.path.len)
544
1.76k
    return NULL;
545
546
26
  r = sc_select_file(p15card->card, &p15card->tokeninfo->last_update.path, &file);
547
26
  if (r < 0)
548
15
    return NULL;
549
550
11
  size = file->size ? file->size : 1024;
551
11
  sc_file_free(file);
552
553
11
  content = calloc(1, size);
554
11
  if (!content)
555
0
    return NULL;
556
557
11
  r = sc_read_binary(p15card->card, 0, content, size, 0);
558
11
  if (r < 0) {
559
5
    free(content);
560
5
    return NULL;
561
5
  }
562
6
  content_len = r;
563
564
6
  sc_copy_asn1_entry(c_asn1_last_update, asn1_last_update);
565
6
  sc_format_asn1_entry(asn1_last_update + 0, last_update, &lupdate_len, 0);
566
567
6
  r = sc_asn1_decode(ctx, asn1_last_update, content, content_len, NULL, NULL);
568
6
  free(content);
569
6
  if (r < 0)
570
1
    return NULL;
571
572
5
  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
8
done:
578
8
  sc_log(ctx, "lastUpdate.gtime '%s'", p15card->tokeninfo->last_update.gtime);
579
8
  return p15card->tokeninfo->last_update.gtime;
580
5
}
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
402
{
612
402
  const unsigned char *p = buf;
613
402
  size_t left = buflen;
614
402
  int r, i, type;
615
402
  struct sc_path path;
616
402
  struct sc_asn1_entry asn1_obj_or_path[] = {
617
402
    { "path", SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_SEQUENCE, 0, &path, NULL },
618
402
    { NULL, 0, 0, 0, NULL, NULL }
619
402
  };
620
402
  struct sc_asn1_entry asn1_odf[10];
621
622
402
  sc_copy_asn1_entry(c_asn1_odf, asn1_odf);
623
4.02k
  for (i = 0; asn1_odf[i].name != NULL; i++)
624
3.61k
    sc_format_asn1_entry(asn1_odf + i, asn1_obj_or_path, NULL, 0);
625
2.28k
  while (left > 0) {
626
2.19k
    r = sc_asn1_decode_choice(p15card->card->ctx, asn1_odf, p, left, &p, &left);
627
2.19k
    if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
628
171
      break;
629
2.02k
    if (r < 0)
630
140
      return r;
631
1.88k
    type = r;
632
1.88k
    if (p15card->file_app) {
633
1.88k
      r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &path);
634
1.88k
      if (r < 0)
635
0
        return r;
636
1.88k
      r = sc_pkcs15_add_df(p15card, odf_indexes[type], &path);
637
1.88k
      if (r)
638
0
        return r;
639
1.88k
    }
640
1.88k
  }
641
262
  return 0;
642
402
}
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
11.2k
{
710
11.2k
  struct sc_pkcs15_card *p15card;
711
712
11.2k
  p15card = calloc(1, sizeof(struct sc_pkcs15_card));
713
11.2k
  if (p15card == NULL)
714
0
    return NULL;
715
716
11.2k
  p15card->tokeninfo = calloc(1, sizeof(struct sc_pkcs15_tokeninfo));
717
11.2k
  if (p15card->tokeninfo == NULL) {
718
0
    free(p15card);
719
0
    return NULL;
720
0
  }
721
722
11.2k
  p15card->magic = SC_PKCS15_CARD_MAGIC;
723
11.2k
  return p15card;
724
11.2k
}
725
726
727
struct sc_pkcs15_tokeninfo *
728
sc_pkcs15_tokeninfo_new(void)
729
8.14k
{
730
8.14k
  struct sc_pkcs15_tokeninfo *tokeninfo;
731
732
8.14k
  tokeninfo = calloc(1, sizeof(struct sc_pkcs15_tokeninfo));
733
8.14k
  if (tokeninfo == NULL) {
734
0
    return NULL;
735
0
  }
736
737
8.14k
  sc_init_oid(&tokeninfo->profile_indication.oid);
738
739
8.14k
  return tokeninfo;
740
8.14k
}
741
742
static void
743
sc_pkcs15_clear_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo)
744
19.8k
{
745
19.8k
  if (!tokeninfo)
746
0
    return;
747
748
19.8k
  free(tokeninfo->label);
749
19.8k
  tokeninfo->label = NULL;
750
19.8k
  free(tokeninfo->serial_number);
751
19.8k
  tokeninfo->serial_number = NULL;
752
19.8k
  free(tokeninfo->manufacturer_id);
753
19.8k
  tokeninfo->manufacturer_id = NULL;
754
19.8k
  free(tokeninfo->last_update.gtime);
755
19.8k
  tokeninfo->last_update.gtime = NULL;
756
19.8k
  free(tokeninfo->preferred_language);
757
19.8k
  tokeninfo->preferred_language = NULL;
758
19.8k
  free(tokeninfo->profile_indication.name);
759
19.8k
  tokeninfo->profile_indication.name = NULL;
760
19.8k
  if (tokeninfo->seInfo != NULL) {
761
38
    unsigned i;
762
41
    for (i = 0; i < tokeninfo->num_seInfo; i++)
763
3
      free(tokeninfo->seInfo[i]);
764
38
    free(tokeninfo->seInfo);
765
38
    tokeninfo->seInfo = NULL;
766
38
  }
767
19.8k
}
768
769
void
770
sc_pkcs15_free_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo)
771
19.9k
{
772
19.9k
  if (!tokeninfo)
773
584
    return;
774
775
19.4k
  sc_pkcs15_clear_tokeninfo(tokeninfo);
776
19.4k
  free(tokeninfo);
777
19.4k
}
778
779
void
780
sc_pkcs15_free_app(struct sc_pkcs15_card *p15card)
781
37.5k
{
782
37.5k
  if (p15card && p15card->app) {
783
656
    free(p15card->app->label);
784
656
    free(p15card->app->ddo.value);
785
656
    free(p15card->app);
786
656
    p15card->app = NULL;
787
656
  }
788
37.5k
}
789
790
791
void
792
sc_pkcs15_card_free(struct sc_pkcs15_card *p15card)
793
21.8k
{
794
21.8k
  if (p15card == NULL || p15card->magic != SC_PKCS15_CARD_MAGIC)
795
10.6k
    return;
796
797
11.2k
  if (p15card->ops.clear)
798
731
    p15card->ops.clear(p15card);
799
800
  /* For more complicated MD data a dedicated release procedure
801
   * has to be implemented. */
802
11.2k
  if (p15card->md_data)
803
0
    free(p15card->md_data);
804
805
11.2k
  sc_pkcs15_free_app(p15card);
806
11.2k
  sc_pkcs15_remove_objects(p15card);
807
11.2k
  sc_pkcs15_remove_dfs(p15card);
808
11.2k
  sc_pkcs15_free_unusedspace(p15card);
809
11.2k
  p15card->unusedspace_read = 0;
810
811
11.2k
  sc_file_free(p15card->file_app);
812
11.2k
  sc_file_free(p15card->file_tokeninfo);
813
11.2k
  sc_file_free(p15card->file_odf);
814
11.2k
  sc_file_free(p15card->file_unusedspace);
815
816
11.2k
  p15card->magic = 0;
817
11.2k
  sc_pkcs15_free_tokeninfo(p15card->tokeninfo);
818
11.2k
  sc_pkcs15_free_app(p15card);
819
11.2k
  free(p15card);
820
11.2k
}
821
822
823
void
824
sc_pkcs15_card_clear(struct sc_pkcs15_card *p15card)
825
14.5k
{
826
14.5k
  if (p15card == NULL)
827
0
    return;
828
829
14.5k
  if (p15card->ops.clear)
830
698
    p15card->ops.clear(p15card);
831
832
14.5k
  p15card->flags = 0;
833
14.5k
  p15card->tokeninfo->version = 0;
834
14.5k
  p15card->tokeninfo->flags   = 0;
835
836
14.5k
  sc_pkcs15_remove_objects(p15card);
837
14.5k
  sc_pkcs15_remove_dfs(p15card);
838
839
14.5k
  p15card->df_list = NULL;
840
14.5k
  sc_file_free(p15card->file_app);
841
14.5k
  p15card->file_app = NULL;
842
14.5k
  sc_file_free(p15card->file_tokeninfo);
843
14.5k
  p15card->file_tokeninfo = NULL;
844
14.5k
  sc_file_free(p15card->file_odf);
845
14.5k
  p15card->file_odf = NULL;
846
14.5k
  sc_file_free(p15card->file_unusedspace);
847
14.5k
  p15card->file_unusedspace = NULL;
848
849
14.5k
  free(p15card->tokeninfo->label);
850
14.5k
  p15card->tokeninfo->label = NULL;
851
14.5k
  free(p15card->tokeninfo->serial_number);
852
14.5k
  p15card->tokeninfo->serial_number = NULL;
853
14.5k
  free(p15card->tokeninfo->manufacturer_id);
854
14.5k
  p15card->tokeninfo->manufacturer_id = NULL;
855
14.5k
  free(p15card->tokeninfo->last_update.gtime);
856
14.5k
  p15card->tokeninfo->last_update.gtime = NULL;
857
14.5k
  free(p15card->tokeninfo->preferred_language);
858
14.5k
  p15card->tokeninfo->preferred_language = NULL;
859
14.5k
  free(p15card->tokeninfo->profile_indication.name);
860
14.5k
  p15card->tokeninfo->profile_indication.name = NULL;
861
14.5k
  if (p15card->tokeninfo->seInfo != NULL) {
862
30
    size_t i;
863
31
    for (i = 0; i < p15card->tokeninfo->num_seInfo; i++)
864
1
      free(p15card->tokeninfo->seInfo[i]);
865
30
    free(p15card->tokeninfo->seInfo);
866
30
    p15card->tokeninfo->seInfo     = NULL;
867
30
    p15card->tokeninfo->num_seInfo = 0;
868
30
  }
869
870
14.5k
  sc_pkcs15_free_app(p15card);
871
14.5k
}
872
873
874
struct sc_app_info *
875
sc_find_app(struct sc_card *card, struct sc_aid *aid)
876
11.7k
{
877
11.7k
  int ii;
878
879
11.7k
  if (card->app_count <= 0)
880
11.2k
    return NULL;
881
882
503
  if (!aid || !aid->len)
883
503
    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
503
{
899
503
  struct sc_app_info *out = calloc(1, sizeof(struct sc_app_info));
900
901
503
  if (!out)
902
0
    return NULL;
903
904
503
  memcpy(out, info, sizeof(struct sc_app_info));
905
906
503
  if (info->label) {
907
6
    out->label = strdup(info->label);
908
6
    if (!out->label) {
909
0
      free(out);
910
0
      return NULL;
911
0
    }
912
6
  } else
913
497
    out->label = NULL;
914
915
503
  out->ddo.value = malloc(info->ddo.len);
916
503
  if (!out->ddo.value) {
917
0
    free(out->label);
918
0
    free(out);
919
0
    return NULL;
920
0
  }
921
503
  memcpy(out->ddo.value, info->ddo.value, info->ddo.len);
922
503
  out->ddo.len = info->ddo.len;
923
924
503
  return out;
925
503
}
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
11.7k
{
975
11.7k
  struct sc_path tmppath;
976
11.7k
  struct sc_card    *card = p15card->card;
977
11.7k
  struct sc_context *ctx  = card->ctx;
978
11.7k
  struct sc_pkcs15_tokeninfo tokeninfo;
979
11.7k
  struct sc_pkcs15_df *df;
980
11.7k
  const struct sc_app_info *info = NULL;
981
11.7k
  unsigned char *buf = NULL;
982
11.7k
  size_t len;
983
11.7k
  int    err, ok = 0;
984
985
11.7k
  LOG_FUNC_CALLED(ctx);
986
  /* Enumerate apps now */
987
11.7k
  if (card->app_count < 0) {
988
10.8k
    err = sc_enum_apps(card);
989
10.8k
    if (err != SC_SUCCESS)
990
10.4k
      sc_log(ctx, "unable to enumerate apps: %s", sc_strerror(err));
991
10.8k
  }
992
11.7k
  sc_file_free(p15card->file_app);
993
11.7k
  p15card->file_app = sc_file_new();
994
11.7k
  if (p15card->file_app == NULL) {
995
0
    err = SC_ERROR_OUT_OF_MEMORY;
996
0
    goto end;
997
0
  }
998
999
11.7k
  sc_format_path("3F005015", &p15card->file_app->path);
1000
1001
11.7k
  info = sc_find_app(card, aid);
1002
11.7k
  if (info)   {
1003
503
    sc_log(ctx, "bind to application('%s',aid:'%s')", info->label, sc_dump_hex(info->aid.value, info->aid.len));
1004
503
    sc_pkcs15_free_app(p15card);
1005
503
    p15card->app = sc_dup_app_info(info);
1006
503
    if (!p15card->app)   {
1007
0
      err = SC_ERROR_OUT_OF_MEMORY;
1008
0
      goto end;
1009
0
    }
1010
1011
503
    if (info->path.len)
1012
477
      p15card->file_app->path = info->path;
1013
1014
503
    if (info->ddo.value && info->ddo.len)
1015
107
      parse_ddo(p15card, info->ddo.value, info->ddo.len);
1016
1017
503
  }
1018
11.2k
  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
11.7k
  sc_log(ctx, "application path '%s'", sc_print_path(&p15card->file_app->path));
1024
1025
  /* Check if pkcs15 directory exists */
1026
11.7k
  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
11.7k
  if ((err != SC_SUCCESS) && (card->app_count < 1)) {
1032
9.38k
    sc_format_path("3F00", &p15card->file_app->path);
1033
9.38k
    err = SC_SUCCESS;
1034
9.38k
  }
1035
1036
11.7k
  if (err < 0)   {
1037
361
    sc_log (ctx, "Cannot select application path");
1038
361
    goto end;
1039
361
  }
1040
1041
11.3k
  if (p15card->file_odf == NULL) {
1042
    /* check if an ODF is present; we don't know yet whether we have a pkcs15 card */
1043
11.3k
    sc_format_path("5031", &tmppath);
1044
11.3k
    err = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &tmppath);
1045
11.3k
    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
11.3k
    sc_log(ctx, "absolute path to EF(ODF) %s", sc_print_path(&tmppath));
1050
11.3k
    err = sc_select_file(card, &tmppath, &p15card->file_odf);
1051
11.3k
  }
1052
59
  else {
1053
59
    tmppath = p15card->file_odf->path;
1054
59
    sc_file_free(p15card->file_odf);
1055
59
    p15card->file_odf = NULL;
1056
59
    err = sc_select_file(card, &tmppath, &p15card->file_odf);
1057
59
  }
1058
1059
11.3k
  if (err != SC_SUCCESS) {
1060
10.3k
    sc_log(ctx, "EF(ODF) not found in '%s'", sc_print_path(&tmppath));
1061
10.3k
    goto end;
1062
10.3k
  }
1063
1064
990
  len = p15card->file_odf->size;
1065
990
  if (!len) {
1066
202
    sc_log(ctx, "EF(ODF) is empty");
1067
202
    goto end;
1068
202
  }
1069
788
  if (len > MAX_FILE_SIZE) {
1070
28
    sc_log(ctx, "EF(ODF) too large");
1071
28
    goto end;
1072
28
  }
1073
760
  buf = malloc(len);
1074
760
  if(buf == NULL) {
1075
0
    err = SC_ERROR_OUT_OF_MEMORY;
1076
0
    goto end;
1077
0
  }
1078
1079
760
  err = -1; /* file state: not in cache */
1080
760
  if (p15card->opts.use_file_cache) {
1081
212
    err = sc_pkcs15_read_cached_file(p15card, &tmppath, &buf, &len);
1082
212
    if (err == SC_SUCCESS)
1083
0
      err = (int)len;
1084
212
  }
1085
760
  if (err < 0) {
1086
760
    err = sc_read_binary(card, 0, buf, len, 0);
1087
760
    if (err < 2) {
1088
358
      if (err < 0) {
1089
317
        sc_log(ctx, "read EF(ODF) file error: %s", sc_strerror(err));
1090
317
      } else {
1091
41
        err = SC_ERROR_PKCS15_APP_NOT_FOUND;
1092
41
        sc_log(ctx, "Invalid content of EF(ODF): %s", sc_strerror(err));
1093
41
      }
1094
358
      goto end;
1095
358
    }
1096
    /* sc_read_binary may return less than requested */
1097
402
    len = err;
1098
1099
402
    if (p15card->opts.use_file_cache) {
1100
94
      sc_pkcs15_cache_file(p15card, &tmppath, buf, len);
1101
94
    }
1102
402
  }
1103
1104
402
  if (parse_odf(buf, len, p15card)) {
1105
140
    err = SC_ERROR_PKCS15_APP_NOT_FOUND;
1106
140
    sc_log(ctx, "Unable to parse ODF");
1107
140
    goto end;
1108
140
  }
1109
262
  free(buf);
1110
262
  buf = NULL;
1111
1112
262
  sc_log(ctx, "The following DFs were found:");
1113
1.99k
  for (df = p15card->df_list; df; df = df->next)
1114
1.73k
    sc_log(ctx, "  DF type %u, path %s, index %u, count %d", df->type,
1115
262
        sc_print_path(&df->path), df->path.index, df->path.count);
1116
1117
262
  if (p15card->file_tokeninfo == NULL) {
1118
260
    sc_format_path("5032", &tmppath);
1119
260
    err = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &tmppath);
1120
260
    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
260
    sc_log(ctx, "absolute path to EF(TokenInfo) %s", sc_print_path(&tmppath));
1125
260
  }
1126
2
  else {
1127
2
    tmppath = p15card->file_tokeninfo->path;
1128
2
    sc_file_free(p15card->file_tokeninfo);
1129
2
    p15card->file_tokeninfo = NULL;
1130
2
  }
1131
1132
262
  err = sc_select_file(card, &tmppath, &p15card->file_tokeninfo);
1133
262
  if (err)   {
1134
171
    sc_log(ctx, "cannot select EF(TokenInfo) file: %s", sc_strerror(err));
1135
171
    goto end;
1136
171
  }
1137
1138
91
  len = p15card->file_tokeninfo->size;
1139
91
  if (!len) {
1140
4
    sc_log(ctx, "EF(TokenInfo) is empty");
1141
4
    goto end;
1142
4
  }
1143
87
  if (len > MAX_FILE_SIZE) {
1144
23
    sc_log(ctx, "EF(TokenInfo) too large");
1145
23
    goto end;
1146
23
  }
1147
64
  buf = malloc(len);
1148
64
  if(buf == NULL) {
1149
0
    err = SC_ERROR_OUT_OF_MEMORY;
1150
0
    goto end;
1151
0
  }
1152
1153
64
  err = -1; /* file state: not in cache */
1154
64
  if (p15card->opts.use_file_cache) {
1155
18
    err = sc_pkcs15_read_cached_file(p15card, &tmppath, &buf, &len);
1156
18
    if (err == SC_SUCCESS)
1157
0
      err = (int)len;
1158
18
  }
1159
64
  if (err < 0) {
1160
64
    err = sc_read_binary(card, 0, buf, len, 0);
1161
64
    if (err <= 2) {
1162
34
      if (err < 0)   {
1163
30
        sc_log(ctx, "read EF(TokenInfo) file error: %s", sc_strerror(err));
1164
30
      } else {
1165
4
        err = SC_ERROR_PKCS15_APP_NOT_FOUND;
1166
4
        sc_log(ctx, "Invalid content of EF(TokenInfo): %s", sc_strerror(err));
1167
4
      }
1168
34
      goto end;
1169
34
    }
1170
    /* sc_read_binary may return less than requested */
1171
30
    len = err;
1172
1173
30
    if (p15card->opts.use_file_cache) {
1174
4
      sc_pkcs15_cache_file(p15card, &tmppath, buf, len);
1175
4
    }
1176
30
  }
1177
1178
30
  memset(&tokeninfo, 0, sizeof(tokeninfo));
1179
30
  err = sc_pkcs15_parse_tokeninfo(ctx, &tokeninfo, buf, (size_t)err);
1180
30
  if (err != SC_SUCCESS)   {
1181
26
    sc_log(ctx, "cannot parse TokenInfo content: %s", sc_strerror(err));
1182
26
    goto end;
1183
26
  }
1184
1185
4
  sc_pkcs15_clear_tokeninfo(p15card->tokeninfo);
1186
4
  *(p15card->tokeninfo) = tokeninfo;
1187
1188
4
  if (!p15card->tokeninfo->serial_number && 0 == card->serialnr.len) {
1189
2
    sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &card->serialnr);
1190
2
  }
1191
1192
4
  if (!p15card->tokeninfo->serial_number && card->serialnr.len)   {
1193
1
    char *serial = calloc(1, card->serialnr.len*2 + 1);
1194
1
    size_t ii;
1195
1
    if (!serial) {
1196
0
      err = SC_ERROR_OUT_OF_MEMORY;
1197
0
      goto end;
1198
0
    }
1199
1200
5
    for(ii=0;ii<card->serialnr.len;ii++)
1201
4
      sprintf(serial + ii*2, "%02X", *(card->serialnr.value + ii));
1202
1203
1
    p15card->tokeninfo->serial_number = serial;
1204
1
    sc_log(ctx, "p15card->tokeninfo->serial_number %s", p15card->tokeninfo->serial_number);
1205
1
  }
1206
1207
4
  ok = 1;
1208
11.7k
end:
1209
11.7k
  if(buf != NULL)
1210
562
    free(buf);
1211
11.7k
  if (!ok) {
1212
11.7k
    sc_pkcs15_card_clear(p15card);
1213
11.7k
    if (err == SC_ERROR_FILE_NOT_FOUND)
1214
1.44k
      err = SC_ERROR_WRONG_CARD;
1215
11.7k
    LOG_FUNC_RETURN(ctx, err);
1216
11.7k
  }
1217
1218
4
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1219
4
}
1220
1221
1222
const char *pkcs15_get_default_use_file_cache(struct sc_card *card)
1223
11.2k
{
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
11.2k
  const char *card_drivers_with_file_cache[] = {
1230
11.2k
      "atrust-acos",
1231
11.2k
      "belpic",
1232
11.2k
      "cac1",
1233
11.2k
      "cac",
1234
11.2k
      "coolkey",
1235
11.2k
      "edo",
1236
11.2k
      "esteid2018",
1237
11.2k
      "esteid2025",
1238
11.2k
      "flex",
1239
11.2k
      "cyberflex",
1240
11.2k
      "gemsafeV1",
1241
11.2k
      "idprime",
1242
11.2k
      "itacns",
1243
11.2k
      "jpki",
1244
11.2k
      "MaskTech",
1245
11.2k
      "mcrd",
1246
11.2k
      "myeid",
1247
11.2k
      "npa",
1248
11.2k
      "nqapplet",
1249
11.2k
      "tcos",
1250
11.2k
      "dtrust",
1251
11.2k
  };
1252
1253
11.2k
  if (NULL == card || NULL == card->driver || NULL == card->driver->short_name)
1254
0
    return "no";
1255
195k
  for (size_t i = 0; i < (sizeof card_drivers_with_file_cache / sizeof *card_drivers_with_file_cache); i++) {
1256
188k
    if (0 == strcmp(card->driver->short_name, card_drivers_with_file_cache[i]))
1257
4.65k
      return "public";
1258
188k
  }
1259
1260
6.60k
  return "no";
1261
11.2k
}
1262
1263
int
1264
sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid,
1265
    struct sc_pkcs15_card **p15card_out)
1266
11.2k
{
1267
11.2k
  struct sc_pkcs15_card *p15card = NULL;
1268
11.2k
  struct sc_context *ctx;
1269
11.2k
  scconf_block *conf_block = NULL;
1270
11.2k
  int r, emu_first, enable_emu;
1271
11.2k
  const char *use_file_cache;
1272
11.2k
  const char *pin_protected_certificate, *private_certificate;
1273
1274
11.2k
  if (card == NULL || p15card_out == NULL) {
1275
0
    return SC_ERROR_INVALID_ARGUMENTS;
1276
0
  }
1277
11.2k
  ctx = card->ctx;
1278
1279
11.2k
  LOG_FUNC_CALLED(ctx);
1280
11.2k
  sc_log(ctx, "application(aid:'%s')", aid ? sc_dump_hex(aid->value, aid->len) : "empty");
1281
1282
11.2k
  p15card = sc_pkcs15_card_new();
1283
11.2k
  if (p15card == NULL)
1284
11.2k
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1285
1286
11.2k
  p15card->card = card;
1287
11.2k
  p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_NO_FILES;
1288
11.2k
  use_file_cache = pkcs15_get_default_use_file_cache(card);
1289
11.2k
  p15card->opts.use_pin_cache = 1;
1290
11.2k
  p15card->opts.pin_cache_counter = 10;
1291
11.2k
  p15card->opts.pin_cache_ignore_user_consent = 0;
1292
11.2k
  pin_protected_certificate = "protect";
1293
11.2k
  private_certificate = "";
1294
1295
11.2k
  conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);
1296
11.2k
  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
11.2k
  if (0 == strcmp(use_file_cache, "yes")) {
1308
0
    p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_ALL_FILES;
1309
11.2k
  } else if (0 == strcmp(use_file_cache, "public")) {
1310
4.65k
    p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_PUBLIC_FILES;
1311
6.60k
  } else if (0 == strcmp(use_file_cache, "no")) {
1312
6.60k
    p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_NO_FILES;
1313
6.60k
  }
1314
1315
11.2k
  if (0 == strcmp(pin_protected_certificate, "protect")) {
1316
11.2k
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT;
1317
11.2k
  } 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
11.2k
  if (0 == strcmp(private_certificate, "protect")) {
1324
0
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT;
1325
11.2k
  } else if (0 == strcmp(private_certificate, "ignore")) {
1326
0
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE;
1327
11.2k
  } else if (0 == strcmp(private_certificate, "declassify")) {
1328
0
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY;
1329
0
  }
1330
11.2k
  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
11.2k
      p15card->opts.use_file_cache, p15card->opts.use_pin_cache, p15card->opts.pin_cache_counter,
1332
11.2k
      p15card->opts.pin_cache_ignore_user_consent, p15card->opts.pin_protected_certificate);
1333
1334
11.2k
  r = sc_lock(card);
1335
11.2k
  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
11.2k
  enable_emu = scconf_get_bool(conf_block, "enable_pkcs15_emulation", 1);
1342
11.2k
  if (enable_emu) {
1343
11.2k
    sc_log(ctx, "PKCS#15 emulation enabled");
1344
11.2k
    emu_first = scconf_get_bool(conf_block, "try_emulation_first", 0);
1345
11.2k
    if (emu_first || sc_pkcs15_is_emulation_only(card)) {
1346
2.01k
      r = sc_pkcs15_bind_synthetic(p15card, aid);
1347
2.01k
      if (r == SC_SUCCESS)
1348
433
        goto done;
1349
1.57k
      r = sc_pkcs15_bind_internal(p15card, aid);
1350
1.57k
      if (r < 0)
1351
1.56k
        goto error;
1352
9.24k
    } else {
1353
9.24k
      r = sc_pkcs15_bind_internal(p15card, aid);
1354
9.24k
      if (r == SC_SUCCESS)
1355
229
        goto done;
1356
9.01k
      r = sc_pkcs15_bind_synthetic(p15card, aid);
1357
9.01k
      if (r < 0)
1358
5.78k
        goto error;
1359
9.01k
    }
1360
11.2k
  }
1361
0
  else {
1362
0
    r = sc_pkcs15_bind_internal(p15card, aid);
1363
0
    if (r < 0)
1364
0
      goto error;
1365
0
  }
1366
3.90k
done:
1367
3.90k
  *p15card_out = p15card;
1368
3.90k
  sc_unlock(card);
1369
3.90k
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1370
7.35k
error:
1371
7.35k
  sc_unlock(card);
1372
7.35k
  sc_pkcs15_card_free(p15card);
1373
7.35k
  LOG_FUNC_RETURN(ctx, r);
1374
7.35k
}
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
2.12k
{
1398
2.12k
  struct sc_pkcs15_object *obj = NULL;
1399
2.12k
  struct sc_pkcs15_df *df = NULL;
1400
2.12k
  unsigned int  df_mask = 0;
1401
2.12k
  size_t    match_count = 0;
1402
2.12k
  int r;
1403
1404
2.12k
  if (type)
1405
2.12k
    class_mask |= SC_PKCS15_TYPE_TO_CLASS(type);
1406
1407
  /* Make sure the class mask we have makes sense */
1408
2.12k
  if (class_mask == 0
1409
2.12k
      || (class_mask & ~(
1410
2.12k
          SC_PKCS15_SEARCH_CLASS_PRKEY |
1411
2.12k
          SC_PKCS15_SEARCH_CLASS_PUBKEY |
1412
2.12k
          SC_PKCS15_SEARCH_CLASS_SKEY |
1413
2.12k
          SC_PKCS15_SEARCH_CLASS_CERT |
1414
2.12k
          SC_PKCS15_SEARCH_CLASS_DATA |
1415
2.12k
          SC_PKCS15_SEARCH_CLASS_AUTH))) {
1416
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1417
0
  }
1418
1419
2.12k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_PRKEY)
1420
624
    df_mask |= (1 << SC_PKCS15_PRKDF);
1421
2.12k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_PUBKEY)
1422
0
    df_mask |= (1 << SC_PKCS15_PUKDF) | (1 << SC_PKCS15_PUKDF_TRUSTED);
1423
2.12k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_CERT)
1424
1.27k
    df_mask |= (1 << SC_PKCS15_CDF) | (1 << SC_PKCS15_CDF_TRUSTED) | (1 << SC_PKCS15_CDF_USEFUL);
1425
2.12k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_DATA)
1426
219
    df_mask |= (1 << SC_PKCS15_DODF);
1427
2.12k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_AUTH)
1428
3
    df_mask |= (1 << SC_PKCS15_AODF);
1429
2.12k
  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.15k
  for (df = p15card->df_list; df != NULL; df = df->next) {
1435
5.03k
    if (!(df_mask & (1 << df->type)))   {
1436
4.10k
      continue;
1437
4.10k
    }
1438
926
    if (df->enumerated)
1439
926
      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
24.6k
  for (obj = p15card->obj_list; obj != NULL; obj = obj->next) {
1451
    /* Check object type */
1452
22.9k
    if (!(class_mask & SC_PKCS15_TYPE_TO_CLASS(obj->type)))
1453
18.6k
      continue;
1454
4.31k
    if (type != 0
1455
4.31k
     && obj->type != type
1456
2.10k
     && (obj->type & SC_PKCS15_TYPE_CLASS_MASK) != type)
1457
0
      continue;
1458
1459
    /* Potential candidate, apply search function */
1460
4.31k
    if (func != NULL && func(obj, func_arg) <= 0)
1461
1.69k
      continue;
1462
    /* Okay, we have a match. */
1463
2.62k
    match_count++;
1464
2.62k
    if (!ret || ret_size <= 0)
1465
0
      continue;
1466
2.62k
    ret[match_count-1] = obj;
1467
2.62k
    if (ret_size <= match_count)
1468
412
      break;
1469
2.62k
  }
1470
1471
2.12k
  return (int)match_count;
1472
2.12k
}
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
221
{
1479
221
  return sc_pkcs15_get_objects_cond(p15card, type, NULL, NULL, ret, ret_size);
1480
221
}
1481
1482
1483
static int
1484
compare_obj_id(struct sc_pkcs15_object *obj, const struct sc_pkcs15_id *id)
1485
2.10k
{
1486
2.10k
  void *data = obj->data;
1487
1488
2.10k
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
1489
799
  case SC_PKCS15_TYPE_CERT:
1490
799
    return sc_pkcs15_compare_id(&((struct sc_pkcs15_cert_info *) data)->id, id);
1491
1.30k
  case SC_PKCS15_TYPE_PRKEY:
1492
1.30k
    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
0
  case SC_PKCS15_TYPE_AUTH:
1498
0
    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
2.10k
  }
1502
0
  return 0;
1503
2.10k
}
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
2.10k
{
1618
2.10k
  struct sc_pkcs15_search_key *sk = (struct sc_pkcs15_search_key *) arg;
1619
1620
2.10k
  if (sk->id && !compare_obj_id(obj, sk->id))
1621
1.69k
    return 0;
1622
412
  if (sk->app_oid && !sc_obj_app_oid(obj, sk->app_oid))
1623
0
    return 0;
1624
412
  if (sk->usage_mask && !compare_obj_usage(obj, sk->usage_mask, sk->usage_value))
1625
0
    return 0;
1626
412
  if (sk->flags_mask && !compare_obj_flags(obj, sk->flags_mask, sk->flags_value))
1627
0
    return 0;
1628
412
  if (sk->match_reference && !compare_obj_reference(obj, sk->reference))
1629
0
    return 0;
1630
412
  if (sk->path && !compare_obj_path(obj, sk->path))
1631
0
    return 0;
1632
412
  if (
1633
412
    sk->app_label && sk->label &&
1634
0
    !compare_obj_data_name(obj, sk->app_label, sk->label)
1635
412
  ) {
1636
0
    return 0;
1637
0
  }
1638
1639
412
  return 1;
1640
412
}
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
2
{
1662
2
  return __sc_pkcs15_search_objects(p15card,
1663
2
      sk->class_mask, sk->type,
1664
2
      compare_obj_key, sk,
1665
2
      ret, ret_size);
1666
2
}
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
221
{
1674
221
  return __sc_pkcs15_search_objects(p15card, 0, type,
1675
221
      func, func_arg, ret, ret_size);
1676
221
}
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.90k
{
1683
1.90k
  struct sc_pkcs15_search_key sk;
1684
1.90k
  int r;
1685
1686
1.90k
  memset(&sk, 0, sizeof(sk));
1687
1.90k
  sk.id = id;
1688
1689
1.90k
  r = __sc_pkcs15_search_objects(p15card, 0, type, compare_obj_key, &sk, out, 1);
1690
1.90k
  if (r < 0)
1691
0
    return r;
1692
1.90k
  if (r == 0)
1693
1.49k
    return SC_ERROR_OBJECT_NOT_FOUND;
1694
412
  return 0;
1695
1.90k
}
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.27k
{
1702
1.27k
  return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_CERT, id, out);
1703
1.27k
}
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
623
{
1710
623
  return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_PRKEY, id, out);
1711
623
}
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
0
{
1734
0
  return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_AUTH, id, out);
1735
0
}
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
24.8k
{
1926
24.8k
  struct sc_pkcs15_object *p = p15card->obj_list;
1927
1928
24.8k
  if (!obj)
1929
0
    return 0;
1930
24.8k
  obj->next = obj->prev = NULL;
1931
24.8k
  if (p15card->obj_list == NULL) {
1932
3.47k
    p15card->obj_list = obj;
1933
3.47k
    return 0;
1934
3.47k
  }
1935
922k
  while (p->next != NULL)
1936
901k
    p = p->next;
1937
21.4k
  p->next = obj;
1938
21.4k
  obj->prev = p;
1939
1940
21.4k
  return 0;
1941
24.8k
}
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
25.7k
{
1961
25.7k
  struct sc_pkcs15_object *cur = NULL, *next = NULL;
1962
1963
25.7k
  if (!p15card || !p15card->obj_list)
1964
22.3k
    return;
1965
28.3k
  for (cur = p15card->obj_list; cur; cur = next)   {
1966
24.8k
    next = cur->next;
1967
24.8k
    sc_pkcs15_free_object(cur);
1968
24.8k
  }
1969
1970
3.47k
  p15card->obj_list = NULL;
1971
3.47k
}
1972
1973
1974
void
1975
sc_pkcs15_free_object(struct sc_pkcs15_object *obj)
1976
24.8k
{
1977
24.8k
  if (!obj)
1978
0
    return;
1979
24.8k
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
1980
1.70k
  case SC_PKCS15_TYPE_PRKEY:
1981
1.70k
    sc_pkcs15_free_prkey_info((sc_pkcs15_prkey_info_t *)obj->data);
1982
1.70k
    break;
1983
245
  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
245
    if (obj->emulated) {
1987
153
      sc_pkcs15_free_pubkey(obj->emulated);
1988
153
    }
1989
245
    sc_pkcs15_free_pubkey_info((sc_pkcs15_pubkey_info_t *)obj->data);
1990
245
    break;
1991
733
  case SC_PKCS15_TYPE_CERT:
1992
733
    sc_pkcs15_free_cert_info((sc_pkcs15_cert_info_t *)obj->data);
1993
733
    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
18.3k
  case SC_PKCS15_TYPE_DATA_OBJECT:
1998
18.3k
    sc_pkcs15_free_data_info((sc_pkcs15_data_info_t *)obj->data);
1999
18.3k
    break;
2000
3.81k
  case SC_PKCS15_TYPE_AUTH:
2001
3.81k
    sc_pkcs15_free_auth_info((sc_pkcs15_auth_info_t *)obj->data);
2002
3.81k
    break;
2003
0
  default:
2004
0
    free(obj->data);
2005
24.8k
  }
2006
2007
24.8k
  sc_pkcs15_free_object_content(obj);
2008
2009
24.8k
  free(obj);
2010
24.8k
}
2011
2012
2013
int
2014
sc_pkcs15_add_df(struct sc_pkcs15_card *p15card, unsigned int type, const sc_path_t *path)
2015
7.35k
{
2016
7.35k
  struct sc_pkcs15_df *p, *newdf;
2017
2018
7.35k
  newdf = calloc(1, sizeof(struct sc_pkcs15_df));
2019
7.35k
  if (newdf == NULL)
2020
0
    return SC_ERROR_OUT_OF_MEMORY;
2021
7.35k
  newdf->path = *path;
2022
7.35k
  newdf->type = type;
2023
2024
7.35k
  if (p15card->df_list == NULL) {
2025
3.60k
    p15card->df_list = newdf;
2026
3.60k
    return 0;
2027
3.60k
  }
2028
2029
3.75k
  p = p15card->df_list;
2030
75.3k
  while (p->next != NULL)
2031
71.6k
    p = p->next;
2032
3.75k
  p->next = newdf;
2033
3.75k
  newdf->prev = p;
2034
2035
3.75k
  return 0;
2036
7.35k
}
2037
2038
2039
static void
2040
sc_pkcs15_remove_dfs(struct sc_pkcs15_card *p15card)
2041
25.7k
{
2042
25.7k
  struct sc_pkcs15_df *cur = NULL, *next = NULL;
2043
2044
25.7k
  if (!p15card || !p15card->df_list)
2045
22.1k
    return;
2046
2047
10.9k
  for (cur = p15card->df_list; cur; cur = next)   {
2048
7.35k
    next = cur->next;
2049
7.35k
    free(cur);
2050
7.35k
  }
2051
2052
3.60k
  p15card->df_list = NULL;
2053
3.60k
}
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
258
{
2132
258
  struct sc_context *ctx = p15card->card->ctx;
2133
258
  unsigned char *buf;
2134
258
  const unsigned char *p;
2135
258
  size_t bufsize;
2136
258
  int r;
2137
258
  struct sc_pkcs15_object *obj = NULL;
2138
258
  int (* func)(struct sc_pkcs15_card *, struct sc_pkcs15_object *,
2139
258
         const u8 **nbuf, size_t *nbufsize) = NULL;
2140
2141
258
  sc_log(ctx, "called; path=%s, type=%d, enum=%d", sc_print_path(&df->path), df->type, df->enumerated);
2142
2143
258
  if (df->enumerated)
2144
258
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2145
2146
258
  switch (df->type) {
2147
96
  case SC_PKCS15_PRKDF:
2148
96
    func = sc_pkcs15_decode_prkdf_entry;
2149
96
    break;
2150
51
  case SC_PKCS15_PUKDF:
2151
51
    func = sc_pkcs15_decode_pukdf_entry;
2152
51
    break;
2153
0
  case SC_PKCS15_SKDF:
2154
0
    func = sc_pkcs15_decode_skdf_entry;
2155
0
    break;
2156
54
  case SC_PKCS15_CDF:
2157
54
  case SC_PKCS15_CDF_TRUSTED:
2158
54
  case SC_PKCS15_CDF_USEFUL:
2159
54
    func = sc_pkcs15_decode_cdf_entry;
2160
54
    break;
2161
0
  case SC_PKCS15_DODF:
2162
0
    func = sc_pkcs15_decode_dodf_entry;
2163
0
    break;
2164
57
  case SC_PKCS15_AODF:
2165
57
    func = sc_pkcs15_decode_aodf_entry;
2166
57
    break;
2167
258
  }
2168
258
  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
258
  r = sc_pkcs15_read_file(p15card, &df->path, &buf, &bufsize, 0);
2173
258
  LOG_TEST_RET(ctx, r, "pkcs15 read file failed");
2174
2175
100
  p = buf;
2176
100
  while (bufsize && *p != 0x00) {
2177
2178
92
    obj = calloc(1, sizeof(struct sc_pkcs15_object));
2179
92
    if (obj == NULL) {
2180
0
      r = SC_ERROR_OUT_OF_MEMORY;
2181
0
      goto ret;
2182
0
    }
2183
92
    r = func(p15card, obj, &p, &bufsize);
2184
92
    if (r) {
2185
92
      free(obj);
2186
92
      if (r == SC_ERROR_ASN1_END_OF_CONTENTS) {
2187
35
        r = 0;
2188
35
        break;
2189
35
      }
2190
57
      sc_log(ctx, "%s: Error decoding DF entry", sc_strerror(r));
2191
57
      goto ret;
2192
92
    }
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
43
  };
2208
2209
43
  if (r > 0)
2210
0
    r = 0;
2211
100
ret:
2212
100
  df->enumerated = 1;
2213
100
  free(buf);
2214
100
  LOG_FUNC_RETURN(ctx, r);
2215
100
}
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
3.90k
{
2222
3.90k
  struct sc_context *ctx = p15card->card->ctx;
2223
3.90k
  struct sc_pkcs15_unusedspace *p = p15card->unusedspace_list, *new_unusedspace;
2224
2225
3.90k
  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
3.90k
  new_unusedspace = calloc(1, sizeof(sc_pkcs15_unusedspace_t));
2237
3.90k
  if (new_unusedspace == NULL)
2238
0
    return SC_ERROR_OUT_OF_MEMORY;
2239
3.90k
  new_unusedspace->path = *path;
2240
3.90k
  if (auth_id != NULL)
2241
0
    new_unusedspace->auth_id = *auth_id;
2242
2243
3.90k
  if (p15card->unusedspace_list == NULL) {
2244
3.90k
    p15card->unusedspace_list = new_unusedspace;
2245
3.90k
    return 0;
2246
3.90k
  }
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
3.90k
}
2254
2255
2256
void
2257
sc_pkcs15_remove_unusedspace(struct sc_pkcs15_card *p15card, struct sc_pkcs15_unusedspace *unusedspace)
2258
3.90k
{
2259
3.90k
  if (!unusedspace)
2260
0
    return;
2261
2262
3.90k
  if (!unusedspace->prev)
2263
3.90k
    p15card->unusedspace_list = unusedspace->next;
2264
0
  else
2265
0
    unusedspace->prev->next = unusedspace->next;
2266
2267
3.90k
  if (unusedspace->next)
2268
0
    unusedspace->next->prev = unusedspace->prev;
2269
2270
3.90k
  free(unusedspace);
2271
3.90k
}
2272
2273
2274
static void
2275
sc_pkcs15_free_unusedspace(struct sc_pkcs15_card *p15card)
2276
11.2k
{
2277
11.2k
  struct sc_pkcs15_unusedspace *cur = NULL, *next = NULL;
2278
2279
11.2k
  if (!p15card || !p15card->unusedspace_list)
2280
11.2k
    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
3.90k
{
2294
3.90k
  struct sc_path dummy_path;
2295
3.90k
  static const struct sc_asn1_entry c_asn1_unusedspace[] = {
2296
3.90k
    { "UnusedSpace", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
2297
3.90k
    { NULL, 0, 0, 0, NULL, NULL }
2298
3.90k
  };
2299
3.90k
  static const struct sc_asn1_entry c_asn1_unusedspace_values[] = {
2300
3.90k
    { "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
2301
3.90k
    { "authId", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
2302
3.90k
    { NULL, 0, 0, 0, NULL, NULL }
2303
3.90k
  };
2304
3.90k
  struct sc_asn1_entry *asn1_unusedspace = NULL;
2305
3.90k
  struct sc_asn1_entry *asn1_values = NULL;
2306
3.90k
  int unusedspace_count = 0, r, c = 0;
2307
3.90k
  struct sc_pkcs15_unusedspace *unusedspace = NULL;
2308
2309
3.90k
  sc_format_path("3F00", &dummy_path);
2310
3.90k
  dummy_path.index = dummy_path.count = 0;
2311
2312
3.90k
  unusedspace = p15card->unusedspace_list;
2313
3.90k
  for ( ; unusedspace != NULL; unusedspace = unusedspace->next)
2314
0
    unusedspace_count++;
2315
3.90k
  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
3.90k
    r = sc_pkcs15_add_unusedspace(p15card, &dummy_path, NULL);
2319
3.90k
    if (r)
2320
0
      return r;
2321
3.90k
    unusedspace_count = 1;
2322
3.90k
  }
2323
2324
3.90k
  asn1_unusedspace = (struct sc_asn1_entry *)
2325
3.90k
    malloc(sizeof(struct sc_asn1_entry) * (unusedspace_count + 1));
2326
3.90k
  if (asn1_unusedspace == NULL) {
2327
0
    r = SC_ERROR_OUT_OF_MEMORY;
2328
0
    goto err;
2329
0
  }
2330
3.90k
  asn1_values = (struct sc_asn1_entry *)
2331
3.90k
    malloc(sizeof(struct sc_asn1_entry) * (unusedspace_count * 3));
2332
3.90k
  if (asn1_values == NULL) {
2333
0
    r = SC_ERROR_OUT_OF_MEMORY;
2334
0
    goto err;
2335
0
  }
2336
2337
7.80k
  for (unusedspace = p15card->unusedspace_list; unusedspace != NULL; unusedspace = unusedspace->next) {
2338
3.90k
    sc_copy_asn1_entry(c_asn1_unusedspace, asn1_unusedspace + c);
2339
3.90k
    sc_format_asn1_entry(asn1_unusedspace + c, asn1_values + 3*c, NULL, 1);
2340
3.90k
    sc_copy_asn1_entry(c_asn1_unusedspace_values, asn1_values + 3*c);
2341
3.90k
    sc_format_asn1_entry(asn1_values + 3*c, &unusedspace->path, NULL, 1);
2342
3.90k
    sc_format_asn1_entry(asn1_values + 3*c+1, &unusedspace->auth_id, NULL,
2343
3.90k
         unusedspace->auth_id.len > 0 ? 1 : 0);
2344
3.90k
    c++;
2345
3.90k
  }
2346
3.90k
  asn1_unusedspace[c].name = NULL;
2347
2348
3.90k
  r = sc_asn1_encode(ctx, asn1_unusedspace, buf, buflen);
2349
2350
3.90k
err:
2351
3.90k
  if (asn1_values != NULL)
2352
3.90k
    free(asn1_values);
2353
3.90k
  if (asn1_unusedspace != NULL)
2354
3.90k
    free(asn1_unusedspace);
2355
2356
  /* If we added the dummy entry, remove it now */
2357
3.90k
  if (unusedspace_count == 1 && sc_compare_path(&p15card->unusedspace_list->path, &dummy_path))
2358
3.90k
    sc_pkcs15_remove_unusedspace(p15card, p15card->unusedspace_list);
2359
2360
3.90k
  return r;
2361
3.90k
}
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
270
{
2417
270
  LOG_FUNC_CALLED(card->ctx);
2418
270
#ifdef ENABLE_ZLIB
2419
270
  int rv = SC_SUCCESS;
2420
270
  int method = 0;
2421
2422
270
  if (flags & SC_FILE_FLAG_COMPRESSED_GZIP) {
2423
0
    method = COMPRESSION_GZIP;
2424
270
  } else if (flags & SC_FILE_FLAG_COMPRESSED_ZLIB) {
2425
0
    method = COMPRESSION_ZLIB;
2426
270
  } else {
2427
270
    method = COMPRESSION_AUTO;
2428
270
  }
2429
2430
270
  rv = sc_decompress_alloc(out, outlen, buf, buflen, method);
2431
270
  if (rv != SC_SUCCESS) {
2432
258
    sc_log(card->ctx,  "Decompression failed: %d", rv);
2433
258
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
2434
258
  }
2435
12
  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
12
}
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
8.82k
{
2468
8.82k
  struct sc_context *ctx;
2469
8.82k
  struct sc_file *file = NULL;
2470
8.82k
  unsigned char *data = NULL;
2471
8.82k
  size_t  len = 0, offset = 0;
2472
8.82k
  int r;
2473
2474
8.82k
  if (p15card == NULL || p15card->card == NULL || in_path == NULL || buf == NULL) {
2475
0
    return SC_ERROR_INVALID_ARGUMENTS;
2476
0
  }
2477
8.82k
  ctx = p15card->card->ctx;
2478
2479
8.82k
  LOG_FUNC_CALLED(ctx);
2480
8.82k
  sc_log(ctx, "path=%s, index=%u, count=%d", sc_print_path(in_path), in_path->index, in_path->count);
2481
2482
8.82k
  r = -1; /* file state: not in cache */
2483
8.82k
  if (p15card->opts.use_file_cache
2484
4.79k
      && ((p15card->opts.use_file_cache & SC_PKCS15_OPTS_CACHE_ALL_FILES) || !private_data)) {
2485
4.76k
    r = sc_pkcs15_read_cached_file(p15card, in_path, &data, &len);
2486
2487
4.76k
    if (!r && in_path->aid.len > 0 && in_path->len >= 2)   {
2488
1
      struct sc_path parent = *in_path;
2489
2490
1
      parent.len -= 2;
2491
1
      parent.type = SC_PATH_TYPE_PATH;
2492
1
      r = sc_select_file(p15card->card, &parent, NULL);
2493
1
    }
2494
4.76k
  }
2495
2496
8.82k
  if (r) {
2497
8.63k
    r = sc_lock(p15card->card);
2498
8.63k
    if (r)
2499
0
      goto fail;
2500
8.63k
    r = sc_select_file(p15card->card, in_path, &file);
2501
8.63k
    if (r)
2502
6.55k
      goto fail_unlock;
2503
2504
    /* Handle the case where the ASN.1 Path object specified
2505
     * index and length values */
2506
2507
2.08k
    if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) {
2508
2509
      // in_path->index: record_no
2510
      // in_path->count: ignored!
2511
2512
62
      if(file->record_length > 0) {
2513
53
        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
53
        } else {
2517
53
          len = file->record_length;
2518
53
        }
2519
53
      } else {
2520
9
        len = MAX_FILE_SIZE;
2521
9
      }
2522
2523
62
      if ((in_path->index <= 0) || (in_path->index > (int)(file->record_count))) {
2524
22
        sc_log(ctx, "  record number out of bounds: %d", in_path->index);
2525
22
        r = SC_ERROR_RECORD_NOT_FOUND;
2526
22
        goto fail_unlock;
2527
22
      }
2528
2529
2.01k
    } else {
2530
2531
2.01k
      if (in_path->count < 0) {
2532
904
        if (file->size)
2533
755
          len = (file->size > MAX_FILE_SIZE)? MAX_FILE_SIZE:file->size;
2534
149
        else
2535
149
          len = 1024;
2536
904
        offset = 0;
2537
904
      }
2538
1.11k
      else {
2539
1.11k
        offset = in_path->index;
2540
1.11k
        len = in_path->count;
2541
        /* Make sure we're within proper bounds */
2542
1.11k
        if (offset >= file->size || offset + len > file->size) {
2543
12
          r = SC_ERROR_INVALID_ASN1_OBJECT;
2544
12
          goto fail_unlock;
2545
12
        }
2546
1.11k
      }
2547
2.01k
    }
2548
2549
2.04k
    free(data);
2550
2.04k
    data = malloc(len);
2551
2.04k
    if (data == NULL) {
2552
0
      r = SC_ERROR_OUT_OF_MEMORY;
2553
0
      goto fail_unlock;
2554
0
    }
2555
2556
2.04k
    if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE_TLV) {
2557
62
      unsigned int i;
2558
62
      size_t l, record_len;
2559
62
      unsigned char *head = data;
2560
2561
755
      for (i=1; ; i++) {
2562
755
        l = len - (head - data);
2563
755
        if (l > 256) {
2564
677
          l = 256;
2565
677
        }
2566
755
        r = sc_read_record(p15card->card, i, 0, head, l, SC_RECORD_BY_REC_NR);
2567
755
        if (r == SC_ERROR_RECORD_NOT_FOUND)
2568
1
          break;
2569
754
        if (r < 0) {
2570
50
          goto fail_unlock;
2571
50
        }
2572
704
        if (r < 2)
2573
10
          break;
2574
694
        record_len = head[1];
2575
694
        if (record_len != 0xff) {
2576
296
          memmove(head, head+2, r-2);
2577
296
          head += (r-2);
2578
296
        }
2579
398
        else {
2580
398
          if (r < 4)
2581
1
            break;
2582
397
          memmove(head, head+4, r-4);
2583
397
          head += (r-4);
2584
397
        }
2585
694
      }
2586
12
      len = head-data;
2587
12
    }
2588
1.98k
    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
8
        goto fail_unlock;
2592
8
      }
2593
      /* sc_read_record may return less than requested */
2594
32
      len = r;
2595
32
    }
2596
1.94k
    else {
2597
1.94k
      unsigned long flags = 0;
2598
1.94k
      r = sc_read_binary(p15card->card, (unsigned)offset, data, len, &flags);
2599
1.94k
      if (r < 0) {
2600
671
        goto fail_unlock;
2601
671
      }
2602
      /* sc_read_binary may return less than requested */
2603
1.27k
      len = r;
2604
2605
1.27k
      if (flags & SC_FILE_FLAG_COMPRESSED_AUTO
2606
1.00k
          || flags & SC_FILE_FLAG_COMPRESSED_ZLIB
2607
1.00k
          || flags & SC_FILE_FLAG_COMPRESSED_GZIP) {
2608
270
        unsigned char *decompressed_buf = NULL;
2609
270
        size_t decompressed_len = 0;
2610
270
        r = decompress_file(p15card->card, data, len, &decompressed_buf, &decompressed_len, flags);
2611
270
        if (r != SC_SUCCESS) {
2612
258
          goto fail_unlock;
2613
258
        }
2614
12
        free(data);
2615
12
        data = decompressed_buf;
2616
12
        len = decompressed_len;
2617
12
      }
2618
1.27k
    }
2619
1.05k
    sc_unlock(p15card->card);
2620
2621
1.05k
    sc_file_free(file);
2622
2623
1.05k
    if (len && p15card->opts.use_file_cache
2624
327
        && ((p15card->opts.use_file_cache & SC_PKCS15_OPTS_CACHE_ALL_FILES) || !private_data)) {
2625
324
      sc_pkcs15_cache_file(p15card, in_path, data, len);
2626
324
    }
2627
1.05k
    if (len == 0) {
2628
227
      free(data);
2629
227
      data = NULL;
2630
227
    }
2631
1.05k
  }
2632
1.24k
  *buf = data;
2633
1.24k
  *buflen = len;
2634
1.24k
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2635
2636
7.58k
fail_unlock:
2637
7.58k
  sc_unlock(p15card->card);
2638
7.58k
fail:
2639
7.58k
  free(data);
2640
7.58k
  sc_file_free(file);
2641
7.58k
  LOG_FUNC_RETURN(ctx, r);
2642
7.58k
}
2643
2644
2645
int
2646
sc_pkcs15_compare_id(const struct sc_pkcs15_id *id1, const struct sc_pkcs15_id *id2)
2647
2.10k
{
2648
2.10k
  if (id1 == NULL || id2 == NULL)
2649
0
    return 0;
2650
2.10k
  if (id1->len != id2->len)
2651
710
    return 0;
2652
1.39k
  return memcmp(id1->value, id2->value, id1->len) == 0;
2653
2.10k
}
2654
2655
2656
void
2657
sc_pkcs15_format_id(const char *str, struct sc_pkcs15_id *id)
2658
63.0k
{
2659
63.0k
  size_t len;
2660
2661
63.0k
  if (!id)
2662
0
    return;
2663
63.0k
  len = sizeof(id->value);
2664
2665
63.0k
  if (sc_hex_to_bin(str, id->value, &len) != SC_SUCCESS)
2666
0
    id->len = 0;
2667
63.0k
  else
2668
63.0k
    id->len = len;
2669
63.0k
}
2670
2671
2672
const char *
2673
sc_pkcs15_print_id(const struct sc_pkcs15_id *id)
2674
379
{
2675
379
  static char buffer[256];
2676
2677
379
  sc_bin_to_hex(id->value, id->len, buffer, sizeof(buffer), '\0');
2678
379
  return buffer;
2679
379
}
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
13.7k
{
2693
  /* nothing to do if child has valid 'aid' */
2694
13.7k
  if (child->aid.len)
2695
0
    return SC_SUCCESS;
2696
2697
13.7k
  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
13.7k
  else if (parent->type == SC_PATH_TYPE_DF_NAME)   {
2713
    /* child inherits parent's 'DF NAME' as 'aid' */
2714
88
    if (parent->len > sizeof(child->aid.value))
2715
0
      return SC_ERROR_WRONG_LENGTH;
2716
2717
88
    memcpy(child->aid.value, parent->value, parent->len);
2718
88
    child->aid.len = parent->len;
2719
2720
88
    return SC_SUCCESS;
2721
88
  }
2722
2723
  /* a 0 length path stays a 0 length path */
2724
13.6k
  if (child->len == 0)
2725
363
    return SC_SUCCESS;
2726
2727
13.2k
  if (sc_compare_path_prefix(sc_get_mf_path(), child))
2728
983
    return SC_SUCCESS;
2729
2730
12.3k
  return sc_concatenate_path(child, parent, child);
2731
13.2k
}
2732
2733
2734
void sc_pkcs15_free_object_content(struct sc_pkcs15_object *obj)
2735
24.8k
{
2736
24.8k
  if (obj->content.value && obj->content.len) {
2737
0
    if (obj->content_free) {
2738
0
      obj->content_free(obj->content.value, obj->content.len);
2739
0
    } else {
2740
0
      free(obj->content.value);
2741
0
    }
2742
0
  }
2743
24.8k
  obj->content.value = NULL;
2744
24.8k
  obj->content.len = 0;
2745
24.8k
}
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
0
{
2752
0
  unsigned char *tmp_buf;
2753
2754
0
  if (!obj)
2755
0
    return SC_ERROR_INVALID_ARGUMENTS;
2756
2757
0
  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
0
  if (SC_PKCS15_TYPE_AUTH & obj->type
2766
0
      || SC_PKCS15_TYPE_SKEY & obj->type
2767
0
      || SC_PKCS15_TYPE_PRKEY & obj->type) {
2768
0
    tmp_buf = sc_mem_secure_alloc(len);
2769
0
    obj->content_free = sc_mem_secure_free;
2770
0
  } else {
2771
0
    tmp_buf = malloc(len);
2772
0
  }
2773
0
  if (!tmp_buf)
2774
0
    return SC_ERROR_OUT_OF_MEMORY;
2775
2776
0
  memcpy(tmp_buf, value, len);
2777
2778
0
  sc_pkcs15_free_object_content(obj);
2779
2780
0
  obj->content.value = tmp_buf;
2781
0
  obj->content.len = len;
2782
2783
0
  return SC_SUCCESS;
2784
0
}
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
2.00k
{
3090
2.00k
  if (!params)
3091
0
    return;
3092
2.00k
  if (params->data && params->free_params)
3093
0
    params->free_params(params->data);
3094
2.00k
  else if (params->data)
3095
0
    free(params->data);
3096
3097
  params->data = NULL;
3098
2.00k
}
3099