Coverage Report

Created: 2025-11-11 06:51

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
690
{
142
690
  int r;
143
690
  size_t ii;
144
690
  u8 serial[128];
145
690
  size_t serial_len = sizeof(serial);
146
690
  u8 mnfid[SC_PKCS15_MAX_LABEL_SIZE];
147
690
  size_t mnfid_len  = sizeof(mnfid) - 1;
148
690
  u8 label[SC_PKCS15_MAX_LABEL_SIZE];
149
690
  size_t label_len = sizeof(label) - 1;
150
690
  u8 last_update[32], profile_indication[SC_PKCS15_MAX_LABEL_SIZE];
151
690
  size_t lupdate_len = sizeof(last_update) - 1, pi_len = sizeof(profile_indication) - 1;
152
690
  size_t flags_len   = sizeof(ti->flags);
153
690
  u8 preferred_language[3];
154
690
  size_t lang_length = sizeof(preferred_language);
155
690
  struct sc_asn1_entry asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1],
156
690
      asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7],
157
690
      asn1_algo_infos_parameters[SC_MAX_SUPPORTED_ALGORITHMS][3];
158
690
  size_t reference_len = sizeof(ti->supported_algos[0].reference);
159
690
  size_t mechanism_len = sizeof(ti->supported_algos[0].mechanism);
160
690
  size_t parameter_len = sizeof(ti->supported_algos[0].parameters);
161
690
  size_t operations_len = sizeof(ti->supported_algos[0].operations);
162
690
  size_t algo_ref_len = sizeof(ti->supported_algos[0].algo_ref);
163
164
690
  struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE];
165
690
  struct sc_asn1_entry asn1_profile_indication[C_ASN1_PROFILE_INDICATION_SIZE];
166
690
  struct sc_asn1_entry asn1_toki_attrs[C_ASN1_TOKI_ATTRS_SIZE], asn1_tokeninfo[3], asn1_twlabel[3];
167
168
690
  memset(last_update, 0, sizeof(last_update));
169
690
  memset(label, 0, sizeof(label));
170
690
  memset(profile_indication, 0, sizeof(profile_indication));
171
690
  memset(mnfid, 0, sizeof(mnfid));
172
173
690
  sc_copy_asn1_entry(c_asn1_twlabel, asn1_twlabel);
174
690
  sc_copy_asn1_entry(c_asn1_toki_attrs, asn1_toki_attrs);
175
690
  sc_copy_asn1_entry(c_asn1_tokeninfo, asn1_tokeninfo);
176
690
  sc_copy_asn1_entry(c_asn1_last_update, asn1_last_update);
177
690
  sc_format_asn1_entry(asn1_twlabel, label, &label_len, 0);
178
690
  sc_copy_asn1_entry(c_asn1_profile_indication, asn1_profile_indication);
179
180
11.7k
  for (ii=0; ii<SC_MAX_SUPPORTED_ALGORITHMS; ii++) {
181
11.0k
    sc_copy_asn1_entry(c_asn1_algorithm_info, asn1_algo_infos[ii]);
182
11.0k
    sc_copy_asn1_entry(c_asn1_algorithm_info_parameters,
183
11.0k
      asn1_algo_infos_parameters[ii]);
184
11.0k
  }
185
690
  sc_copy_asn1_entry(c_asn1_supported_algorithms, asn1_supported_algorithms);
186
187
11.7k
  for (ii=0; ii<SC_MAX_SUPPORTED_ALGORITHMS; ii++)   {
188
11.0k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 0, &ti->supported_algos[ii].reference, &reference_len, 0);
189
11.0k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 1, &ti->supported_algos[ii].mechanism, &mechanism_len, 0);
190
11.0k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 2,
191
11.0k
      asn1_algo_infos_parameters[ii], NULL, 0);
192
11.0k
    sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 0,
193
11.0k
      NULL, NULL, 0);
194
11.0k
    sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 1,
195
11.0k
      &ti->supported_algos[ii].parameters, &parameter_len, 0);
196
11.0k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 3, &ti->supported_algos[ii].operations, &operations_len, 0);
197
11.0k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 4, &ti->supported_algos[ii].algo_id, NULL, 1);
198
11.0k
    sc_format_asn1_entry(asn1_algo_infos[ii] + 5, &ti->supported_algos[ii].algo_ref, &algo_ref_len, 0);
199
11.0k
    sc_format_asn1_entry(asn1_supported_algorithms + ii, asn1_algo_infos[ii], NULL, 0);
200
11.0k
  }
201
202
690
  sc_format_asn1_entry(asn1_last_update + 0, last_update, &lupdate_len, 0);
203
690
  sc_format_asn1_entry(asn1_last_update + 1, &ti->last_update.path, NULL, 0);
204
205
690
  sc_format_asn1_entry(asn1_profile_indication + 0, &ti->profile_indication.oid, NULL, 0);
206
690
  sc_format_asn1_entry(asn1_profile_indication + 1, profile_indication, &pi_len, 0);
207
208
690
  sc_format_asn1_entry(asn1_toki_attrs + 0, &ti->version, NULL, 0);
209
690
  sc_format_asn1_entry(asn1_toki_attrs + 1, serial, &serial_len, 0);
210
690
  sc_format_asn1_entry(asn1_toki_attrs + 2, mnfid, &mnfid_len, 0);
211
690
  sc_format_asn1_entry(asn1_toki_attrs + 3, label, &label_len, 0);
212
690
  sc_format_asn1_entry(asn1_toki_attrs + 4, asn1_twlabel, NULL, 0);
213
690
  sc_format_asn1_entry(asn1_toki_attrs + 5, &ti->flags, &flags_len, 0);
214
690
  sc_format_asn1_entry(asn1_toki_attrs + 6, &ti->seInfo, &ti->num_seInfo, 0);
215
690
  sc_format_asn1_entry(asn1_toki_attrs + 7, NULL, NULL, 0);
216
690
  sc_format_asn1_entry(asn1_toki_attrs + 8, asn1_supported_algorithms, NULL, 0);
217
690
  sc_format_asn1_entry(asn1_toki_attrs + 9, NULL, NULL, 0);
218
690
  sc_format_asn1_entry(asn1_toki_attrs + 10, NULL, NULL, 0);
219
690
  sc_format_asn1_entry(asn1_toki_attrs + 11, asn1_last_update, NULL, 0);
220
690
  sc_format_asn1_entry(asn1_toki_attrs + 12, preferred_language, &lang_length, 0);
221
690
  sc_format_asn1_entry(asn1_toki_attrs + 13, asn1_profile_indication, NULL, 0);
222
690
  sc_format_asn1_entry(asn1_tokeninfo, asn1_toki_attrs, NULL, 0);
223
224
690
  r = sc_asn1_decode(ctx, asn1_tokeninfo, buf, blen, NULL, NULL);
225
690
  if (r != SC_SUCCESS) {
226
    /* The decoding could have allocated something we need to free */
227
372
    sc_pkcs15_clear_tokeninfo(ti);
228
372
    LOG_TEST_RET(ctx, r, "ASN.1 parsing of EF(TokenInfo) failed");
229
372
  }
230
231
318
  if (asn1_toki_attrs[1].flags & SC_ASN1_PRESENT && serial_len > 0)   {
232
246
    free(ti->serial_number);
233
246
    ti->serial_number = malloc(serial_len * 2 + 1);
234
246
    if (ti->serial_number == NULL)
235
0
      return SC_ERROR_OUT_OF_MEMORY;
236
246
    sc_bin_to_hex(serial, serial_len, ti->serial_number, serial_len * 2 + 1, 0);
237
246
    sc_log(ctx, "TokenInfo.serialNunmber '%s'", ti->serial_number);
238
246
  }
239
240
318
  if (ti->manufacturer_id == NULL) {
241
318
    if (asn1_toki_attrs[2].flags & SC_ASN1_PRESENT)
242
20
      ti->manufacturer_id = strdup((char *) mnfid);
243
298
    else
244
298
      ti->manufacturer_id = strdup("(unknown)");
245
318
    if (ti->manufacturer_id == NULL)
246
0
      return SC_ERROR_OUT_OF_MEMORY;
247
318
  }
248
318
  if (ti->label == NULL) {
249
318
    if (asn1_toki_attrs[3].flags & SC_ASN1_PRESENT ||
250
311
        asn1_toki_attrs[4].flags & SC_ASN1_PRESENT)
251
7
      ti->label = strdup((char *) label);
252
311
    else
253
311
      ti->label = strdup("(unknown)");
254
318
    if (ti->label == NULL)
255
0
      return SC_ERROR_OUT_OF_MEMORY;
256
318
  }
257
318
  if (asn1_toki_attrs[11].flags & SC_ASN1_PRESENT) {
258
84
    if (asn1_last_update[0].flags & SC_ASN1_PRESENT)   {
259
8
      sc_log(ctx, "LastUpdate.generalizedTime present");
260
8
      ti->last_update.gtime = strdup((char *)last_update);
261
8
      if (ti->last_update.gtime == NULL)
262
0
        return SC_ERROR_OUT_OF_MEMORY;
263
8
    }
264
76
    else if (asn1_last_update[1].flags & SC_ASN1_PRESENT)  {
265
71
      sc_log(ctx, "LastUpdate.referencedTime present");
266
71
    }
267
84
  }
268
318
  if (asn1_toki_attrs[12].flags & SC_ASN1_PRESENT) {
269
11
    preferred_language[2] = 0;
270
11
    ti->preferred_language = strdup((char *)preferred_language);
271
11
    if (ti->preferred_language == NULL)
272
0
      return SC_ERROR_OUT_OF_MEMORY;
273
11
  }
274
275
318
  sc_init_oid(&ti->profile_indication.oid);
276
318
  if (asn1_toki_attrs[13].flags & SC_ASN1_PRESENT) {
277
107
    if (asn1_profile_indication[0].flags & SC_ASN1_PRESENT)   {
278
3
      sc_log(ctx, "ProfileIndication.oid present");
279
3
    }
280
104
    else if (asn1_profile_indication[1].flags & SC_ASN1_PRESENT)  {
281
100
      sc_log(ctx, "ProfileIndication.name present");
282
100
      ti->profile_indication.name = strdup((char *)profile_indication);
283
100
      if (ti->profile_indication.name == NULL)
284
0
        return SC_ERROR_OUT_OF_MEMORY;
285
100
    }
286
107
  }
287
288
318
  sc_log(ctx, "LastUpdate.path '%s'", sc_print_path(&ti->last_update.path));
289
318
  sc_log(ctx, "ProfileIndication.name '%s'",  ti->profile_indication.name);
290
318
  return SC_SUCCESS;
291
318
}
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
36
{
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
36
  if (p15card->card->type == SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2)   {
454
0
    sc_file_free(p15card->file_odf);
455
0
    p15card->file_odf = NULL;
456
0
    sc_file_free(p15card->file_tokeninfo);
457
0
    p15card->file_tokeninfo = NULL;
458
0
  }
459
36
}
460
461
static int
462
parse_ddo(struct sc_pkcs15_card *p15card, const u8 * buf, size_t buflen)
463
44
{
464
44
  struct sc_context *ctx = p15card->card->ctx;
465
44
  struct sc_asn1_entry asn1_ddo[7];
466
44
  sc_path_t odf_path, ti_path, us_path;
467
44
  struct sc_iid iid;
468
44
  struct sc_aid aid;
469
44
  int r;
470
471
44
  LOG_FUNC_CALLED(ctx);
472
473
44
  iid.len = sizeof(iid.value);
474
44
  aid.len = sizeof(aid.value);
475
476
44
  sc_copy_asn1_entry(c_asn1_ddo, asn1_ddo);
477
44
  sc_format_asn1_entry(asn1_ddo + 1, &odf_path, NULL, 0);
478
44
  sc_format_asn1_entry(asn1_ddo + 2, &ti_path, NULL, 0);
479
44
  sc_format_asn1_entry(asn1_ddo + 3, &us_path, NULL, 0);
480
44
  sc_format_asn1_entry(asn1_ddo + 4, iid.value, &iid.len, 0);
481
44
  sc_format_asn1_entry(asn1_ddo + 5, aid.value, &aid.len, 0);
482
483
44
  r = sc_asn1_decode(ctx, asn1_ddo, buf, buflen, NULL, NULL);
484
44
  LOG_TEST_RET(ctx, r, "DDO parsing failed");
485
486
36
  if (asn1_ddo[1].flags & SC_ASN1_PRESENT) {
487
13
    sc_file_free(p15card->file_odf);
488
13
    p15card->file_odf = sc_file_new();
489
13
    if (p15card->file_odf == NULL)
490
0
      goto mem_err;
491
13
    p15card->file_odf->path = odf_path;
492
13
  }
493
36
  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
36
  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
36
  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
36
  if (asn1_ddo[5].flags & SC_ASN1_PRESENT) {
512
3
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "DDO.AID '%s'", sc_dump_hex(aid.value, aid.len));
513
3
    memcpy(&p15card->app->ddo.aid, &aid, sizeof(struct sc_aid));
514
3
  }
515
516
36
  fix_authentic_ddo(p15card);
517
36
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
518
0
mem_err:
519
0
  sc_file_free(p15card->file_odf);
520
0
  p15card->file_odf = NULL;
521
0
  sc_file_free(p15card->file_tokeninfo);
522
0
  p15card->file_tokeninfo = NULL;
523
0
  sc_file_free(p15card->file_unusedspace);
524
0
  p15card->file_unusedspace = NULL;
525
0
  LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
526
0
}
527
528
529
char *
530
sc_pkcs15_get_lastupdate(struct sc_pkcs15_card *p15card)
531
3.46k
{
532
3.46k
  struct sc_context *ctx  = p15card->card->ctx;
533
3.46k
  struct sc_file *file = NULL;
534
3.46k
  struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE];
535
3.46k
  unsigned char *content, last_update[32] = {0};
