Coverage Report

Created: 2026-10-28 06:52

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