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