536
3.46k
  size_t lupdate_len = sizeof(last_update) - 1;
537
3.46k
  int r, content_len;
538
3.46k
  size_t size;
539
540
3.46k
  if (p15card->tokeninfo->last_update.gtime)
541
40
    goto done;
542
543
3.42k
  if (!p15card->tokeninfo->last_update.path.len)
544
2.75k
    return NULL;
545
546
667
  r = sc_select_file(p15card->card, &p15card->tokeninfo->last_update.path, &file);
547
667
  if (r < 0)
548
581
    return NULL;
549
550
86
  size = file->size ? file->size : 1024;
551
86
  sc_file_free(file);
552
553
86
  content = calloc(1, size);
554
86
  if (!content)
555
0
    return NULL;
556
557
86
  r = sc_read_binary(p15card->card, 0, content, size, 0);
558
86
  if (r < 0) {
559
33
    free(content);
560
33
    return NULL;
561
33
  }
562
53
  content_len = r;
563
564
53
  sc_copy_asn1_entry(c_asn1_last_update, asn1_last_update);
565
53
  sc_format_asn1_entry(asn1_last_update + 0, last_update, &lupdate_len, 0);
566
567
53
  r = sc_asn1_decode(ctx, asn1_last_update, content, content_len, NULL, NULL);
568
53
  free(content);
569
53
  if (r < 0)
570
1
    return NULL;
571
572
52
  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
92
done:
578
92
  sc_log(ctx, "lastUpdate.gtime '%s'", p15card->tokeninfo->last_update.gtime);
579
92
  return p15card->tokeninfo->last_update.gtime;
580
52
}
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
399
{
612
399
  const unsigned char *p = buf;
613
399
  size_t left = buflen;
614
399
  int r, i, type;
615
399
  struct sc_path path;
616
399
  struct sc_asn1_entry asn1_obj_or_path[] = {
617
399
    { "path", SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_SEQUENCE, 0, &path, NULL },
618
399
    { NULL, 0, 0, 0, NULL, NULL }
619
399
  };
620
399
  struct sc_asn1_entry asn1_odf[10];
621
622
399
  sc_copy_asn1_entry(c_asn1_odf, asn1_odf);
623
3.99k
  for (i = 0; asn1_odf[i].name != NULL; i++)
624
3.59k
    sc_format_asn1_entry(asn1_odf + i, asn1_obj_or_path, NULL, 0);
625
3.75k
  while (left > 0) {
626
3.69k
    r = sc_asn1_decode_choice(p15card->card->ctx, asn1_odf, p, left, &p, &left);
627
3.69k
    if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
628
159
      break;
629
3.53k
    if (r < 0)
630
180
      return r;
631
3.35k
    type = r;
632
3.35k
    if (p15card->file_app) {
633
3.35k
      r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &path);
634
3.35k
      if (r < 0)
635
1
        return r;
636
3.35k
      r = sc_pkcs15_add_df(p15card, odf_indexes[type], &path);
637
3.35k
      if (r)
638
0
        return r;
639
3.35k
    }
640
3.35k
  }
641
218
  return 0;
642
399
}
643
644
645
int
646
sc_pkcs15_encode_odf(struct sc_context *ctx, struct sc_pkcs15_card *p15card,
647
       unsigned char **buf, size_t *buflen)
648
0
{
649
0
  struct sc_path path;
650
0
  struct sc_asn1_entry asn1_obj_or_path[] = {
651
0
    { "path", SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_SEQUENCE, 0, &path, NULL },
652
0
    { NULL, 0, 0, 0, NULL, NULL }
653
0
  };
654
0
  struct sc_asn1_entry *asn1_paths = NULL;
655
0
  struct sc_asn1_entry *asn1_odf = NULL;
656
0
  int df_count = 0, r, c = 0;
657
0
  const int nr_indexes = sizeof(odf_indexes)/sizeof(odf_indexes[0]);
658
0
  struct sc_pkcs15_df *df;
659
660
0
  df = p15card->df_list;
661
0
  while (df != NULL) {
662
0
    df_count++;
663
0
    df = df->next;
664
0
  };
665
0
  if (df_count == 0)
666
0
    LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "No DF's found.");
667
668
0
  asn1_odf = malloc(sizeof(struct sc_asn1_entry) * (df_count + 1));
669
0
  if (asn1_odf == NULL) {
670
0
    r = SC_ERROR_OUT_OF_MEMORY;
671
0
    goto err;
672
0
  }
673
0
  asn1_paths = malloc(sizeof(struct sc_asn1_entry) * (df_count * 2));
674
0
  if (asn1_paths == NULL) {
675
0
    r = SC_ERROR_OUT_OF_MEMORY;
676
0
    goto err;
677
0
  }
678
0
  for (df = p15card->df_list; df != NULL; df = df->next) {
679
0
    int j, type = -1;
680
681
0
    for (j = 0; j < nr_indexes; j++)
682
0
      if (odf_indexes[j] == df->type) {
683
0
        type = j;
684
0
        break;
685
0
      }
686
0
    if (type == -1) {
687
0
      sc_log(ctx, "Unsupported DF type.");
688
0
      continue;
689
0
    }
690
0
    asn1_odf[c] = c_asn1_odf[type];
691
0
    sc_format_asn1_entry(asn1_odf + c, asn1_paths + 2*c, NULL, 1);
692
0
    sc_copy_asn1_entry(asn1_obj_or_path, asn1_paths + 2*c);
693
0
    sc_format_asn1_entry(asn1_paths + 2*c, &df->path, NULL, 1);
694
0
    c++;
695
0
  }
696
0
  asn1_odf[c].name = NULL;
697
0
  r = sc_asn1_encode(ctx, asn1_odf, buf, buflen);
698
0
err:
699
0
  if (asn1_paths != NULL)
700
0
    free(asn1_paths);
701
0
  if (asn1_odf != NULL)
702
0
    free(asn1_odf);
703
0
  return r;
704
0
}
705
706
707
struct sc_pkcs15_card *
708
sc_pkcs15_card_new(void)
709
12.3k
{
710
12.3k
  struct sc_pkcs15_card *p15card;
711
712
12.3k
  p15card = calloc(1, sizeof(struct sc_pkcs15_card));
713
12.3k
  if (p15card == NULL)
714
0
    return NULL;
715
716
12.3k
  p15card->tokeninfo = calloc(1, sizeof(struct sc_pkcs15_tokeninfo));
717
12.3k
  if (p15card->tokeninfo == NULL) {
718
0
    free(p15card);
719
0
    return NULL;
720
0
  }
721
722
12.3k
  p15card->magic = SC_PKCS15_CARD_MAGIC;
723
12.3k
  return p15card;
724
12.3k
}
725
726
727
struct sc_pkcs15_tokeninfo *
728
sc_pkcs15_tokeninfo_new(void)
729
8.86k
{
730
8.86k
  struct sc_pkcs15_tokeninfo *tokeninfo;
731
732
8.86k
  tokeninfo = calloc(1, sizeof(struct sc_pkcs15_tokeninfo));
733
8.86k
  if (tokeninfo == NULL) {
734
0
    return NULL;
735
0
  }
736
737
8.86k
  sc_init_oid(&tokeninfo->profile_indication.oid);
738
739
8.86k
  return tokeninfo;
740
8.86k
}
741
742
static void
743
sc_pkcs15_clear_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo)
744
21.5k
{
745
21.5k
  if (!tokeninfo)
746
0
    return;
747
748
21.5k
  free(tokeninfo->label);
749
21.5k
  tokeninfo->label = NULL;
750
21.5k
  free(tokeninfo->serial_number);
751
21.5k
  tokeninfo->serial_number = NULL;
752
21.5k
  free(tokeninfo->manufacturer_id);
753
21.5k
  tokeninfo->manufacturer_id = NULL;
754
21.5k
  free(tokeninfo->last_update.gtime);
755
21.5k
  tokeninfo->last_update.gtime = NULL;
756
21.5k
  free(tokeninfo->preferred_language);
757
21.5k
  tokeninfo->preferred_language = NULL;
758
21.5k
  free(tokeninfo->profile_indication.name);
759
21.5k
  tokeninfo->profile_indication.name = NULL;
760
21.5k
  if (tokeninfo->seInfo != NULL) {
761
25
    unsigned i;
762
28
    for (i = 0; i < tokeninfo->num_seInfo; i++)
763
3
      free(tokeninfo->seInfo[i]);
764
25
    free(tokeninfo->seInfo);
765
25
    tokeninfo->seInfo = NULL;
766
25
  }
767
21.5k
}
768
769
void
770
sc_pkcs15_free_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo)
771
22.5k
{
772
22.5k
  if (!tokeninfo)
773
1.36k
    return;
774
775
21.1k
  sc_pkcs15_clear_tokeninfo(tokeninfo);
776
21.1k
  free(tokeninfo);
777
21.1k
}
778
779
void
780
sc_pkcs15_free_app(struct sc_pkcs15_card *p15card)
781
39.8k
{
782
39.8k
  if (p15card && p15card->app) {
783
700
    free(p15card->app->label);
784
700
    free(p15card->app->ddo.value);
785
700
    free(p15card->app);
786
700
    p15card->app = NULL;
787
700
  }
788
39.8k
}
789
790
791
void
792
sc_pkcs15_card_free(struct sc_pkcs15_card *p15card)
793
12.3k
{
794
12.3k
  if (p15card == NULL || p15card->magic != SC_PKCS15_CARD_MAGIC)
795
0
    return;
796
797
12.3k
  if (p15card->ops.clear)
798
801
    p15card->ops.clear(p15card);
799
800
  /* For more complicated MD data a dedicated release procedure
801
   * has to be implemented. */
802
12.3k
  if (p15card->md_data)
803
0
    free(p15card->md_data);
804
805
12.3k
  sc_pkcs15_free_app(p15card);
806
12.3k
  sc_pkcs15_remove_objects(p15card);
807
12.3k
  sc_pkcs15_remove_dfs(p15card);
808
12.3k
  sc_pkcs15_free_unusedspace(p15card);
809
12.3k
  p15card->unusedspace_read = 0;
810
811
12.3k
  sc_file_free(p15card->file_app);
812
12.3k
  sc_file_free(p15card->file_tokeninfo);
813
12.3k
  sc_file_free(p15card->file_odf);
814
12.3k
  sc_file_free(p15card->file_unusedspace);
815
816
12.3k
  p15card->magic = 0;
817
12.3k
  sc_pkcs15_free_tokeninfo(p15card->tokeninfo);
818
12.3k
  sc_pkcs15_free_app(p15card);
819
12.3k
  free(p15card);
820
12.3k
}
821
822
823
void
824
sc_pkcs15_card_clear(struct sc_pkcs15_card *p15card)
825
14.7k
{
826
14.7k
  if (p15card == NULL)
827
0
    return;
828
829
14.7k
  if (p15card->ops.clear)
830
695
    p15card->ops.clear(p15card);
831
832
14.7k
  p15card->flags = 0;
833
14.7k
  p15card->tokeninfo->version = 0;
834
14.7k
  p15card->tokeninfo->flags   = 0;
835
836
14.7k
  sc_pkcs15_remove_objects(p15card);
837
14.7k
  sc_pkcs15_remove_dfs(p15card);
838
839
14.7k
  p15card->df_list = NULL;
840
14.7k
  sc_file_free(p15card->file_app);
841
14.7k
  p15card->file_app = NULL;
842
14.7k
  sc_file_free(p15card->file_tokeninfo);
843
14.7k
  p15card->file_tokeninfo = NULL;
844
14.7k
  sc_file_free(p15card->file_odf);
845
14.7k
  p15card->file_odf = NULL;
846
14.7k
  sc_file_free(p15card->file_unusedspace);
847
14.7k
  p15card->file_unusedspace = NULL;
848
849
14.7k
  free(p15card->tokeninfo->label);
850
14.7k
  p15card->tokeninfo->label = NULL;
851
14.7k
  free(p15card->tokeninfo->serial_number);
852
14.7k
  p15card->tokeninfo->serial_number = NULL;
853
14.7k
  free(p15card->tokeninfo->manufacturer_id);
854
14.7k
  p15card->tokeninfo->manufacturer_id = NULL;
855
14.7k
  free(p15card->tokeninfo->last_update.gtime);
856
14.7k
  p15card->tokeninfo->last_update.gtime = NULL;
857
14.7k
  free(p15card->tokeninfo->preferred_language);
858
14.7k
  p15card->tokeninfo->preferred_language = NULL;
859
14.7k
  free(p15card->tokeninfo->profile_indication.name);
860
14.7k
  p15card->tokeninfo->profile_indication.name = NULL;
861
14.7k
  if (p15card->tokeninfo->seInfo != NULL) {
862
3
    size_t i;
863
3
    for (i = 0; i < p15card->tokeninfo->num_seInfo; i++)
864
0
      free(p15card->tokeninfo->seInfo[i]);
865
3
    free(p15card->tokeninfo->seInfo);
866
3
    p15card->tokeninfo->seInfo     = NULL;
867
3
    p15card->tokeninfo->num_seInfo = 0;
868
3
  }
869
870
14.7k
  sc_pkcs15_free_app(p15card);
871
14.7k
}
872
873
874
struct sc_app_info *
875
sc_find_app(struct sc_card *card, struct sc_aid *aid)
876
12.0k
{
877
12.0k
  int ii;
878
879
12.0k
  if (card->app_count <= 0)
880
11.6k
    return NULL;
881
882
432
  if (!aid || !aid->len)
883
432
    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
432
{
899
432
  struct sc_app_info *out = calloc(1, sizeof(struct sc_app_info));
900
901
432
  if (!out)
902
0
    return NULL;
903
904
432
  memcpy(out, info, sizeof(struct sc_app_info));
905
906
432
  if (info->label) {
907
9
    out->label = strdup(info->label);
908
9
    if (!out->label) {
909
0
      free(out);
910
0
      return NULL;
911
0
    }
912
9
  } else
913
423
    out->label = NULL;
914
915
432
  out->ddo.value = malloc(info->ddo.len);
916
432
  if (!out->ddo.value) {
917
0
    free(out->label);
918
0
    free(out);
919
0
    return NULL;
920
0
  }
921
432
  memcpy(out->ddo.value, info->ddo.value, info->ddo.len);
922
432
  out->ddo.len = info->ddo.len;
923
924
432
  return out;
925
432
}
926
927
928
struct sc_app_info *
929
sc_pkcs15_get_application_by_type(struct sc_card * card, char *app_type)
930
0
{
931
0
  struct sc_app_info *out = NULL;
932
0
  scconf_block *conf_block = NULL;
933
0
  int i, rv;
934
935
0
  if (!card)
936
0
    return NULL;
937
938
0
  if (card->app_count < 0)   {
939
0
    rv = sc_enum_apps(card);
940
0
    if (rv < 0 && rv != SC_ERROR_FILE_NOT_FOUND)
941
0
      return NULL;
942
0
  }
943
944
0
  conf_block = sc_get_conf_block(card->ctx, "framework", "pkcs15", 1);
945
0
  if (!conf_block)
946
0
    return NULL;
947
948
0
  for (i = 0; i < card->app_count; i++)   {
949
0
    struct sc_app_info *app_info = card->app[i];
950
0
    scconf_block **blocks = NULL;
951
0
    char str_path[SC_MAX_AID_STRING_SIZE];
952
953
0
    sc_bin_to_hex(app_info->aid.value, app_info->aid.len, str_path, sizeof(str_path), 0);
954
0
    blocks = scconf_find_blocks(card->ctx->conf, conf_block, "application", str_path);
955
0
    if (blocks)   {
956
0
      if (blocks[0])   {
957
0
        char *type = (char *)scconf_get_str(blocks[0], "type", app_type);
958
0
        if (!strcmp(type, app_type))   {
959
0
          out = app_info;
960
0
          free(blocks);
961
0
          break;
962
0
        }
963
0
      }
964
0
      free(blocks);
965
0
    }
966
0
  }
967
968
0
  return out;
969
0
}
970
971
972
int
973
sc_pkcs15_bind_internal(struct sc_pkcs15_card *p15card, struct sc_aid *aid)
974
12.0k
{
975
12.0k
  struct sc_path tmppath;
976
12.0k
  struct sc_card    *card = p15card->card;
977
12.0k
  struct sc_context *ctx  = card->ctx;
978
12.0k
  struct sc_pkcs15_tokeninfo tokeninfo;
979
12.0k
  struct sc_pkcs15_df *df;
980
12.0k
  const struct sc_app_info *info = NULL;
981
12.0k
  unsigned char *buf = NULL;
982
12.0k
  size_t len;
983
12.0k
  int    err, ok = 0;
984
985
12.0k
  LOG_FUNC_CALLED(ctx);
986
  /* Enumerate apps now */
987
12.0k
  if (card->app_count < 0) {
988
11.2k
    err = sc_enum_apps(card);
989
11.2k
    if (err != SC_SUCCESS)
990
10.8k
      sc_log(ctx, "unable to enumerate apps: %s", sc_strerror(err));
991
11.2k
  }
992
12.0k
  sc_file_free(p15card->file_app);
993
12.0k
  p15card->file_app = sc_file_new();
994
12.0k
  if (p15card->file_app == NULL) {
995
0
    err = SC_ERROR_OUT_OF_MEMORY;
996
0
    goto end;
997
0
  }
998
999
12.0k
  sc_format_path("3F005015", &p15card->file_app->path);
1000
1001
12.0k
  info = sc_find_app(card, aid);
1002
12.0k
  if (info)   {
1003
432
    sc_log(ctx, "bind to application('%s',aid:'%s')", info->label, sc_dump_hex(info->aid.value, info->aid.len));
1004
432
    sc_pkcs15_free_app(p15card);
1005
432
    p15card->app = sc_dup_app_info(info);
1006
432
    if (!p15card->app)   {
1007
0
      err = SC_ERROR_OUT_OF_MEMORY;
1008
0
      goto end;
1009
0
    }
1010
1011
432
    if (info->path.len)
1012
394
      p15card->file_app->path = info->path;
1013
1014
432
    if (info->ddo.value && info->ddo.len)
1015
44
      parse_ddo(p15card, info->ddo.value, info->ddo.len);
1016
1017
432
  }
1018
11.6k
  else if (aid)   {
1019
0
    sc_log(ctx, "Application '%s' not found", sc_dump_hex(aid->value, aid->len));
1020
0
    err = SC_ERROR_INVALID_ARGUMENTS;
1021
0
    goto end;
1022
0
  }
1023
12.0k
  sc_log(ctx, "application path '%s'", sc_print_path(&p15card->file_app->path));
1024
1025
  /* Check if pkcs15 directory exists */
1026
12.0k
  err = sc_select_file(card, &p15card->file_app->path, NULL);
1027
1028
  /* If the above test failed on cards without EF(DIR),
1029
   * try to continue read ODF from 3F005031. -aet
1030
   */
1031
12.0k
  if ((err != SC_SUCCESS) && (card->app_count < 1)) {
1032
9.90k
    sc_format_path("3F00", &p15card->file_app->path);
1033
9.90k
    err = SC_SUCCESS;
1034
9.90k
  }
1035
1036
12.0k
  if (err < 0)   {
1037
336
    sc_log (ctx, "Cannot select application path");
1038
336
    goto end;
1039
336
  }
1040
1041
11.7k
  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.7k
    sc_format_path("5031", &tmppath);
1044
11.7k
    err = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &tmppath);
1045
11.7k
    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.7k
    sc_log(ctx, "absolute path to EF(ODF) %s", sc_print_path(&tmppath));
1050
11.7k
    err = sc_select_file(card, &tmppath, &p15card->file_odf);
1051
11.7k
  }
