Coverage Report

Created: 2026-03-01 06:54

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