1052
8
  else {
1053
8
    tmppath = p15card->file_odf->path;
1054
8
    sc_file_free(p15card->file_odf);
1055
8
    p15card->file_odf = NULL;
1056
8
    err = sc_select_file(card, &tmppath, &p15card->file_odf);
1057
8
  }
1058
1059
11.7k
  if (err != SC_SUCCESS) {
1060
10.7k
    sc_log(ctx, "EF(ODF) not found in '%s'", sc_print_path(&tmppath));
1061
10.7k
    goto end;
1062
10.7k
  }
1063
1064
948
  len = p15card->file_odf->size;
1065
948
  if (!len) {
1066
160
    sc_log(ctx, "EF(ODF) is empty");
1067
160
    goto end;
1068
160
  }
1069
788
  if (len > MAX_FILE_SIZE) {
1070
27
    sc_log(ctx, "EF(ODF) too large");
1071
27
    goto end;
1072
27
  }
1073
761
  buf = malloc(len);
1074
761
  if(buf == NULL) {
1075
0
    err = SC_ERROR_OUT_OF_MEMORY;
1076
0
    goto end;
1077
0
  }
1078
1079
761
  err = -1; /* file state: not in cache */
1080
761
  if (p15card->opts.use_file_cache) {
1081
160
    err = sc_pkcs15_read_cached_file(p15card, &tmppath, &buf, &len);
1082
160
    if (err == SC_SUCCESS)
1083
1
      err = (int)len;
1084
160
  }
1085
761
  if (err < 0) {
1086
760
    err = sc_read_binary(card, 0, buf, len, 0);
1087
760
    if (err < 2) {
1088
362
      if (err < 0) {
1089
316
        sc_log(ctx, "read EF(ODF) file error: %s", sc_strerror(err));
1090
316
      } else {
1091
46
        err = SC_ERROR_PKCS15_APP_NOT_FOUND;
1092
46
        sc_log(ctx, "Invalid content of EF(ODF): %s", sc_strerror(err));
1093
46
      }
1094
362
      goto end;
1095
362
    }
1096
    /* sc_read_binary may return less than requested */
1097
398
    len = err;
1098
1099
398
    if (p15card->opts.use_file_cache) {
1100
85
      sc_pkcs15_cache_file(p15card, &tmppath, buf, len);
1101
85
    }
1102
398
  }
1103
1104
399
  if (parse_odf(buf, len, p15card)) {
1105
181
    err = SC_ERROR_PKCS15_APP_NOT_FOUND;
1106
181
    sc_log(ctx, "Unable to parse ODF");
1107
181
    goto end;
1108
181
  }
1109
218
  free(buf);
1110
218
  buf = NULL;
1111
1112
218
  sc_log(ctx, "The following DFs were found:");
1113
1.62k
  for (df = p15card->df_list; df; df = df->next)
1114
1.40k
    sc_log(ctx, "  DF type %u, path %s, index %u, count %d", df->type,
1115
218
        sc_print_path(&df->path), df->path.index, df->path.count);
1116
1117
218
  if (p15card->file_tokeninfo == NULL) {
1118
218
    sc_format_path("5032", &tmppath);
1119
218
    err = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &tmppath);
1120
218
    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
218
    sc_log(ctx, "absolute path to EF(TokenInfo) %s", sc_print_path(&tmppath));
1125
218
  }
1126
0
  else {
1127
0
    tmppath = p15card->file_tokeninfo->path;
1128
0
    sc_file_free(p15card->file_tokeninfo);
1129
0
    p15card->file_tokeninfo = NULL;
1130
0
  }
1131
1132
218
  err = sc_select_file(card, &tmppath, &p15card->file_tokeninfo);
1133
218
  if (err)   {
1134
118
    sc_log(ctx, "cannot select EF(TokenInfo) file: %s", sc_strerror(err));
1135
118
    goto end;
1136
118
  }
1137
1138
100
  len = p15card->file_tokeninfo->size;
1139
100
  if (!len) {
1140
4
    sc_log(ctx, "EF(TokenInfo) is empty");
1141
4
    goto end;
1142
4
  }
1143
96
  if (len > MAX_FILE_SIZE) {
1144
21
    sc_log(ctx, "EF(TokenInfo) too large");
1145
21
    goto end;
1146
21
  }
1147
75
  buf = malloc(len);
1148
75
  if(buf == NULL) {
1149
0
    err = SC_ERROR_OUT_OF_MEMORY;
1150
0
    goto end;
1151
0
  }
1152
1153
75
  err = -1; /* file state: not in cache */
1154
75
  if (p15card->opts.use_file_cache) {
1155
27
    err = sc_pkcs15_read_cached_file(p15card, &tmppath, &buf, &len);
1156
27
    if (err == SC_SUCCESS)
1157
0
      err = (int)len;
1158
27
  }
1159
75
  if (err < 0) {
1160
75
    err = sc_read_binary(card, 0, buf, len, 0);
1161
75
    if (err <= 2) {
1162
37
      if (err < 0)   {
1163
30
        sc_log(ctx, "read EF(TokenInfo) file error: %s", sc_strerror(err));
1164
30
      } else {
1165
7
        err = SC_ERROR_PKCS15_APP_NOT_FOUND;
1166
7
        sc_log(ctx, "Invalid content of EF(TokenInfo): %s", sc_strerror(err));
1167
7
      }
1168
37
      goto end;
1169
37
    }
1170
    /* sc_read_binary may return less than requested */
1171
38
    len = err;
1172
1173
38
    if (p15card->opts.use_file_cache) {
1174
11
      sc_pkcs15_cache_file(p15card, &tmppath, buf, len);
1175
11
    }
1176
38
  }
1177
1178
38
  memset(&tokeninfo, 0, sizeof(tokeninfo));
1179
38
  err = sc_pkcs15_parse_tokeninfo(ctx, &tokeninfo, buf, (size_t)err);
1180
38
  if (err != SC_SUCCESS)   {
1181
24
    sc_log(ctx, "cannot parse TokenInfo content: %s", sc_strerror(err));
1182
24
    goto end;
1183
24
  }
1184
1185
14
  sc_pkcs15_clear_tokeninfo(p15card->tokeninfo);
1186
14
  *(p15card->tokeninfo) = tokeninfo;
1187
1188
14
  if (!p15card->tokeninfo->serial_number && 0 == card->serialnr.len) {
1189
13
    sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &card->serialnr);
1190
13
  }
1191
1192
14
  if (!p15card->tokeninfo->serial_number && card->serialnr.len)   {
1193
11
    char *serial = calloc(1, card->serialnr.len*2 + 1);
1194
11
    size_t ii;
1195
11
    if (!serial) {
1196
0
      err = SC_ERROR_OUT_OF_MEMORY;
1197
0
      goto end;
1198
0
    }
1199
1200
206
    for(ii=0;ii<card->serialnr.len;ii++)
1201
195
      sprintf(serial + ii*2, "%02X", *(card->serialnr.value + ii));
1202
1203
11
    p15card->tokeninfo->serial_number = serial;
1204
11
    sc_log(ctx, "p15card->tokeninfo->serial_number %s", p15card->tokeninfo->serial_number);
1205
11
  }
1206
1207
14
  ok = 1;
1208
12.0k
end:
1209
12.0k
  if(buf != NULL)
1210
618
    free(buf);
1211
12.0k
  if (!ok) {
1212
12.0k
    sc_pkcs15_card_clear(p15card);
1213
12.0k
    if (err == SC_ERROR_FILE_NOT_FOUND)
1214
1.33k
      err = SC_ERROR_WRONG_CARD;
1215
12.0k
    LOG_FUNC_RETURN(ctx, err);
1216
12.0k
  }
1217
1218
14
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1219
14
}
1220
1221
1222
const char *pkcs15_get_default_use_file_cache(struct sc_card *card)
1223
12.3k
{
1224
  /* enable file caching by default for cards with static content to avoid
1225
   * synchronization problems.
1226
   *
1227
   * The following list was initialized with the cards that can't be modified
1228
   * with OpenSC i.e. which don't have a profile/driver for pkcs15-init. */
1229
12.3k
  const char *card_drivers_with_file_cache[] = {
1230
12.3k
      "atrust-acos",
1231
12.3k
      "belpic",
1232
12.3k
      "cac1",
1233
12.3k
      "cac",
1234
12.3k
      "coolkey",
1235
12.3k
      "edo",
1236
12.3k
      "esteid2018",
1237
12.3k
      "esteid2025",
1238
12.3k
      "flex",
1239
12.3k
      "cyberflex",
1240
12.3k
      "gemsafeV1",
1241
12.3k
      "idprime",
1242
12.3k
      "itacns",
1243
12.3k
      "jpki",
1244
12.3k
      "MaskTech",
1245
12.3k
      "mcrd",
1246
12.3k
      "myeid",
1247
12.3k
      "npa",
1248
12.3k
      "nqapplet",
1249
12.3k
      "tcos",
1250
12.3k
      "dtrust",
1251
12.3k
  };
1252
1253
12.3k
  if (NULL == card || NULL == card->driver || NULL == card->driver->short_name)
1254
0
    return "no";
1255
215k
  for (size_t i = 0; i < (sizeof card_drivers_with_file_cache / sizeof *card_drivers_with_file_cache); i++) {
1256
208k
    if (0 == strcmp(card->driver->short_name, card_drivers_with_file_cache[i]))
1257
5.26k
      return "public";
1258
208k
  }
1259
1260
7.06k
  return "no";
1261
12.3k
}
1262
1263
int
1264
sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid,
1265
    struct sc_pkcs15_card **p15card_out)
1266
12.3k
{
1267
12.3k
  struct sc_pkcs15_card *p15card = NULL;
1268
12.3k
  struct sc_context *ctx;
1269
12.3k
  scconf_block *conf_block = NULL;
1270
12.3k
  int r, emu_first, enable_emu;
1271
12.3k
  const char *use_file_cache;
1272
12.3k
  const char *pin_protected_certificate, *private_certificate;
1273
1274
12.3k
  if (card == NULL || p15card_out == NULL) {
1275
0
    return SC_ERROR_INVALID_ARGUMENTS;
1276
0
  }
1277
12.3k
  ctx = card->ctx;
1278
1279
12.3k
  LOG_FUNC_CALLED(ctx);
1280
12.3k
  sc_log(ctx, "application(aid:'%s')", aid ? sc_dump_hex(aid->value, aid->len) : "empty");
1281
1282
12.3k
  p15card = sc_pkcs15_card_new();
1283
12.3k
  if (p15card == NULL)
1284
12.3k
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1285
1286
12.3k
  p15card->card = card;
1287
12.3k
  p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_NO_FILES;
1288
12.3k
  use_file_cache = pkcs15_get_default_use_file_cache(card);
1289
12.3k
  p15card->opts.use_pin_cache = 1;
1290
12.3k
  p15card->opts.pin_cache_counter = 10;
1291
12.3k
  p15card->opts.pin_cache_ignore_user_consent = 0;
1292
12.3k
  pin_protected_certificate = "protect";
1293
12.3k
  private_certificate = "";
1294
1295
12.3k
  conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);
1296
12.3k
  if (conf_block) {
1297
0
    use_file_cache = scconf_get_str(conf_block, "use_file_caching", use_file_cache);
1298
0
    p15card->opts.use_pin_cache = scconf_get_bool(conf_block, "use_pin_caching", p15card->opts.use_pin_cache);
1299
0
    p15card->opts.pin_cache_counter = scconf_get_int(conf_block, "pin_cache_counter", p15card->opts.pin_cache_counter);
1300
0
    p15card->opts.pin_cache_ignore_user_consent = scconf_get_bool(conf_block, "pin_cache_ignore_user_consent",
1301
0
        p15card->opts.pin_cache_ignore_user_consent);
1302
0
    pin_protected_certificate = scconf_get_str(conf_block, "pin_protected_certificate", pin_protected_certificate);
1303
    /* read also the old value to keep backward compatibility */
1304
0
    private_certificate = scconf_get_str(conf_block, "private_certificate", private_certificate);
1305
0
  }
1306
1307
12.3k
  if (0 == strcmp(use_file_cache, "yes")) {
1308
0
    p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_ALL_FILES;
1309
12.3k
  } else if (0 == strcmp(use_file_cache, "public")) {
1310
5.26k
    p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_PUBLIC_FILES;
1311
7.06k
  } else if (0 == strcmp(use_file_cache, "no")) {
1312
7.06k
    p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_NO_FILES;
1313
7.06k
  }
1314
1315
12.3k
  if (0 == strcmp(pin_protected_certificate, "protect")) {
1316
12.3k
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT;
1317
12.3k
  } else if (0 == strcmp(pin_protected_certificate, "ignore")) {
1318
0
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE;
1319
0
  } else if (0 == strcmp(pin_protected_certificate, "declassify")) {
1320
0
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY;
1321
0
  }
1322
  /* overwrite pin_protected_certificate when private_certificate set */
1323
12.3k
  if (0 == strcmp(private_certificate, "protect")) {
1324
0
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT;
1325
12.3k
  } else if (0 == strcmp(private_certificate, "ignore")) {
1326
0
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE;
1327
12.3k
  } else if (0 == strcmp(private_certificate, "declassify")) {
1328
0
    p15card->opts.pin_protected_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY;
1329
0
  }
1330
12.3k
  sc_log(ctx, "PKCS#15 options: use_file_cache=%d use_pin_cache=%d pin_cache_counter=%d pin_cache_ignore_user_consent=%d pin_protected_certificate=%d",
1331
12.3k
      p15card->opts.use_file_cache, p15card->opts.use_pin_cache, p15card->opts.pin_cache_counter,
1332
12.3k
      p15card->opts.pin_cache_ignore_user_consent, p15card->opts.pin_protected_certificate);
1333
1334
12.3k
  r = sc_lock(card);
1335
12.3k
  if (r) {
1336
0
    sc_log(ctx, "sc_lock() failed: %s", sc_strerror(r));
1337
0
    sc_pkcs15_card_free(p15card);
1338
0
    LOG_FUNC_RETURN(ctx, r);
1339
0
  }
1340
1341
12.3k
  enable_emu = scconf_get_bool(conf_block, "enable_pkcs15_emulation", 1);
1342
12.3k
  if (enable_emu) {
1343
12.3k
    sc_log(ctx, "PKCS#15 emulation enabled");
1344
12.3k
    emu_first = scconf_get_bool(conf_block, "try_emulation_first", 0);
1345
12.3k
    if (emu_first || sc_pkcs15_is_emulation_only(card)) {
1346
2.46k
      r = sc_pkcs15_bind_synthetic(p15card, aid);
1347
2.46k
      if (r == SC_SUCCESS)
1348
1.14k
        goto done;
1349
1.32k
      r = sc_pkcs15_bind_internal(p15card, aid);
1350
1.32k
      if (r < 0)
1351
1.31k
        goto error;
1352
9.86k
    } else {
1353
9.86k
      r = sc_pkcs15_bind_internal(p15card, aid);
1354
9.86k
      if (r == SC_SUCCESS)
1355
200
        goto done;
1356
9.66k
      r = sc_pkcs15_bind_synthetic(p15card, aid);
1357
9.66k
      if (r < 0)
1358
5.60k
        goto error;
1359
9.66k
    }
1360
12.3k
  }
1361
0
  else {
1362
0
    r = sc_pkcs15_bind_internal(p15card, aid);
1363
0
    if (r < 0)
1364
0
      goto error;
1365
0
  }
1366
5.41k
done:
1367
5.41k
  *p15card_out = p15card;
1368
5.41k
  sc_unlock(card);
1369
5.41k
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1370
6.91k
error:
1371
6.91k
  sc_unlock(card);
1372
6.91k
  sc_pkcs15_card_free(p15card);
1373
6.91k
  LOG_FUNC_RETURN(ctx, r);
1374
6.91k
}
1375
1376
1377
int
1378
sc_pkcs15_unbind(struct sc_pkcs15_card *p15card)
1379
0
{
1380
0
  if (p15card == NULL || p15card->magic != SC_PKCS15_CARD_MAGIC) {
1381
0
    return SC_ERROR_INVALID_ARGUMENTS;
1382
0
  }
1383
1384
0
  LOG_FUNC_CALLED(p15card->card->ctx);
1385
0
  if (p15card->dll_handle)
1386
0
    sc_dlclose(p15card->dll_handle);
1387
0
  sc_pkcs15_pincache_clear(p15card);
1388
0
  sc_pkcs15_card_free(p15card);
1389
0
  return 0;
1390
0
}
1391
1392
1393
static int
1394
__sc_pkcs15_search_objects(struct sc_pkcs15_card *p15card, unsigned int class_mask, unsigned int type,
1395
      int (*func)(sc_pkcs15_object_t *, void *), void *func_arg,
1396
      sc_pkcs15_object_t **ret, size_t ret_size)
1397
1.83k
{
1398
1.83k
  struct sc_pkcs15_object *obj = NULL;
1399
1.83k
  struct sc_pkcs15_df *df = NULL;
1400
1.83k
  unsigned int  df_mask = 0;
1401
1.83k
  size_t    match_count = 0;
1402
1.83k
  int r;
1403
1404
1.83k
  if (type)
1405
1.83k
    class_mask |= SC_PKCS15_TYPE_TO_CLASS(type);
1406
1407
  /* Make sure the class mask we have makes sense */
1408
1.83k
  if (class_mask == 0
1409
1.83k
      || (class_mask & ~(
1410
1.83k
          SC_PKCS15_SEARCH_CLASS_PRKEY |
1411
1.83k
          SC_PKCS15_SEARCH_CLASS_PUBKEY |
1412
1.83k
          SC_PKCS15_SEARCH_CLASS_SKEY |
1413
1.83k
          SC_PKCS15_SEARCH_CLASS_CERT |
1414
1.83k
          SC_PKCS15_SEARCH_CLASS_DATA |
1415
1.83k
          SC_PKCS15_SEARCH_CLASS_AUTH))) {
1416
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1417
0
  }
1418
1419
1.83k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_PRKEY)
1420
1
    df_mask |= (1 << SC_PKCS15_PRKDF);
1421
1.83k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_PUBKEY)
1422
0
    df_mask |= (1 << SC_PKCS15_PUKDF) | (1 << SC_PKCS15_PUKDF_TRUSTED);
1423
1.83k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_CERT)
1424
1.00k
    df_mask |= (1 << SC_PKCS15_CDF) | (1 << SC_PKCS15_CDF_TRUSTED) | (1 << SC_PKCS15_CDF_USEFUL);
1425
1.83k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_DATA)
1426
144
    df_mask |= (1 << SC_PKCS15_DODF);
1427
1.83k
  if (class_mask & SC_PKCS15_SEARCH_CLASS_AUTH)
1428
690
    df_mask |= (1 << SC_PKCS15_AODF);
1429
1.83k
  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
6.63k
  for (df = p15card->df_list; df != NULL; df = df->next) {
1435
4.80k
    if (!(df_mask & (1 << df->type)))   {
1436
3.47k
      continue;
1437
3.47k
    }
1438
1.33k
    if (df->enumerated)
1439
1.33k
      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
13.6k
  for (obj = p15card->obj_list; obj != NULL; obj = obj->next) {
1451
    /* Check object type */
1452
12.7k
    if (!(class_mask & SC_PKCS15_TYPE_TO_CLASS(obj->type)))
1453
9.33k
      continue;
1454
3.38k
    if (type != 0
1455
3.38k
     && obj->type != type
1456
1.68k
     && (obj->type & SC_PKCS15_TYPE_CLASS_MASK) != type)
1457
0
      continue;
1458
1459
    /* Potential candidate, apply search function */
1460
3.38k
    if (func != NULL && func(obj, func_arg) <= 0)
1461
784
      continue;
1462
    /* Okay, we have a match. */
1463
2.59k
    match_count++;
1464
2.59k
    if (!ret || ret_size <= 0)
1465
0
      continue;
1466
2.59k
    ret[match_count-1] = obj;
1467
2.59k
    if (ret_size <= match_count)
1468
899
      break;
1469
2.59k
  }
1470
1471
1.83k
  return (int)match_count;
1472
1.83k
}
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
156
{
1479
156
  return sc_pkcs15_get_objects_cond(p15card, type, NULL, NULL, ret, ret_size);
1480
156
}
1481
1482
1483
static int
1484
compare_obj_id(struct sc_pkcs15_object *obj, const struct sc_pkcs15_id *id)
1485
1.68k
{
1486
1.68k
  void *data = obj->data;
1487
1488
1.68k
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
1489
764
  case SC_PKCS15_TYPE_CERT:
1490
764
    return sc_pkcs15_compare_id(&((struct sc_pkcs15_cert_info *) data)->id, id);
1491
0
  case SC_PKCS15_TYPE_PRKEY:
1492
0
    return sc_pkcs15_compare_id(&((struct sc_pkcs15_prkey_info *) data)->id, id);
1493
0
  case SC_PKCS15_TYPE_PUBKEY:
1494
0
    return sc_pkcs15_compare_id(&((struct sc_pkcs15_pubkey_info *) data)->id, id);
1495
0
  case SC_PKCS15_TYPE_SKEY:
1496
0
    return sc_pkcs15_compare_id(&((struct sc_pkcs15_skey_info *) data)->id, id);
1497
919
  case SC_PKCS15_TYPE_AUTH:
1498
919
    return sc_pkcs15_compare_id(&((struct sc_pkcs15_auth_info *) data)->auth_id, id);
1499
0
  case SC_PKCS15_TYPE_DATA_OBJECT:
1500
0
    return sc_pkcs15_compare_id(&((struct sc_pkcs15_data_info *) data)->id, id);
1501
1.68k
  }
1502
0
  return 0;
1503
1.68k
}
1504
1505
1506
static int
1507
sc_obj_app_oid(struct sc_pkcs15_object *obj, const struct sc_object_id *app_oid)
1508
0
{
1509
0
  if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_DATA_OBJECT)
1510
0
    return sc_compare_oid(&((struct sc_pkcs15_data_info *) obj->data)->app_oid, app_oid);
1511
0
  return 0;
1512
0
}
1513
1514
1515
static int
1516
compare_obj_usage(struct sc_pkcs15_object *obj, unsigned int mask, unsigned int value)
1517
0
{
1518
0
  void    *data = obj->data;
1519
0
  unsigned int  usage;
1520
1521
0
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
1522
0
  case SC_PKCS15_TYPE_PRKEY:
1523
0
    usage = ((struct sc_pkcs15_prkey_info *) data)->usage;
1524
0
    break;
1525
0
  case SC_PKCS15_TYPE_PUBKEY:
1526
0
    usage = ((struct sc_pkcs15_pubkey_info *) data)->usage;
1527
0
    break;
1528
0
  default:
1529
0
    return 0;
1530
0
  }
1531
0
  return (usage & mask & value) != 0;
1532
0
}
1533
1534
1535
static int
1536
compare_obj_flags(struct sc_pkcs15_object *obj, unsigned int mask, unsigned int value)
1537
0
{
1538
0
  struct sc_pkcs15_auth_info *auth_info;
1539
0
  unsigned int  flags;
1540
1541
0
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
1542
0
  case SC_PKCS15_TYPE_AUTH:
1543
0
    auth_info = (struct sc_pkcs15_auth_info *) obj->data;
1544
0
    if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1545
0
      return 0;
1546
0
    flags = auth_info->attrs.pin.flags;
1547
0
    break;
1548
0
  default:
1549
0
    return 0;
1550
0
  }
1551
0
  return !((flags ^ value) & mask);
1552
0
}
1553
1554
1555
static int
1556
compare_obj_reference(struct sc_pkcs15_object *obj, int value)
1557
0
{
1558
0
  struct sc_pkcs15_auth_info *auth_info;
1559
0
  void    *data = obj->data;
1560
0
  int   reference;
1561
1562
0
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
1563
0
  case SC_PKCS15_TYPE_AUTH:
1564
0
    auth_info = (struct sc_pkcs15_auth_info *) obj->data;
1565
0
    if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1566
0
      return 0;
1567
0
    reference = auth_info->attrs.pin.reference;
1568
0
    break;
1569
0
  case SC_PKCS15_TYPE_PRKEY:
1570
0
    reference = ((struct sc_pkcs15_prkey_info *) data)->key_reference;
1571
0
    break;
1572
0
  default:
1573
0
    return 0;
1574
0
  }
1575
0
  return reference == value;
1576
0
}
1577
1578
1579
static int
1580
compare_obj_path(struct sc_pkcs15_object *obj, const struct sc_path *path)
1581
0
{
1582
0
  void *data = obj->data;
1583
1584
0
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
1585
0
  case SC_PKCS15_TYPE_PRKEY:
1586
0
    return sc_compare_path(&((struct sc_pkcs15_prkey_info *) data)->path, path);
1587
0
  case SC_PKCS15_TYPE_PUBKEY:
1588
0
    return sc_compare_path(&((struct sc_pkcs15_pubkey_info *) data)->path, path);
1589
0
  case SC_PKCS15_TYPE_SKEY:
1590
0
    return sc_compare_path(&((struct sc_pkcs15_skey_info *) data)->path, path);
1591
0
  case SC_PKCS15_TYPE_CERT:
1592
0
    return sc_compare_path(&((struct sc_pkcs15_cert_info *) data)->path, path);
1593
0
  case SC_PKCS15_TYPE_AUTH:
1594
0
    return sc_compare_path(&((struct sc_pkcs15_auth_info *) data)->path, path);
1595
0
  case SC_PKCS15_TYPE_DATA_OBJECT:
1596
0
    return sc_compare_path(&((struct sc_pkcs15_data_info *) data)->path, path);
1597
0
  }
1598
0
  return 0;
1599
0
}
1600
1601
1602
static int
1603
compare_obj_data_name(struct sc_pkcs15_object *obj, const char *app_label, const char *label)
1604
0
{
1605
0
  struct sc_pkcs15_data_info *cinfo = (struct sc_pkcs15_data_info *) obj->data;
1606
1607
0
  if (obj->type != SC_PKCS15_TYPE_DATA_OBJECT)
1608
0
    return 0;
1609
1610
0
  return !strncmp(cinfo->app_label, app_label, sizeof cinfo->app_label) &&
1611
0
    !strncmp(obj->label, label, sizeof obj->label);
1612
0
}
1613
1614
1615
static int
1616
compare_obj_key(struct sc_pkcs15_object *obj, void *arg)
1617
1.68k
{
1618
1.68k
  struct sc_pkcs15_search_key *sk = (struct sc_pkcs15_search_key *) arg;
1619
1620
1.68k
  if (sk->id && !compare_obj_id(obj, sk->id))
1621
784
    return 0;
1622
899
  if (sk->app_oid && !sc_obj_app_oid(obj, sk->app_oid))
1623
0
    return 0;
1624
899
  if (sk->usage_mask && !compare_obj_usage(obj, sk->usage_mask, sk->usage_value))
1625
0
    return 0;
1626
899
  if (sk->flags_mask && !compare_obj_flags(obj, sk->flags_mask, sk->flags_value))
1627
0
    return 0;
1628
899
  if (sk->match_reference && !compare_obj_reference(obj, sk->reference))
1629
0
    return 0;
1630
899
  if (sk->path && !compare_obj_path(obj, sk->path))
1631
0
    return 0;
1632
899
  if (
1633
899
    sk->app_label && sk->label &&
1634
0
    !compare_obj_data_name(obj, sk->app_label, sk->label)
1635
899
  ) {
1636
0
    return 0;
1637
0
  }
1638
1639
899
  return 1;
1640
899
}
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
156
{
1674
156
  return __sc_pkcs15_search_objects(p15card, 0, type,
1675
156
      func, func_arg, ret, ret_size);
1676
156
}
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.67k
{
1683
1.67k
  struct sc_pkcs15_search_key sk;
1684
1.67k
  int r;
1685
1686
1.67k
  memset(&sk, 0, sizeof(sk));
1687
1.67k
  sk.id = id;
1688
1689
1.67k
  r = __sc_pkcs15_search_objects(p15card, 0, type, compare_obj_key, &sk, out, 1);
1690
1.67k
  if (r < 0)
1691
0
    return r;
1692
1.67k
  if (r == 0)
1693
779
    return SC_ERROR_OBJECT_NOT_FOUND;
1694
899
  return 0;
1695
1.67k
}
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
991
{
1702
991
  return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_CERT, id, out);
1703
991
}
1704
1705
1706
int
1707
sc_pkcs15_find_prkey_by_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
1708
    struct sc_pkcs15_object **out)
1709
0
{
1710
0
  return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_PRKEY, id, out);
1711
0
}
1712
1713
1714
int
1715
sc_pkcs15_find_pubkey_by_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
1716
    struct sc_pkcs15_object **out)
1717
0
{
1718
0
  return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_PUBKEY, id, out);
1719
0
}
1720
1721
1722
int
1723
sc_pkcs15_find_skey_by_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
1724
    struct sc_pkcs15_object **out)
1725
0
{
1726
0
  return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_SKEY, id, out);
1727
0
}
1728
1729
1730
int
1731
sc_pkcs15_find_pin_by_auth_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
1732
    struct sc_pkcs15_object **out)
1733
687
{
1734
687
  return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_AUTH, id, out);
1735
687
}
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
38.5k
{
1926
38.5k
  struct sc_pkcs15_object *p = p15card->obj_list;
1927
1928
38.5k
  if (!obj)
1929
0
    return 0;
1930
38.5k
  obj->next = obj->prev = NULL;
1931
38.5k
  if (p15card->obj_list == NULL) {
1932
4.97k
    p15card->obj_list = obj;
1933
4.97k
    return 0;
1934
4.97k
  }
1935
572k
  while (p->next != NULL)
1936
538k
    p = p->next;
1937
33.5k
  p->next = obj;
1938
33.5k
  obj->prev = p;
1939
1940
33.5k
  return 0;
1941
38.5k
}
1942
1943
1944
void
1945
sc_pkcs15_remove_object(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj)
1946
0
{
1947
0
  if (!obj)
1948
0
    return;
1949
0
  else if (obj->prev == NULL)
1950
0
    p15card->obj_list = obj->next;
1951
0
  else
1952
0
    obj->prev->next = obj->next;
1953
0
  if (obj->next != NULL)
1954
0
    obj->next->prev = obj->prev;
1955
0
}
1956
1957
1958
static void
1959
sc_pkcs15_remove_objects(struct sc_pkcs15_card *p15card)
1960
27.1k
{
1961
27.1k
  struct sc_pkcs15_object *cur = NULL, *next = NULL;
1962
1963
27.1k
  if (!p15card || !p15card->obj_list)
1964
22.1k
    return;
1965
43.4k
  for (cur = p15card->obj_list; cur; cur = next)   {
1966
38.5k
    next = cur->next;
1967
38.5k
    sc_pkcs15_free_object(cur);
1968
38.5k
  }
1969
1970
4.97k
  p15card->obj_list = NULL;
1971
4.97k
}
1972
1973
1974
void
1975
sc_pkcs15_free_object(struct sc_pkcs15_object *obj)
1976
38.5k
{
1977
38.5k
  if (!obj)
1978
0
    return;
1979
38.5k
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
1980
4.16k
  case SC_PKCS15_TYPE_PRKEY:
1981
4.16k
    sc_pkcs15_free_prkey_info((sc_pkcs15_prkey_info_t *)obj->data);
1982
4.16k
    break;
1983
1.54k
  case SC_PKCS15_TYPE_PUBKEY:
1984
    /* This is normally passed to framework-pkcs15,
1985
     * but if something fails on the way, it would not get freed */
1986
1.54k
    if (obj->emulated) {
1987
1.44k
      sc_pkcs15_free_pubkey(obj->emulated);
1988
1.44k
    }
1989
1.54k
    sc_pkcs15_free_pubkey_info((sc_pkcs15_pubkey_info_t *)obj->data);
1990
1.54k
    break;
1991
3.20k
  case SC_PKCS15_TYPE_CERT:
1992
3.20k
    sc_pkcs15_free_cert_info((sc_pkcs15_cert_info_t *)obj->data);
1993
3.20k
    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
23.2k
  case SC_PKCS15_TYPE_DATA_OBJECT:
1998
23.2k
    sc_pkcs15_free_data_info((sc_pkcs15_data_info_t *)obj->data);
1999
23.2k
    break;
2000
6.33k
  case SC_PKCS15_TYPE_AUTH:
2001
6.33k
    sc_pkcs15_free_auth_info((sc_pkcs15_auth_info_t *)obj->data);
2002
6.33k
    break;
2003
0
  default:
2004
0
    free(obj->data);
2005
38.5k
  }
2006
2007
38.5k
  sc_pkcs15_free_object_content(obj);
2008
2009
38.5k
  free(obj);
2010
38.5k
}
2011
2012
2013
int
2014
sc_pkcs15_add_df(struct sc_pkcs15_card *p15card, unsigned int type, const sc_path_t *path)
2015
15.1k
{
2016
15.1k
  struct sc_pkcs15_df *p, *newdf;
2017
2018
15.1k
  newdf = calloc(1, sizeof(struct sc_pkcs15_df));
2019
15.1k
  if (newdf == NULL)
2020
0
    return SC_ERROR_OUT_OF_MEMORY;
2021
15.1k
  newdf->path = *path;
2022
15.1k
  newdf->type = type;
2023
2024
15.1k
  if (p15card->df_list == NULL) {
2025
5.11k
    p15card->df_list = newdf;
2026
5.11k
    return 0;
2027
5.11k
  }
2028
2029
10.0k
  p = p15card->df_list;
2030
318k
  while (p->next != NULL)
2031
308k
    p = p->next;
2032
10.0k
  p->next = newdf;
2033
10.0k
  newdf->prev = p;
2034
2035
10.0k
  return 0;
2036
15.1k
}
2037
2038
2039
static void
2040
sc_pkcs15_remove_dfs(struct sc_pkcs15_card *p15card)
2041
27.1k
{
2042
27.1k
  struct sc_pkcs15_df *cur = NULL, *next = NULL;
2043
2044
27.1k
  if (!p15card || !p15card->df_list)
2045
22.0k
    return;
2046
2047
20.2k
  for (cur = p15card->df_list; cur; cur = next)   {
2048
15.1k
    next = cur->next;
2049
15.1k
    free(cur);
2050
15.1k
  }
2051
2052
5.11k
  p15card->df_list = NULL;
2053
5.11k
}
2054
2055
2056
int
2057
sc_pkcs15_encode_df(struct sc_context *ctx, struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df,
2058
    unsigned char **buf_out, size_t *bufsize_out)
2059
0
{
2060
0
  unsigned char *buf = NULL, *tmp = NULL, *p;
2061
0
  size_t bufsize = 0, tmpsize;
2062
0
  const struct sc_pkcs15_object *obj;
2063
0
  int (* func)(struct sc_context *, const struct sc_pkcs15_object *nobj,
2064
0
         unsigned char **nbuf, size_t *nbufsize) = NULL;
2065
0
  int r;
2066
2067
0
  if (p15card == NULL || p15card->magic != SC_PKCS15_CARD_MAGIC) {
2068
0
    return SC_ERROR_INVALID_ARGUMENTS;
2069
0
  }
2070
0
  switch (df->type) {
2071
0
  case SC_PKCS15_PRKDF:
2072
0
    func = sc_pkcs15_encode_prkdf_entry;
2073
0
    break;
2074
0
  case SC_PKCS15_PUKDF:
2075
0
  case SC_PKCS15_PUKDF_TRUSTED:
2076
0
    func = sc_pkcs15_encode_pukdf_entry;
2077
0
    break;
2078
0
  case SC_PKCS15_SKDF:
2079
0
    func = sc_pkcs15_encode_skdf_entry;
2080
0
    break;
2081
0
  case SC_PKCS15_CDF:
2082
0
  case SC_PKCS15_CDF_TRUSTED:
2083
0
  case SC_PKCS15_CDF_USEFUL:
2084
0
    func = sc_pkcs15_encode_cdf_entry;
2085
0
    break;
2086
0
  case SC_PKCS15_DODF:
2087
0
    func = sc_pkcs15_encode_dodf_entry;
2088
0
    break;
2089
0
  case SC_PKCS15_AODF:
2090
0
    func = sc_pkcs15_encode_aodf_entry;
2091
0
    break;
2092
0
  }
2093
0
  if (func == NULL) {
2094
0
    sc_log(ctx, "unknown DF type: %d", df->type);
2095
0
    *buf_out = NULL;
2096
0
    *bufsize_out = 0;
2097
0
    return 0;
2098
0
  }
2099
0
  for (obj = p15card->obj_list; obj != NULL; obj = obj->next) {
2100
0
    if (obj->df != df)
2101
0
      continue;
2102
0
    r = func(ctx, obj, &tmp, &tmpsize);
2103
0
    if (r) {
2104
0
      free(tmp);
2105
0
      free(buf);
2106
0
      return r;
2107
0
    }
2108
0
    if (!tmpsize)
2109
0
      continue;
2110
0
    p = (u8 *) realloc(buf, bufsize + tmpsize);
2111
0
    if (!p) {
2112
0
      free(tmp);
2113
0
      free(buf);
2114
0
      return SC_ERROR_OUT_OF_MEMORY;
2115
0
    }
2116
0
    buf = p;
2117
0
    memcpy(buf + bufsize, tmp, tmpsize);
2118
0
    free(tmp);
2119
0
    tmp = NULL;
2120
0
    bufsize += tmpsize;
2121
0
  }
2122
0
  *buf_out = buf;
2123
0
  *bufsize_out = bufsize;
2124
2125
0
  return 0;
2126
0
}
2127
2128
2129
int
2130
sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df)
2131
1.64k
{
2132
1.64k
  struct sc_context *ctx = p15card->card->ctx;
2133
1.64k
  unsigned char *buf;
2134
1.64k
  const unsigned char *p;
2135
1.64k
  size_t bufsize;
2136
1.64k
  int r;
2137
1.64k
  struct sc_pkcs15_object *obj = NULL;
2138
1.64k
  int (* func)(struct sc_pkcs15_card *, struct sc_pkcs15_object *,
2139
1.64k
         const u8 **nbuf, size_t *nbufsize) = NULL;
2140
2141
1.64k
  sc_log(ctx, "called; path=%s, type=%d, enum=%d", sc_print_path(&df->path), df->type, df->enumerated);
2142
2143
1.64k
  if (df->enumerated)
2144
1.64k
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2145
2146
1.64k
  switch (df->type) {
2147
58
  case SC_PKCS15_PRKDF:
2148
58
    func = sc_pkcs15_decode_prkdf_entry;
2149
58
    break;
2150
1.23k
  case SC_PKCS15_PUKDF:
2151
1.23k
    func = sc_pkcs15_decode_pukdf_entry;
2152
1.23k
    break;
2153
0
  case SC_PKCS15_SKDF:
2154
0
    func = sc_pkcs15_decode_skdf_entry;
2155
0
    break;
2156
270
  case SC_PKCS15_CDF:
2157
270
  case SC_PKCS15_CDF_TRUSTED:
2158
270
  case SC_PKCS15_CDF_USEFUL:
2159
270
    func = sc_pkcs15_decode_cdf_entry;
2160
270
    break;
2161
0
  case SC_PKCS15_DODF:
2162
0
    func = sc_pkcs15_decode_dodf_entry;
2163
0
    break;
2164
79
  case SC_PKCS15_AODF:
2165
79
    func = sc_pkcs15_decode_aodf_entry;
2166
79
    break;
2167
1.64k
  }
2168
1.64k
  if (func == NULL) {
2169
0
    sc_log(ctx, "unknown DF type: %d", df->type);
2170
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
2171
0
  }
2172
1.64k
  r = sc_pkcs15_read_file(p15card, &df->path, &buf, &bufsize, 0);
2173
1.64k
  LOG_TEST_RET(ctx, r, "pkcs15 read file failed");
2174
2175
424
  p = buf;
2176
424
  while (bufsize && *p != 0x00) {
2177
2178
378
    obj = calloc(1, sizeof(struct sc_pkcs15_object));
2179
378
    if (obj == NULL) {
2180
0
      r = SC_ERROR_OUT_OF_MEMORY;
2181
0
      goto ret;
2182
0
    }
2183
378
    r = func(p15card, obj, &p, &bufsize);
2184
378
    if (r) {
2185
378
      free(obj);
2186
378
      if (r == SC_ERROR_ASN1_END_OF_CONTENTS) {
2187
41
        r = 0;
2188
41
        break;
2189
41
      }
2190
337
      sc_log(ctx, "%s: Error decoding DF entry", sc_strerror(r));
2191
337
      goto ret;
2192
378
    }
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
87
  };
2208
2209
87
  if (r > 0)
2210
0
    r = 0;
2211
424
ret:
2212
424
  df->enumerated = 1;
2213
424
  free(buf);
2214
424
  LOG_FUNC_RETURN(ctx, r);
2215
424
}
2216
2217
2218
int
2219
sc_pkcs15_add_unusedspace(struct sc_pkcs15_card *p15card, const struct sc_path *path,
2220
    const struct sc_pkcs15_id *auth_id)
2221
0
{
2222
0
  struct sc_context *ctx = p15card->card->ctx;
2223
0
  struct sc_pkcs15_unusedspace *p = p15card->unusedspace_list, *new_unusedspace;
2224
2225
0
  if (path->count == -1) {
2226
0
    char pbuf[SC_MAX_PATH_STRING_SIZE];
2227
2228
0
    int r = sc_path_print(pbuf, sizeof(pbuf), path);
2229
0
    if (r != SC_SUCCESS)
2230
0
      pbuf[0] = '\0';
2231
2232
0
    sc_log(ctx, "No offset and length present in path %s", pbuf);
2233
0
    return SC_ERROR_INVALID_ARGUMENTS;
2234
0
  }
2235
2236
0
  new_unusedspace = calloc(1, sizeof(sc_pkcs15_unusedspace_t));
2237
0
  if (new_unusedspace == NULL)
2238
0
    return SC_ERROR_OUT_OF_MEMORY;
2239
0
  new_unusedspace->path = *path;
2240
0
  if (auth_id != NULL)
2241
0
    new_unusedspace->auth_id = *auth_id;
2242
2243
0
  if (p15card->unusedspace_list == NULL) {
2244
0
    p15card->unusedspace_list = new_unusedspace;
2245
0
    return 0;
2246
0
  }
2247
0
  while (p->next != NULL)
2248
0
    p = p->next;
2249
0
  p->next = new_unusedspace;
2250
0
  new_unusedspace->prev = p;
2251
2252
0
  return 0;
2253
0
}
2254
2255
2256
void
2257
sc_pkcs15_remove_unusedspace(struct sc_pkcs15_card *p15card, struct sc_pkcs15_unusedspace *unusedspace)
2258
0
{
2259
0
  if (!unusedspace)
2260
0
    return;
2261
2262
0
  if (!unusedspace->prev)
2263
0
    p15card->unusedspace_list = unusedspace->next;
2264
0
  else
2265
0
    unusedspace->prev->next = unusedspace->next;
2266
2267
0
  if (unusedspace->next)
2268
0
    unusedspace->next->prev = unusedspace->prev;
2269
2270
0
  free(unusedspace);
2271
0
}
2272
2273
2274
static void
2275
sc_pkcs15_free_unusedspace(struct sc_pkcs15_card *p15card)
2276
12.3k
{
2277
12.3k
  struct sc_pkcs15_unusedspace *cur = NULL, *next = NULL;
2278
2279
12.3k
  if (!p15card || !p15card->unusedspace_list)
2280
12.3k
    return;
2281
0
  for (cur = p15card->unusedspace_list; cur; cur = next)   {
2282
0
    next = cur->next;
2283
0
    free(cur);
2284
0
  }
2285
2286
0
  p15card->unusedspace_list = NULL;
2287
0
}
2288
2289
2290
int
2291
sc_pkcs15_encode_unusedspace(struct sc_context *ctx, struct sc_pkcs15_card *p15card,
2292
       unsigned char **buf, size_t *buflen)
2293
0
{
2294
0
  struct sc_path dummy_path;
2295
0
  static const struct sc_asn1_entry c_asn1_unusedspace[] = {
2296
0
    { "UnusedSpace", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
2297
0
    { NULL, 0, 0, 0, NULL, NULL }
2298
0
  };
2299
0
  static const struct sc_asn1_entry c_asn1_unusedspace_values[] = {
2300
0
    { "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
2301
0
    { "authId", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
2302
0
    { NULL, 0, 0, 0, NULL, NULL }
2303
0
  };
2304
0
  struct sc_asn1_entry *asn1_unusedspace = NULL;
2305
0
  struct sc_asn1_entry *asn1_values = NULL;
2306
0
  int unusedspace_count = 0, r, c = 0;
2307
0
  struct sc_pkcs15_unusedspace *unusedspace = NULL;
2308
2309
0
  sc_format_path("3F00", &dummy_path);
2310
0
  dummy_path.index = dummy_path.count = 0;
2311
2312
0
  unusedspace = p15card->unusedspace_list;
2313
0
  for ( ; unusedspace != NULL; unusedspace = unusedspace->next)
2314
0
    unusedspace_count++;
2315
0
  if (unusedspace_count == 0) {
2316
    /* The standard says there has to be at least 1 entry,
2317
     * so we use a path with a length of 0 bytes */
2318
0
    r = sc_pkcs15_add_unusedspace(p15card, &dummy_path, NULL);
2319
0
    if (r)
2320
0
      return r;
2321
0
    unusedspace_count = 1;
2322
0
  }
2323
2324
0
  asn1_unusedspace = (struct sc_asn1_entry *)
2325
0
    malloc(sizeof(struct sc_asn1_entry) * (unusedspace_count + 1));
2326
0
  if (asn1_unusedspace == NULL) {
2327
0
    r = SC_ERROR_OUT_OF_MEMORY;
2328
0
    goto err;
2329
0
  }
2330
0
  asn1_values = (struct sc_asn1_entry *)
2331
0
    malloc(sizeof(struct sc_asn1_entry) * (unusedspace_count * 3));
2332
0
  if (asn1_values == NULL) {
2333
0
    r = SC_ERROR_OUT_OF_MEMORY;
2334
0
    goto err;
2335
0
  }
2336
2337
0
  for (unusedspace = p15card->unusedspace_list; unusedspace != NULL; unusedspace = unusedspace->next) {
2338
0
    sc_copy_asn1_entry(c_asn1_unusedspace, asn1_unusedspace + c);
2339
0
    sc_format_asn1_entry(asn1_unusedspace + c, asn1_values + 3*c, NULL, 1);
2340
0
    sc_copy_asn1_entry(c_asn1_unusedspace_values, asn1_values + 3*c);
2341
0
    sc_format_asn1_entry(asn1_values + 3*c, &unusedspace->path, NULL, 1);
2342
0
    sc_format_asn1_entry(asn1_values + 3*c+1, &unusedspace->auth_id, NULL,
2343
0
         unusedspace->auth_id.len > 0 ? 1 : 0);
2344
0
    c++;
2345
0
  }
2346
0
  asn1_unusedspace[c].name = NULL;
2347
2348
0
  r = sc_asn1_encode(ctx, asn1_unusedspace, buf, buflen);
2349
2350
0
err:
2351
0
  if (asn1_values != NULL)
2352
0
    free(asn1_values);
2353
0
  if (asn1_unusedspace != NULL)
2354
0
    free(asn1_unusedspace);
2355
2356
  /* If we added the dummy entry, remove it now */
2357
0
  if (unusedspace_count == 1 && sc_compare_path(&p15card->unusedspace_list->path, &dummy_path))
2358
0
    sc_pkcs15_remove_unusedspace(p15card, p15card->unusedspace_list);
2359
2360
0
  return r;
2361
0
}
2362
2363
2364
int
2365
sc_pkcs15_parse_unusedspace(const unsigned char *buf, size_t buflen, struct sc_pkcs15_card *p15card)
2366
0
{
2367
0
  const unsigned char *p = buf;
2368
0
  size_t left = buflen;
2369
0
  int r;
2370
0
  struct sc_path path;
2371
0
  struct sc_pkcs15_id auth_id;
2372
0
  struct sc_asn1_entry asn1_unusedspace[] = {
2373
0
    { "UnusedSpace", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
2374
0
    { NULL, 0, 0, 0, NULL, NULL }
2375
0
  };
2376
0
  struct sc_asn1_entry asn1_unusedspace_values[] = {
2377
0
    { "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
2378
0
    { "authId", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
2379
0
    { NULL, 0, 0, 0, NULL, NULL }
2380
0
  };
2381
2382
  /* Clean the list if already present */
2383
0
  sc_pkcs15_free_unusedspace(p15card);
2384
2385
0
  sc_format_asn1_entry(asn1_unusedspace, asn1_unusedspace_values, NULL, 1);
2386
0
  sc_format_asn1_entry(asn1_unusedspace_values, &path, NULL, 1);
2387
0
  sc_format_asn1_entry(asn1_unusedspace_values+1, &auth_id, NULL, 0);
2388
2389
0
  while (left > 0) {
2390
0
    memset(&auth_id, 0, sizeof(auth_id));
2391
0
    r = sc_asn1_decode(p15card->card->ctx, asn1_unusedspace, p, left, &p, &left);
2392
0
    if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
2393
0
      break;
2394
0
    if (r < 0)
2395
0
      return r;
2396
    /* If the path length is 0, it's a dummy path then don't add it.
2397
     * If the path length isn't included (-1) then it's against the standard
2398
     *   but we'll just ignore it instead of returning an error. */
2399
0
    if (path.count > 0 && p15card->file_app) {
2400
0
      r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &path);
2401
0
      if (r < 0)
2402
0
        return r;
2403
0
      r = sc_pkcs15_add_unusedspace(p15card, &path, &auth_id);
2404
0
      if (r)
2405
0
        return r;
2406
0
    }
2407
0
  }
2408
2409
0
  p15card->unusedspace_read = 1;
2410
2411
0
  return 0;
2412
0
}
2413
2414
static int decompress_file(sc_card_t *card, unsigned char *buf, size_t buflen,
2415
    unsigned char **out, size_t *outlen, unsigned long flags)
2416
304
{
2417
304
  LOG_FUNC_CALLED(card->ctx);
2418
304
#ifdef ENABLE_ZLIB
2419
304
  int rv = SC_SUCCESS;
2420
304
  int method = 0;
2421
2422
304
  if (flags & SC_FILE_FLAG_COMPRESSED_GZIP) {
2423
0
    method = COMPRESSION_GZIP;
2424
304
  } else if (flags & SC_FILE_FLAG_COMPRESSED_ZLIB) {
2425
0
    method = COMPRESSION_ZLIB;
2426
304
  } else {
2427
304
    method = COMPRESSION_AUTO;
2428
304
  }
2429
2430
304
  rv = sc_decompress_alloc(out, outlen, buf, buflen, method);
2431
304
  if (rv != SC_SUCCESS) {
2432
176
    sc_log(card->ctx,  "Decompression failed: %d", rv);
2433
176
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
2434
176
  }
2435
128
  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
128
}
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
13.9k
{
2468
13.9k
  struct sc_context *ctx;
2469
13.9k
  struct sc_file *file = NULL;
2470
13.9k
  unsigned char *data = NULL;
2471
13.9k
  size_t  len = 0, offset = 0;
2472
13.9k
  int r;
2473
2474
13.9k
  if (p15card == NULL || p15card->card == NULL || in_path == NULL || buf == NULL) {
2475
0
    return SC_ERROR_INVALID_ARGUMENTS;
2476
0
  }
2477
13.9k
  ctx = p15card->card->ctx;
2478
2479
13.9k
  LOG_FUNC_CALLED(ctx);
2480
13.9k
  sc_log(ctx, "path=%s, index=%u, count=%d", sc_print_path(in_path), in_path->index, in_path->count);
2481
2482
13.9k
  r = -1; /* file state: not in cache */
2483
13.9k
  if (p15card->opts.use_file_cache
2484
6.24k
      && ((p15card->opts.use_file_cache & SC_PKCS15_OPTS_CACHE_ALL_FILES) || !private_data)) {
2485
6.24k
    r = sc_pkcs15_read_cached_file(p15card, in_path, &data, &len);
2486
2487
6.24k
    if (!r && in_path->aid.len > 0 && in_path->len >= 2)   {
2488
75
      struct sc_path parent = *in_path;
2489
2490
75
      parent.len -= 2;
2491
75
      parent.type = SC_PATH_TYPE_PATH;
2492
75
      r = sc_select_file(p15card->card, &parent, NULL);
2493
75
    }
2494
6.24k
  }
2495
2496
13.9k
  if (r) {
2497
13.3k
    r = sc_lock(p15card->card);
2498
13.3k
    if (r)
2499
0
      goto fail;
2500
13.3k
    r = sc_select_file(p15card->card, in_path, &file);
2501
13.3k
    if (r)
2502
9.57k
      goto fail_unlock;
2503
2504
    /* Handle the case where the ASN.1 Path object specified
2505
     * index and length values */
2506
2507
3.78k
    if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) {
2508
2509
      // in_path->index: record_no
2510
      // in_path->count: ignored!
2511
2512
99
      if(file->record_length > 0) {
2513
79
        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
79
        } else {
2517
79
          len = file->record_length;
2518
79
        }
2519
79
      } else {
2520
20
        len = MAX_FILE_SIZE;
2521
20
      }
2522
2523
99
      if ((in_path->index <= 0) || (in_path->index > (int)(file->record_count))) {
2524
70
        sc_log(ctx, "  record number out of bounds: %d", in_path->index);
2525
70
        r = SC_ERROR_RECORD_NOT_FOUND;
2526
70
        goto fail_unlock;
2527
70
      }
2528
2529
3.68k
    } else {
2530
2531
3.68k
      if (in_path->count < 0) {
2532
2.11k
        if (file->size)
2533
1.95k
          len = (file->size > MAX_FILE_SIZE)? MAX_FILE_SIZE:file->size;
2534
165
        else
2535
165
          len = 1024;
2536
2.11k
        offset = 0;
2537
2.11k
      }
2538
1.56k
      else {
2539
1.56k
        offset = in_path->index;
2540
1.56k
        len = in_path->count;
2541
        /* Make sure we're within proper bounds */
2542
1.56k
        if (offset >= file->size || offset + len > file->size) {
2543
45
          r = SC_ERROR_INVALID_ASN1_OBJECT;
2544
45
          goto fail_unlock;
2545
45
        }
2546
1.56k
      }
2547
3.68k
    }
2548
2549
3.66k
    free(data);
2550
3.66k
    data = malloc(len);
2551
3.66k
    if (data == NULL) {
2552
0
      r = SC_ERROR_OUT_OF_MEMORY;
2553
0
      goto fail_unlock;
2554
0
    }
2555
2556
3.66k
    if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE_TLV) {
2557
57
      unsigned int i;
2558
57
      size_t l, record_len;
2559
57
      unsigned char *head = data;
2560
2561
533
      for (i=1; ; i++) {
2562
533
        l = len - (head - data);
2563
533
        if (l > 256) {
2564
452
          l = 256;
2565
452
        }
2566
533
        r = sc_read_record(p15card->card, i, 0, head, l, SC_RECORD_BY_REC_NR);
2567
533
        if (r == SC_ERROR_RECORD_NOT_FOUND)
2568
1
          break;
2569
532
        if (r < 0) {
2570
51
          goto fail_unlock;
2571
51
        }
2572
481
        if (r < 2)
2573
4
          break;
2574
477
        record_len = head[1];
2575
477
        if (record_len != 0xff) {
2576
343
          memmove(head, head+2, r-2);
2577
343
          head += (r-2);
2578
343
        }
2579
134
        else {
2580
134
          if (r < 4)
2581
1
            break;
2582
133
          memmove(head, head+4, r-4);
2583
133
          head += (r-4);
2584
133
        }
2585
477
      }
2586
6
      len = head-data;
2587
6
    }
2588
3.61k
    else if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) {
2589
29
      r = sc_read_record(p15card->card, in_path->index, (unsigned)offset, data, len, SC_RECORD_BY_REC_NR);
2590
29
      if (r < 0) {
2591
6
        goto fail_unlock;
2592
6
      }
2593
      /* sc_read_record may return less than requested */
2594
23
      len = r;
2595
23
    }
2596
3.58k
    else {
2597
3.58k
      unsigned long flags = 0;
2598
3.58k
      r = sc_read_binary(p15card->card, (unsigned)offset, data, len, &flags);
2599
3.58k
      if (r < 0) {
2600
1.01k
        goto fail_unlock;
2601
1.01k
      }
2602
      /* sc_read_binary may return less than requested */
2603
2.56k
      len = r;
2604
2605
2.56k
      if (flags & SC_FILE_FLAG_COMPRESSED_AUTO
2606
2.26k
          || flags & SC_FILE_FLAG_COMPRESSED_ZLIB
2607
2.26k
          || flags & SC_FILE_FLAG_COMPRESSED_GZIP) {
2608
304
        unsigned char *decompressed_buf = NULL;
2609
304
        size_t decompressed_len = 0;
2610
304
        r = decompress_file(p15card->card, data, len, &decompressed_buf, &decompressed_len, flags);
2611
304
        if (r != SC_SUCCESS) {
2612
176
          goto fail_unlock;
2613
176
        }
2614
128
        free(data);
2615
128
        data = decompressed_buf;
2616
128
        len = decompressed_len;
2617
128
      }
2618
2.56k
    }
2619
2.42k
    sc_unlock(p15card->card);
2620
2621
2.42k
    sc_file_free(file);
2622
2623
2.42k
    if (len && p15card->opts.use_file_cache
2624
403
        && ((p15card->opts.use_file_cache & SC_PKCS15_OPTS_CACHE_ALL_FILES) || !private_data)) {
2625
403
      sc_pkcs15_cache_file(p15card, in_path, data, len);
2626
403
    }
2627
2.42k
    if (len == 0) {
2628
221
      free(data);
2629
221
      data = NULL;
2630
221
    }
2631
2.42k
  }
2632
2.99k
  *buf = data;
2633
2.99k
  *buflen = len;
2634
2.99k
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2635
2636
10.9k
fail_unlock:
2637
10.9k
  sc_unlock(p15card->card);
2638
10.9k
fail:
2639
10.9k
  free(data);
2640
10.9k
  sc_file_free(file);
2641
10.9k
  LOG_FUNC_RETURN(ctx, r);
2642
10.9k
}
2643
2644
2645
int
2646
sc_pkcs15_compare_id(const struct sc_pkcs15_id *id1, const struct sc_pkcs15_id *id2)
2647
5.80k
{
2648
5.80k
  if (id1 == NULL || id2 == NULL)
2649
0
    return 0;
2650
5.80k
  if (id1->len != id2->len)
2651
3.06k
    return 0;
2652
2.74k
  return memcmp(id1->value, id2->value, id1->len) == 0;
2653
5.80k
}
2654
2655
2656
void
2657
sc_pkcs15_format_id(const char *str, struct sc_pkcs15_id *id)
2658
93.1k
{
2659
93.1k
  size_t len;
2660
2661
93.1k
  if (!id)
2662
0
    return;
2663
93.1k
  len = sizeof(id->value);
2664
2665
93.1k
  if (sc_hex_to_bin(str, id->value, &len) != SC_SUCCESS)
2666
0
    id->len = 0;
2667
93.1k
  else
2668
93.1k
    id->len = len;
2669
93.1k
}
2670
2671
2672
const char *
2673
sc_pkcs15_print_id(const struct sc_pkcs15_id *id)
2674
505
{
2675
505
  static char buffer[256];
2676
2677
505
  sc_bin_to_hex(id->value, id->len, buffer, sizeof(buffer), '\0');
2678
505
  return buffer;
2679
505
}
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
17.0k
{
2693
  /* nothing to do if child has valid 'aid' */
2694
17.0k
  if (child->aid.len)
2695
0
    return SC_SUCCESS;
2696
2697
17.0k
  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
17.0k
  else if (parent->type == SC_PATH_TYPE_DF_NAME)   {
2713
    /* child inherits parent's 'DF NAME' as 'aid' */
2714
115
    if (parent->len > sizeof(child->aid.value))
2715
0
      return SC_ERROR_WRONG_LENGTH;
2716
2717
115
    memcpy(child->aid.value, parent->value, parent->len);
2718
115
    child->aid.len = parent->len;
2719
2720
115
    return SC_SUCCESS;
2721
115
  }
2722
2723
  /* a 0 length path stays a 0 length path */
2724
16.9k
  if (child->len == 0)
2725
92
    return SC_SUCCESS;
2726
2727
16.8k
  if (sc_compare_path_prefix(sc_get_mf_path(), child))
2728
42
    return SC_SUCCESS;
2729
2730
16.8k
  return sc_concatenate_path(child, parent, child);
2731
16.8k
}
2732
2733
2734
void sc_pkcs15_free_object_content(struct sc_pkcs15_object *obj)
2735
39.2k
{
2736
39.2k
  if (obj->content.value && obj->content.len) {
2737
711
    if (obj->content_free) {
2738
711
      obj->content_free(obj->content.value, obj->content.len);
2739
711
    } else {
2740
0
      free(obj->content.value);
2741
0
    }
2742
711
  }
2743
39.2k
  obj->content.value = NULL;
2744
39.2k
  obj->content.len = 0;
2745
39.2k
}
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
711
{
2752
711
  unsigned char *tmp_buf;
2753
2754
711
  if (!obj)
2755
0
    return SC_ERROR_INVALID_ARGUMENTS;
2756
2757
711
  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
711
  if (SC_PKCS15_TYPE_AUTH & obj->type
2766
0
      || SC_PKCS15_TYPE_SKEY & obj->type
2767
711
      || SC_PKCS15_TYPE_PRKEY & obj->type) {
2768
711
    tmp_buf = sc_mem_secure_alloc(len);
2769
711
    obj->content_free = sc_mem_secure_free;
2770
711
  } else {
2771
0
    tmp_buf = malloc(len);
2772
0
  }
2773
711
  if (!tmp_buf)
2774
0
    return SC_ERROR_OUT_OF_MEMORY;
2775
2776
711
  memcpy(tmp_buf, value, len);
2777
2778
711
  sc_pkcs15_free_object_content(obj);
2779
2780
711
  obj->content.value = tmp_buf;
2781
711
  obj->content.len = len;
2782
2783
711
  return SC_SUCCESS;
2784
711
}
2785
2786
2787
struct sc_supported_algo_info *
2788
sc_pkcs15_get_supported_algo(struct sc_pkcs15_card *p15card, unsigned operation, unsigned mechanism)
2789
0
{
2790
0
  struct sc_context *ctx = p15card->card->ctx;
2791
0
  struct sc_supported_algo_info *info = NULL;
2792
0
  int ii;
2793
2794
0
  for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference; ii++)
2795
0
    if ((p15card->tokeninfo->supported_algos[ii].operations & operation)
2796
0
        && (p15card->tokeninfo->supported_algos[ii].mechanism == mechanism))
2797
0
      break;
2798
2799
0
  if (ii < SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference)   {
2800
0
    info = &p15card->tokeninfo->supported_algos[ii];
2801
0
    sc_log(ctx, "found supported algorithm (ref:%X,mech:%X,ops:%X,algo_ref:%X)",
2802
0
        info->reference, info->mechanism, info->operations, info->algo_ref);
2803
0
  }
2804
2805
0
  return info;
2806
0
}
2807
2808
struct sc_supported_algo_info *
2809
sc_pkcs15_get_specific_supported_algo(struct sc_pkcs15_card *p15card, unsigned operation, unsigned mechanism, const struct sc_object_id *algo_oid)
2810
0
{
2811
0
  struct sc_context *ctx = p15card->card->ctx;
2812
0
  struct sc_supported_algo_info *info = NULL;
2813
0
  int ii;
2814
2815
0
  if (algo_oid == NULL)
2816
0
    return NULL;
2817
2818
0
  for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference; ii++)
2819
0
    if ((p15card->tokeninfo->supported_algos[ii].operations & operation)
2820
0
        && (p15card->tokeninfo->supported_algos[ii].mechanism == mechanism)
2821
0
        && sc_compare_oid(algo_oid, &p15card->tokeninfo->supported_algos[ii].algo_id) == 1)
2822
0
      break;
2823
2824
0
  if (ii < SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference)   {
2825
0
    info = &p15card->tokeninfo->supported_algos[ii];
2826
0
    sc_log(ctx, "found supported algorithm (ref:%X,mech:%X,ops:%X,algo_ref:%X)",
2827
0
        info->reference, info->mechanism, info->operations, info->algo_ref);
2828
0
  }
2829
2830
0
  return info;
2831
0
}
2832
2833
int
2834
sc_pkcs15_get_generalized_time(struct sc_context *ctx, char **out)
2835
0
{
2836
0
#ifdef HAVE_GETTIMEOFDAY
2837
0
  struct timeval tv;
2838
0
#endif
2839
0
  struct tm tm;
2840
0
  time_t t;
2841
2842
0
  if (!ctx || !out)
2843
0
    return SC_ERROR_INVALID_ARGUMENTS;
2844
0
  *out = NULL;
2845
2846
0
#ifdef HAVE_GETTIMEOFDAY
2847
0
  gettimeofday(&tv, NULL);
2848
0
  t = tv.tv_sec;
2849
#else
2850
  t = time(NULL);
2851
#endif
2852
2853
#ifdef _WIN32
2854
  if (0 != gmtime_s(&tm, &t))
2855
    LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
2856
#else
2857
0
  if (NULL == gmtime_r(&t, &tm))
2858
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
2859
0
#endif
2860
2861
0
  *out = calloc(1, 16);
2862
0
  if (*out == NULL)
2863
0
    LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "memory failure");
2864
2865
  /* print time in generalized time format */
2866
0
  if (!strftime(*out, 16, "%Y%m%d%H%M%SZ", &tm)) {
2867
0
    free(*out);
2868
0
    LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "strftime failed");
2869
0
  }
2870
2871
0
  return SC_SUCCESS;
2872
0
}
2873
2874
2875
int
2876
sc_pkcs15_add_supported_algo_ref(struct sc_pkcs15_object *obj, struct sc_supported_algo_info *algo)
2877
0
{
2878
0
  unsigned int ii, *algo_refs = NULL;
2879
2880
0
  if (!algo)
2881
0
    return SC_SUCCESS;
2882
2883
0
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
2884
0
  case SC_PKCS15_TYPE_PRKEY:
2885
0
    algo_refs = ((struct sc_pkcs15_prkey_info *)obj->data)->algo_refs;
2886
0
    break;
2887
0
  case SC_PKCS15_TYPE_PUBKEY:
2888
0
    algo_refs = ((struct sc_pkcs15_pubkey_info *)obj->data)->algo_refs;
2889
0
    break;
2890
0
  case SC_PKCS15_TYPE_SKEY:
2891
0
    algo_refs = ((struct sc_pkcs15_skey_info *)obj->data)->algo_refs;
2892
0
    break;
2893
0
  }
2894
0
  if (!algo_refs)
2895
0
    return SC_ERROR_NOT_SUPPORTED;
2896
2897
0
  for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS && *(algo_refs + ii);ii++)
2898
0
    if (*(algo_refs + ii) == algo->reference)
2899
0
      return SC_SUCCESS;
2900
2901
0
  for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS;ii++)   {
2902
0
    if (*(algo_refs + ii) == 0)   {
2903
0
      *(algo_refs + ii) = algo->reference;
2904
0
      return SC_SUCCESS;
2905
0
    }
2906
0
  }
2907
2908
0
  return SC_ERROR_TOO_MANY_OBJECTS;
2909
0
}
2910
2911
2912
int
2913
sc_pkcs15_get_object_id(const struct sc_pkcs15_object *obj, struct sc_pkcs15_id *out)
2914
0
{
2915
0
  if (!obj || !out)
2916
0
    return SC_ERROR_INVALID_ARGUMENTS;
2917
2918
0
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
2919
0
  case SC_PKCS15_TYPE_CERT:
2920
0
    *out = ((struct sc_pkcs15_cert_info *) obj->data)->id;
2921
0
    break;
2922
0
  case SC_PKCS15_TYPE_PRKEY:
2923
0
    *out = ((struct sc_pkcs15_prkey_info *) obj->data)->id;
2924
0
    break;
2925
0
  case SC_PKCS15_TYPE_PUBKEY:
2926
0
    *out = ((struct sc_pkcs15_pubkey_info *) obj->data)->id;
2927
0
    break;
2928
0
  case SC_PKCS15_TYPE_SKEY:
2929
0
    *out = ((struct sc_pkcs15_skey_info *) obj->data)->id;
2930
0
    break;
2931
0
  case SC_PKCS15_TYPE_AUTH:
2932
0
    *out = ((struct sc_pkcs15_auth_info *) obj->data)->auth_id;
2933
0
    break;
2934
0
  case SC_PKCS15_TYPE_DATA_OBJECT:
2935
0
    *out = ((struct sc_pkcs15_data_info *) obj->data)->id;
2936
0
    break;
2937
0
  default:
2938
0
    return SC_ERROR_NOT_SUPPORTED;
2939
0
  }
2940
2941
0
  return SC_SUCCESS;
2942
0
}
2943
2944
/*
2945
 * Simplified GUID serializing.
2946
 * Ex. {3F2504E0-4F89-11D3-9A0C-0305E82C3301}
2947
 *
2948
 * There is no variant, version number and other special meaning fields
2949
 *  that are described in RFC-4122 .
2950
 */
2951
int
2952
sc_pkcs15_serialize_guid(unsigned char *in, size_t in_size, unsigned flags,
2953
    char *out, size_t out_size)
2954
0
{
2955
0
  int ii, jj, offs = 0;
2956
2957
0
  if (in_size < 16)
2958
0
    return SC_ERROR_BUFFER_TOO_SMALL;
2959
0
  if (out_size < 39)
2960
0
    return SC_ERROR_BUFFER_TOO_SMALL;
2961
2962
0
  *out = '\0';
2963
0
  if (!flags)
2964
0
    strcpy(out, "{");
2965
0
  for (ii=0; ii<4; ii++)
2966
0
    sprintf(out + strlen(out), "%02x", *(in + offs++));
2967
0
  for (jj=0; jj<3; jj++)   {
2968
0
    strcat(out, "-");
2969
0
    for (ii=0; ii<2; ii++)
2970
0
      sprintf(out + strlen(out), "%02x", *(in + offs++));
2971
0
  }
2972
0
  strcat(out, "-");
2973
0
  for (ii=0; ii<6; ii++)
2974
0
    sprintf(out + strlen(out), "%02x", *(in + offs++));
2975
0
  if (!flags)
2976
0
    strcat(out, "}");
2977
2978
0
  return SC_SUCCESS;
2979
0
}
2980
2981
2982
int
2983
sc_pkcs15_get_object_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj,
2984
    unsigned flags, unsigned char *out, size_t *out_size)
2985
0
{
2986
0
  struct sc_context *ctx = p15card->card->ctx;
2987
0
  struct sc_serial_number serialnr;
2988
0
  struct sc_pkcs15_id  id;
2989
0
  unsigned char guid_bin[SC_PKCS15_MAX_ID_SIZE + SC_MAX_SERIALNR];
2990
0
  int rv;
2991
0
  size_t guid_bin_size;
2992
2993
0
  LOG_FUNC_CALLED(ctx);
2994
0
  if(!out || !out_size)
2995
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
2996
2997
0
  if (p15card->ops.get_guid)   {
2998
0
    rv = p15card->ops.get_guid(p15card, obj, out, out_size);
2999
0
    LOG_FUNC_RETURN(ctx, rv);
3000
0
  }
3001
3002
0
  rv = sc_pkcs15_aux_get_md_guid(p15card, obj, flags, out, out_size);
3003
0
  if (rv == SC_SUCCESS)
3004
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
3005
0
  else if (rv != SC_ERROR_NOT_SUPPORTED)
3006
0
    LOG_TEST_RET(ctx, rv, "Failed to get alternative object GUID");
3007
3008
0
  memset(out, 0, *out_size);
3009
3010
0
  rv = sc_pkcs15_get_object_id(obj, &id);
3011
0
  LOG_TEST_RET(ctx, rv, "Cannot get object's ID");
3012
3013
0
  if (p15card->tokeninfo && p15card->tokeninfo->serial_number)   {
3014
    /* The serial from EF(TokenInfo) is preferred because of the
3015
     * "--serial" parameter of pkcs15-init. */
3016
0
    serialnr.len = SC_MAX_SERIALNR;
3017
0
    rv = sc_hex_to_bin(p15card->tokeninfo->serial_number, serialnr.value, &serialnr.len);
3018
0
    if (rv) {
3019
      /* Fallback in case hex_to_bin fails due to unexpected characters */
3020
0
      serialnr.len = strlen(p15card->tokeninfo->serial_number);
3021
0
      if (serialnr.len > SC_MAX_SERIALNR)
3022
0
        serialnr.len = SC_MAX_SERIALNR;
3023
3024
0
      memcpy(serialnr.value, p15card->tokeninfo->serial_number, serialnr.len);
3025
0
    }
3026
0
  } else if (p15card->card->serialnr.len)   {
3027
0
    serialnr = p15card->card->serialnr;
3028
0
  } else   {
3029
0
    rv = sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &serialnr);
3030
0
    LOG_TEST_RET(ctx, rv, "'GET_SERIALNR' CTL failed and other serial numbers not present");
3031
0
  }
3032
3033
0
  memset(guid_bin, 0, sizeof(guid_bin));
3034
0
  memcpy(guid_bin, id.value, id.len);
3035
0
  memcpy(guid_bin + id.len, serialnr.value, serialnr.len);
3036
0
  guid_bin_size = id.len + serialnr.len;
3037
3038
  /*
3039
   * If OpenSSL is available (SHA1), then rather use the hash of the data
3040
   * - this also protects against data being too short
3041
   */
3042
0
#ifdef ENABLE_OPENSSL
3043
0
  SHA1(guid_bin, guid_bin_size, guid_bin);
3044
0
  guid_bin_size = SHA_DIGEST_LENGTH;
3045
#else
3046
  /* If guid_bin has a size larger than 16 bytes
3047
   * force the remaining bytes up to 16 bytes to be zero
3048
   * so sc_pkcs15_serialize_guid won't fail because the size is less than 16
3049
   */
3050
  if (guid_bin_size < 16)
3051
    guid_bin_size = 16;
3052
#endif
3053
3054
0
  rv = sc_pkcs15_serialize_guid(guid_bin, guid_bin_size, flags, (char *)out, *out_size);
3055
0
  LOG_TEST_RET(ctx, rv, "Serialize GUID error");
3056
3057
0
  *out_size = strlen((char *)out);
3058
0
  LOG_FUNC_RETURN(ctx, rv);
3059
0
}
3060
3061
3062
static int
3063
sc_pkcs15_aux_get_md_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj,
3064
    unsigned flags,
3065
    unsigned char *out, size_t *out_size)
3066
0
{
3067
0
  struct sc_context *ctx = p15card->card->ctx;
3068
0
  struct sc_pkcs15_prkey_info *prkey_info = NULL;
3069
0
  int rv;
3070
3071
0
  LOG_FUNC_CALLED(ctx);
3072
0
  if(!out || !out_size)
3073
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
3074
3075
0
  if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY)
3076
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
3077
3078
0
  prkey_info = (struct sc_pkcs15_prkey_info *)obj->data;
3079
0
  if (!prkey_info->aux_data || prkey_info->aux_data->type != SC_AUX_DATA_TYPE_MD_CMAP_RECORD)
3080
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
3081
3082
0
  rv = sc_aux_data_get_md_guid(ctx, prkey_info->aux_data, flags, out, out_size);
3083
0
  LOG_FUNC_RETURN(ctx, rv);
3084
0
}
3085
3086
3087
void
3088
sc_pkcs15_free_key_params(struct sc_pkcs15_key_params *params)
3089
6.05k
{
3090
6.05k
  if (!params)
3091
0
    return;
3092
6.05k
  if (params->data && params->free_params)
3093
0
    params->free_params(params->data);
3094
6.05k
  else if (params->data)
3095
0
    free(params->data);
3096
3097
  params->data = NULL;
3098
6.05k
}
3099