1 /*
2  * sc.c: 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 #if HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include <stdio.h>
26 #include <ctype.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <assert.h>
30 #ifdef HAVE_SYS_MMAN_H
31 #include <sys/mman.h>
32 #endif
33 #ifdef ENABLE_OPENSSL
34 #include <openssl/crypto.h>     /* for OPENSSL_cleanse */
35 #endif
36 
37 
38 #include "internal.h"
39 
40 #ifdef PACKAGE_VERSION
41 static const char *sc_version = PACKAGE_VERSION;
42 #else
43 static const char *sc_version = "(undef)";
44 #endif
45 
46 #ifdef _WIN32
47 #include <windows.h>
48 #define PAGESIZE 0
49 #else
50 #include <sys/mman.h>
51 #include <limits.h>
52 #include <unistd.h>
53 #ifndef PAGESIZE
54 #define PAGESIZE 0
55 #endif
56 #endif
57 static size_t page_size = PAGESIZE;
58 
sc_get_version(void)59 const char *sc_get_version(void)
60 {
61     return sc_version;
62 }
63 
sc_hex_to_bin(const char * in,u8 * out,size_t * outlen)64 int sc_hex_to_bin(const char *in, u8 *out, size_t *outlen)
65 {
66 	const char *sc_hex_to_bin_separators = " :";
67 	if (in == NULL || out == NULL || outlen == NULL) {
68 		return SC_ERROR_INVALID_ARGUMENTS;
69 	}
70 
71 	int byte_needs_nibble = 0;
72 	int r = SC_SUCCESS;
73 	size_t left = *outlen;
74 	u8 byte = 0;
75 	while (*in != '\0' && 0 != left) {
76 		char c = *in++;
77 		u8 nibble;
78 		if      ('0' <= c && c <= '9')
79 			nibble = c - '0';
80 		else if ('a' <= c && c <= 'f')
81 			nibble = c - 'a' + 10;
82 		else if ('A' <= c && c <= 'F')
83 			nibble = c - 'A' + 10;
84 		else {
85 			if (strchr(sc_hex_to_bin_separators, (int) c))
86 				continue;
87 			r = SC_ERROR_INVALID_ARGUMENTS;
88 			goto err;
89 		}
90 
91 		if (byte_needs_nibble) {
92 			byte |= nibble;
93 			*out++ = (u8) byte;
94 			left--;
95 			byte_needs_nibble = 0;
96 		} else {
97 			byte  = nibble << 4;
98 			byte_needs_nibble = 1;
99 		}
100 	}
101 
102 	if (left == *outlen && 1 == byte_needs_nibble && 0 != left) {
103 		/* no output written so far, but we have a valid nibble in the upper
104 		 * bits. Allow this special case. */
105 		*out = (u8) byte>>4;
106 		left--;
107 		byte_needs_nibble = 0;
108 	}
109 
110 	/* for ease of implementation we only accept completely hexed bytes. */
111 	if (byte_needs_nibble) {
112 		r = SC_ERROR_INVALID_ARGUMENTS;
113 		goto err;
114 	}
115 
116 	/* skip all trailing separators to see if we missed something */
117 	while (*in != '\0') {
118 		if (NULL == strchr(sc_hex_to_bin_separators, (int) *in))
119 			break;
120 		in++;
121 	}
122 	if (*in != '\0') {
123 		r = SC_ERROR_BUFFER_TOO_SMALL;
124 		goto err;
125 	}
126 
127 err:
128 	*outlen -= left;
129 	return r;
130 }
131 
sc_bin_to_hex(const u8 * in,size_t in_len,char * out,size_t out_len,int in_sep)132 int sc_bin_to_hex(const u8 *in, size_t in_len, char *out, size_t out_len,
133 				  int in_sep)
134 {
135 	if (in == NULL || out == NULL) {
136 		return SC_ERROR_INVALID_ARGUMENTS;
137 	}
138 
139 	if (in_sep > 0) {
140 		if (out_len < in_len*3 || out_len < 1)
141 			return SC_ERROR_BUFFER_TOO_SMALL;
142 	} else {
143 		if (out_len < in_len*2 + 1)
144 			return SC_ERROR_BUFFER_TOO_SMALL;
145 	}
146 
147 	const char hex[] = "0123456789abcdef";
148 	while (in_len) {
149 		unsigned char value = *in++;
150 		*out++ = hex[(value >> 4) & 0xF];
151 		*out++ = hex[ value       & 0xF];
152 		in_len--;
153 		if (in_len && in_sep > 0)
154 			*out++ = (char)in_sep;
155 	}
156 	*out = '\0';
157 
158 	return SC_SUCCESS;
159 }
160 
161 /*
162  * Right trim all non-printable characters
163  */
sc_right_trim(u8 * buf,size_t len)164 size_t sc_right_trim(u8 *buf, size_t len) {
165 
166 	size_t i;
167 
168 	if (!buf)
169 		return 0;
170 
171 	if (len > 0) {
172 		for(i = len-1; i > 0; i--) {
173 			if(!isprint(buf[i])) {
174 				buf[i] = '\0';
175 				len--;
176 				continue;
177 			}
178 			break;
179 		}
180 	}
181 	return len;
182 }
183 
ulong2bebytes(u8 * buf,unsigned long x)184 u8 *ulong2bebytes(u8 *buf, unsigned long x)
185 {
186 	if (buf != NULL) {
187 		buf[3] = (u8) (x & 0xff);
188 		buf[2] = (u8) ((x >> 8) & 0xff);
189 		buf[1] = (u8) ((x >> 16) & 0xff);
190 		buf[0] = (u8) ((x >> 24) & 0xff);
191 	}
192 	return buf;
193 }
194 
ushort2bebytes(u8 * buf,unsigned short x)195 u8 *ushort2bebytes(u8 *buf, unsigned short x)
196 {
197 	if (buf != NULL) {
198 		buf[1] = (u8) (x & 0xff);
199 		buf[0] = (u8) ((x >> 8) & 0xff);
200 	}
201 	return buf;
202 }
203 
bebytes2ulong(const u8 * buf)204 unsigned long bebytes2ulong(const u8 *buf)
205 {
206 	if (buf == NULL)
207 		return 0UL;
208 	return (unsigned long)buf[0] << 24
209 		| (unsigned long)buf[1] << 16
210 		| (unsigned long)buf[2] << 8
211 		| (unsigned long)buf[3];
212 }
213 
bebytes2ushort(const u8 * buf)214 unsigned short bebytes2ushort(const u8 *buf)
215 {
216 	if (buf == NULL)
217 		return 0U;
218 	return (unsigned short)buf[0] << 8
219 		| (unsigned short)buf[1];
220 }
221 
lebytes2ushort(const u8 * buf)222 unsigned short lebytes2ushort(const u8 *buf)
223 {
224 	if (buf == NULL)
225 		return 0U;
226 	return (unsigned short)buf[1] << 8
227 		| (unsigned short)buf[0];
228 }
229 
lebytes2ulong(const u8 * buf)230 unsigned long lebytes2ulong(const u8 *buf)
231 {
232 	if (buf == NULL)
233 		return 0UL;
234 	return (unsigned long)buf[3] << 24
235 		| (unsigned long)buf[2] << 16
236 		| (unsigned long)buf[1] << 8
237 		| (unsigned long)buf[0];
238 }
239 
set_string(char ** strp,const char * value)240 void set_string(char **strp, const char *value)
241 {
242 	if (strp == NULL) {
243 		return;
244 	}
245 
246 	free(*strp);
247 	*strp = value ? strdup(value) : NULL;
248 }
249 
sc_init_oid(struct sc_object_id * oid)250 void sc_init_oid(struct sc_object_id *oid)
251 {
252 	int ii;
253 
254 	if (!oid)
255 		return;
256 	for (ii=0; ii<SC_MAX_OBJECT_ID_OCTETS; ii++)
257 		oid->value[ii] = -1;
258 }
259 
sc_format_oid(struct sc_object_id * oid,const char * in)260 int sc_format_oid(struct sc_object_id *oid, const char *in)
261 {
262 	int        ii, ret = SC_ERROR_INVALID_ARGUMENTS;
263 	const char *p;
264 	char       *q;
265 
266 	if (oid == NULL || in == NULL)
267 		return SC_ERROR_INVALID_ARGUMENTS;
268 
269 	sc_init_oid(oid);
270 
271 	p = in;
272 	for (ii=0; ii < SC_MAX_OBJECT_ID_OCTETS; ii++)   {
273 		oid->value[ii] = strtol(p, &q, 10);
274 		if (!*q)
275 			break;
276 
277 		if (!(q[0] == '.' && isdigit((unsigned char)q[1])))
278 			goto out;
279 
280 		p = q + 1;
281 	}
282 
283 	if (!sc_valid_oid(oid))
284 		goto out;
285 
286 	ret = SC_SUCCESS;
287 out:
288 	if (ret)
289 		sc_init_oid(oid);
290 
291 	return ret;
292 }
293 
sc_compare_oid(const struct sc_object_id * oid1,const struct sc_object_id * oid2)294 int sc_compare_oid(const struct sc_object_id *oid1, const struct sc_object_id *oid2)
295 {
296 	int i;
297 
298 	if (oid1 == NULL || oid2 == NULL) {
299 		return SC_ERROR_INVALID_ARGUMENTS;
300 	}
301 
302 	for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++)   {
303 		if (oid1->value[i] != oid2->value[i])
304 			return 0;
305 		if (oid1->value[i] == -1)
306 			break;
307 	}
308 
309 	return 1;
310 }
311 
312 
sc_valid_oid(const struct sc_object_id * oid)313 int sc_valid_oid(const struct sc_object_id *oid)
314 {
315 	int ii;
316 
317 	if (!oid)
318 		return 0;
319 	if (oid->value[0] == -1 || oid->value[1] == -1)
320 		return 0;
321 	if (oid->value[0] > 2 || oid->value[1] > 39)
322 		return 0;
323 	for (ii=0;ii<SC_MAX_OBJECT_ID_OCTETS;ii++)
324 		if (oid->value[ii])
325 			break;
326 	if (ii==SC_MAX_OBJECT_ID_OCTETS)
327 		return 0;
328 	return 1;
329 }
330 
331 
sc_detect_card_presence(sc_reader_t * reader)332 int sc_detect_card_presence(sc_reader_t *reader)
333 {
334 	int r;
335 	LOG_FUNC_CALLED(reader->ctx);
336 	if (reader->ops->detect_card_presence == NULL)
337 		LOG_FUNC_RETURN(reader->ctx, SC_ERROR_NOT_SUPPORTED);
338 
339 	r = reader->ops->detect_card_presence(reader);
340 	LOG_FUNC_RETURN(reader->ctx, r);
341 }
342 
sc_path_set(sc_path_t * path,int type,const u8 * id,size_t id_len,int idx,int count)343 int sc_path_set(sc_path_t *path, int type, const u8 *id, size_t id_len,
344 	int idx, int count)
345 {
346 	if (path == NULL || id == NULL || id_len == 0 || id_len > SC_MAX_PATH_SIZE)
347 		return SC_ERROR_INVALID_ARGUMENTS;
348 
349 	memset(path, 0, sizeof(*path));
350 	memcpy(path->value, id, id_len);
351 	path->len   = id_len;
352 	path->type  = type;
353 	path->index = idx;
354 	path->count = count;
355 
356 	return SC_SUCCESS;
357 }
358 
sc_format_path(const char * str,sc_path_t * path)359 void sc_format_path(const char *str, sc_path_t *path)
360 {
361 	int type = SC_PATH_TYPE_PATH;
362 
363 	if (path) {
364 		memset(path, 0, sizeof(*path));
365 		if (*str == 'i' || *str == 'I') {
366 			type = SC_PATH_TYPE_FILE_ID;
367 			str++;
368 		}
369 		path->len = sizeof(path->value);
370 		if (sc_hex_to_bin(str, path->value, &path->len) >= 0) {
371 			path->type = type;
372 		}
373 		path->count = -1;
374 	}
375 }
376 
sc_append_path(sc_path_t * dest,const sc_path_t * src)377 int sc_append_path(sc_path_t *dest, const sc_path_t *src)
378 {
379 	return sc_concatenate_path(dest, dest, src);
380 }
381 
sc_append_path_id(sc_path_t * dest,const u8 * id,size_t idlen)382 int sc_append_path_id(sc_path_t *dest, const u8 *id, size_t idlen)
383 {
384 	if (dest->len + idlen > SC_MAX_PATH_SIZE)
385 		return SC_ERROR_INVALID_ARGUMENTS;
386 	memcpy(dest->value + dest->len, id, idlen);
387 	dest->len += idlen;
388 	return SC_SUCCESS;
389 }
390 
sc_append_file_id(sc_path_t * dest,unsigned int fid)391 int sc_append_file_id(sc_path_t *dest, unsigned int fid)
392 {
393 	u8 id[2] = { fid >> 8, fid & 0xff };
394 
395 	return sc_append_path_id(dest, id, 2);
396 }
397 
sc_concatenate_path(sc_path_t * d,const sc_path_t * p1,const sc_path_t * p2)398 int sc_concatenate_path(sc_path_t *d, const sc_path_t *p1, const sc_path_t *p2)
399 {
400 	sc_path_t tpath;
401 
402 	if (d == NULL || p1 == NULL || p2 == NULL)
403 		return SC_ERROR_INVALID_ARGUMENTS;
404 
405 	if (p1->type == SC_PATH_TYPE_DF_NAME || p2->type == SC_PATH_TYPE_DF_NAME)
406 		/* we do not support concatenation of AIDs at the moment */
407 		return SC_ERROR_NOT_SUPPORTED;
408 
409 	if (p1->len + p2->len > SC_MAX_PATH_SIZE)
410 		return SC_ERROR_INVALID_ARGUMENTS;
411 
412 	memset(&tpath, 0, sizeof(sc_path_t));
413 	memcpy(tpath.value, p1->value, p1->len);
414 	memcpy(tpath.value + p1->len, p2->value, p2->len);
415 	tpath.len  = p1->len + p2->len;
416 	tpath.type = SC_PATH_TYPE_PATH;
417 	/* use 'index' and 'count' entry of the second path object */
418 	tpath.index = p2->index;
419 	tpath.count = p2->count;
420 	/* the result is currently always as path */
421 	tpath.type  = SC_PATH_TYPE_PATH;
422 
423 	*d = tpath;
424 
425 	return SC_SUCCESS;
426 }
427 
sc_print_path(const sc_path_t * path)428 const char *sc_print_path(const sc_path_t *path)
429 {
430 	static char buffer[SC_MAX_PATH_STRING_SIZE + SC_MAX_AID_STRING_SIZE];
431 
432 	if (sc_path_print(buffer, sizeof(buffer), path) != SC_SUCCESS)
433 		buffer[0] = '\0';
434 
435 	return buffer;
436 }
437 
sc_path_print(char * buf,size_t buflen,const sc_path_t * path)438 int sc_path_print(char *buf, size_t buflen, const sc_path_t *path)
439 {
440 	size_t i;
441 
442 	if (buf == NULL || path == NULL)
443 		return SC_ERROR_INVALID_ARGUMENTS;
444 
445 	if (buflen < path->len * 2 + path->aid.len * 2 + 3)
446 		return SC_ERROR_BUFFER_TOO_SMALL;
447 
448 	buf[0] = '\0';
449 	if (path->aid.len)   {
450 		for (i = 0; i < path->aid.len; i++)
451 			snprintf(buf + strlen(buf), buflen - strlen(buf), "%02x", path->aid.value[i]);
452 		snprintf(buf + strlen(buf), buflen - strlen(buf), "::");
453 	}
454 
455 	for (i = 0; i < path->len; i++)
456 		snprintf(buf + strlen(buf), buflen - strlen(buf), "%02x", path->value[i]);
457 	if (!path->aid.len && path->type == SC_PATH_TYPE_DF_NAME)
458 		snprintf(buf + strlen(buf), buflen - strlen(buf), "::");
459 
460 	return SC_SUCCESS;
461 }
462 
sc_compare_path(const sc_path_t * path1,const sc_path_t * path2)463 int sc_compare_path(const sc_path_t *path1, const sc_path_t *path2)
464 {
465 	return path1->len == path2->len
466 		&& !memcmp(path1->value, path2->value, path1->len);
467 }
468 
sc_compare_path_prefix(const sc_path_t * prefix,const sc_path_t * path)469 int sc_compare_path_prefix(const sc_path_t *prefix, const sc_path_t *path)
470 {
471 	sc_path_t tpath;
472 
473 	if (prefix->len > path->len)
474 		return 0;
475 
476 	tpath     = *path;
477 	tpath.len = prefix->len;
478 
479 	return sc_compare_path(&tpath, prefix);
480 }
481 
sc_get_mf_path(void)482 const sc_path_t *sc_get_mf_path(void)
483 {
484 	static const sc_path_t mf_path = {
485 		{0x3f, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2,
486 		0,
487 		0,
488 		SC_PATH_TYPE_PATH,
489 		{{0},0}
490 	};
491 	return &mf_path;
492 }
493 
sc_file_add_acl_entry(sc_file_t * file,unsigned int operation,unsigned int method,unsigned long key_ref)494 int sc_file_add_acl_entry(sc_file_t *file, unsigned int operation,
495                           unsigned int method, unsigned long key_ref)
496 {
497 	sc_acl_entry_t *p, *_new;
498 
499 	if (file == NULL || operation >= SC_MAX_AC_OPS) {
500 		return SC_ERROR_INVALID_ARGUMENTS;
501 	}
502 
503 	switch (method) {
504 	case SC_AC_NEVER:
505 		sc_file_clear_acl_entries(file, operation);
506 		file->acl[operation] = (sc_acl_entry_t *) 1;
507 		return SC_SUCCESS;
508 	case SC_AC_NONE:
509 		sc_file_clear_acl_entries(file, operation);
510 		file->acl[operation] = (sc_acl_entry_t *) 2;
511 		return SC_SUCCESS;
512 	case SC_AC_UNKNOWN:
513 		sc_file_clear_acl_entries(file, operation);
514 		file->acl[operation] = (sc_acl_entry_t *) 3;
515 		return SC_SUCCESS;
516 	default:
517 		/* NONE and UNKNOWN get zapped when a new AC is added.
518 		 * If the ACL is NEVER, additional entries will be
519 		 * dropped silently. */
520 		if (file->acl[operation] == (sc_acl_entry_t *) 1)
521 			return SC_SUCCESS;
522 		if (file->acl[operation] == (sc_acl_entry_t *) 2
523 		 || file->acl[operation] == (sc_acl_entry_t *) 3)
524 			file->acl[operation] = NULL;
525 	}
526 
527 	/* If the entry is already present (e.g. due to the mapping)
528 	 * of the card's AC with OpenSC's), don't add it again. */
529 	for (p = file->acl[operation]; p != NULL; p = p->next) {
530 		if ((p->method == method) && (p->key_ref == key_ref))
531 			return SC_SUCCESS;
532 	}
533 
534 	_new = malloc(sizeof(sc_acl_entry_t));
535 	if (_new == NULL)
536 		return SC_ERROR_OUT_OF_MEMORY;
537 	_new->method = method;
538 	_new->key_ref = key_ref;
539 	_new->next = NULL;
540 
541 	p = file->acl[operation];
542 	if (p == NULL) {
543 		file->acl[operation] = _new;
544 		return SC_SUCCESS;
545 	}
546 	while (p->next != NULL)
547 		p = p->next;
548 	p->next = _new;
549 
550 	return SC_SUCCESS;
551 }
552 
sc_file_get_acl_entry(const sc_file_t * file,unsigned int operation)553 const sc_acl_entry_t * sc_file_get_acl_entry(const sc_file_t *file,
554 						  unsigned int operation)
555 {
556 	sc_acl_entry_t *p;
557 	static const sc_acl_entry_t e_never = {
558 		SC_AC_NEVER, SC_AC_KEY_REF_NONE, NULL
559 	};
560 	static const sc_acl_entry_t e_none = {
561 		SC_AC_NONE, SC_AC_KEY_REF_NONE, NULL
562 	};
563 	static const sc_acl_entry_t e_unknown = {
564 		SC_AC_UNKNOWN, SC_AC_KEY_REF_NONE, NULL
565 	};
566 
567 	if (file == NULL || operation >= SC_MAX_AC_OPS) {
568 		return NULL;
569 	}
570 
571 	p = file->acl[operation];
572 	if (p == (sc_acl_entry_t *) 1)
573 		return &e_never;
574 	if (p == (sc_acl_entry_t *) 2)
575 		return &e_none;
576 	if (p == (sc_acl_entry_t *) 3)
577 		return &e_unknown;
578 
579 	return file->acl[operation];
580 }
581 
sc_file_clear_acl_entries(sc_file_t * file,unsigned int operation)582 void sc_file_clear_acl_entries(sc_file_t *file, unsigned int operation)
583 {
584 	sc_acl_entry_t *e;
585 
586 	if (file == NULL || operation >= SC_MAX_AC_OPS) {
587 		return;
588 	}
589 
590 	e = file->acl[operation];
591 	if (e == (sc_acl_entry_t *) 1 ||
592 	    e == (sc_acl_entry_t *) 2 ||
593 	    e == (sc_acl_entry_t *) 3) {
594 		file->acl[operation] = NULL;
595 		return;
596 	}
597 
598 	while (e != NULL) {
599 		sc_acl_entry_t *tmp = e->next;
600 		free(e);
601 		e = tmp;
602 	}
603 	file->acl[operation] = NULL;
604 }
605 
sc_file_new(void)606 sc_file_t * sc_file_new(void)
607 {
608 	sc_file_t *file = (sc_file_t *)calloc(1, sizeof(sc_file_t));
609 	if (file == NULL)
610 		return NULL;
611 
612 	file->magic = SC_FILE_MAGIC;
613 	return file;
614 }
615 
sc_file_free(sc_file_t * file)616 void sc_file_free(sc_file_t *file)
617 {
618 	unsigned int i;
619 	if (file == NULL || !sc_file_valid(file))
620 		return;
621 	file->magic = 0;
622 	for (i = 0; i < SC_MAX_AC_OPS; i++)
623 		sc_file_clear_acl_entries(file, i);
624 	if (file->sec_attr)
625 		free(file->sec_attr);
626 	if (file->prop_attr)
627 		free(file->prop_attr);
628 	if (file->type_attr)
629 		free(file->type_attr);
630 	if (file->encoded_content)
631 		free(file->encoded_content);
632 	free(file);
633 }
634 
sc_file_dup(sc_file_t ** dest,const sc_file_t * src)635 void sc_file_dup(sc_file_t **dest, const sc_file_t *src)
636 {
637 	sc_file_t *newf;
638 	const sc_acl_entry_t *e;
639 	unsigned int op;
640 
641 	*dest = NULL;
642 	if (!sc_file_valid(src))
643 		return;
644 	newf = sc_file_new();
645 	if (newf == NULL)
646 		return;
647 	*dest = newf;
648 
649 	memcpy(&newf->path, &src->path, sizeof(struct sc_path));
650 	memcpy(&newf->name, &src->name, sizeof(src->name));
651 	newf->namelen = src->namelen;
652 	newf->type    = src->type;
653 	newf->shareable    = src->shareable;
654 	newf->ef_structure = src->ef_structure;
655 	newf->size    = src->size;
656 	newf->id      = src->id;
657 	newf->status  = src->status;
658 	for (op = 0; op < SC_MAX_AC_OPS; op++) {
659 		newf->acl[op] = NULL;
660 		e = sc_file_get_acl_entry(src, op);
661 		if (e != NULL) {
662 			if (sc_file_add_acl_entry(newf, op, e->method, e->key_ref) < 0)
663 				goto err;
664 		}
665 	}
666 	newf->record_length = src->record_length;
667 	newf->record_count  = src->record_count;
668 
669 	if (sc_file_set_sec_attr(newf, src->sec_attr, src->sec_attr_len) < 0)
670 		goto err;
671 	if (sc_file_set_prop_attr(newf, src->prop_attr, src->prop_attr_len) < 0)
672 		goto err;
673 	if (sc_file_set_type_attr(newf, src->type_attr, src->type_attr_len) < 0)
674 		goto err;
675 	if (sc_file_set_content(newf, src->encoded_content, src->encoded_content_len) < 0)
676 		goto err;
677 	return;
678 err:
679 	sc_file_free(newf);
680 	*dest = NULL;
681 }
682 
sc_file_set_sec_attr(sc_file_t * file,const u8 * sec_attr,size_t sec_attr_len)683 int sc_file_set_sec_attr(sc_file_t *file, const u8 *sec_attr,
684 			 size_t sec_attr_len)
685 {
686 	u8 *tmp;
687 	if (!sc_file_valid(file)) {
688 		return SC_ERROR_INVALID_ARGUMENTS;
689 	}
690 
691 	if (sec_attr == NULL || sec_attr_len == 0) {
692 		if (file->sec_attr != NULL)
693 			free(file->sec_attr);
694 		file->sec_attr = NULL;
695 		file->sec_attr_len = 0;
696 		return 0;
697 	 }
698 	tmp = (u8 *) realloc(file->sec_attr, sec_attr_len);
699 	if (!tmp) {
700 		if (file->sec_attr)
701 			free(file->sec_attr);
702 		file->sec_attr     = NULL;
703 		file->sec_attr_len = 0;
704 		return SC_ERROR_OUT_OF_MEMORY;
705 	}
706 	file->sec_attr = tmp;
707 	memcpy(file->sec_attr, sec_attr, sec_attr_len);
708 	file->sec_attr_len = sec_attr_len;
709 
710 	return 0;
711 }
712 
sc_file_set_prop_attr(sc_file_t * file,const u8 * prop_attr,size_t prop_attr_len)713 int sc_file_set_prop_attr(sc_file_t *file, const u8 *prop_attr,
714 			 size_t prop_attr_len)
715 {
716 	u8 *tmp;
717 	if (!sc_file_valid(file)) {
718 		return SC_ERROR_INVALID_ARGUMENTS;
719 	}
720 
721 	if (prop_attr == NULL || prop_attr_len == 0) {
722 		if (file->prop_attr != NULL)
723 			free(file->prop_attr);
724 		file->prop_attr = NULL;
725 		file->prop_attr_len = 0;
726 		return SC_SUCCESS;
727 	 }
728 	tmp = (u8 *) realloc(file->prop_attr, prop_attr_len);
729 	if (!tmp) {
730 		if (file->prop_attr)
731 			free(file->prop_attr);
732 		file->prop_attr = NULL;
733 		file->prop_attr_len = 0;
734 		return SC_ERROR_OUT_OF_MEMORY;
735 	}
736 	file->prop_attr = tmp;
737 	memcpy(file->prop_attr, prop_attr, prop_attr_len);
738 	file->prop_attr_len = prop_attr_len;
739 
740 	return SC_SUCCESS;
741 }
742 
sc_file_set_type_attr(sc_file_t * file,const u8 * type_attr,size_t type_attr_len)743 int sc_file_set_type_attr(sc_file_t *file, const u8 *type_attr,
744 			 size_t type_attr_len)
745 {
746 	u8 *tmp;
747 	if (!sc_file_valid(file)) {
748 		return SC_ERROR_INVALID_ARGUMENTS;
749 	}
750 
751 	if (type_attr == NULL || type_attr_len == 0) {
752 		if (file->type_attr != NULL)
753 			free(file->type_attr);
754 		file->type_attr = NULL;
755 		file->type_attr_len = 0;
756 		return SC_SUCCESS;
757 	 }
758 	tmp = (u8 *) realloc(file->type_attr, type_attr_len);
759 	if (!tmp) {
760 		if (file->type_attr)
761 			free(file->type_attr);
762 		file->type_attr = NULL;
763 		file->type_attr_len = 0;
764 		return SC_ERROR_OUT_OF_MEMORY;
765 	}
766 	file->type_attr = tmp;
767 	memcpy(file->type_attr, type_attr, type_attr_len);
768 	file->type_attr_len = type_attr_len;
769 
770 	return SC_SUCCESS;
771 }
772 
773 
sc_file_set_content(sc_file_t * file,const u8 * content,size_t content_len)774 int sc_file_set_content(sc_file_t *file, const u8 *content,
775 			 size_t content_len)
776 {
777 	u8 *tmp;
778 	if (!sc_file_valid(file)) {
779 		return SC_ERROR_INVALID_ARGUMENTS;
780 	}
781 
782 	if (content == NULL || content_len == 0) {
783 		if (file->encoded_content != NULL)
784 			free(file->encoded_content);
785 		file->encoded_content = NULL;
786 		file->encoded_content_len = 0;
787 		return SC_SUCCESS;
788 	}
789 
790 	tmp = (u8 *) realloc(file->encoded_content, content_len);
791 	if (!tmp) {
792 		if (file->encoded_content)
793 			free(file->encoded_content);
794 		file->encoded_content = NULL;
795 		file->encoded_content_len = 0;
796 		return SC_ERROR_OUT_OF_MEMORY;
797 	}
798 
799 	file->encoded_content = tmp;
800 	memcpy(file->encoded_content, content, content_len);
801 	file->encoded_content_len = content_len;
802 
803 	return SC_SUCCESS;
804 }
805 
806 
sc_file_valid(const sc_file_t * file)807 int sc_file_valid(const sc_file_t *file) {
808 	if (file == NULL)
809 		return 0;
810 	return file->magic == SC_FILE_MAGIC;
811 }
812 
_sc_parse_atr(sc_reader_t * reader)813 int _sc_parse_atr(sc_reader_t *reader)
814 {
815 	u8 *p = reader->atr.value;
816 	int atr_len = (int) reader->atr.len;
817 	int n_hist, x;
818 	int tx[4] = {-1, -1, -1, -1};
819 	int i, FI, DI;
820 	const int Fi_table[] = {
821 		372, 372, 558, 744, 1116, 1488, 1860, -1,
822 		-1, 512, 768, 1024, 1536, 2048, -1, -1 };
823 	const int f_table[] = {
824 		40, 50, 60, 80, 120, 160, 200, -1,
825 		-1, 50, 75, 100, 150, 200, -1, -1 };
826 	const int Di_table[] = {
827 		-1, 1, 2, 4, 8, 16, 32, -1,
828 		12, 20, -1, -1, -1, -1, -1, -1 };
829 
830 	reader->atr_info.hist_bytes_len = 0;
831 	reader->atr_info.hist_bytes = NULL;
832 
833 	if (atr_len == 0) {
834 		sc_log(reader->ctx, "empty ATR - card not present?\n");
835 		return SC_ERROR_INTERNAL;
836 	}
837 
838 	if (p[0] != 0x3B && p[0] != 0x3F) {
839 		sc_log(reader->ctx, "invalid sync byte in ATR: 0x%02X\n", p[0]);
840 		return SC_ERROR_INTERNAL;
841 	}
842 	n_hist = p[1] & 0x0F;
843 	x = p[1] >> 4;
844 	p += 2;
845 	atr_len -= 2;
846 	for (i = 0; i < 4 && atr_len > 0; i++) {
847                 if (x & (1 << i)) {
848                         tx[i] = *p;
849                         p++;
850                         atr_len--;
851                 } else
852                         tx[i] = -1;
853         }
854 	if (tx[0] >= 0) {
855 		reader->atr_info.FI = FI = tx[0] >> 4;
856 		reader->atr_info.DI = DI = tx[0] & 0x0F;
857 		reader->atr_info.Fi = Fi_table[FI];
858 		reader->atr_info.f = f_table[FI];
859 		reader->atr_info.Di = Di_table[DI];
860 	} else {
861 		reader->atr_info.Fi = -1;
862 		reader->atr_info.f = -1;
863 		reader->atr_info.Di = -1;
864 	}
865 	if (tx[2] >= 0)
866 		reader->atr_info.N = tx[3];
867 	else
868 		reader->atr_info.N = -1;
869 	while (tx[3] > 0 && tx[3] & 0xF0 && atr_len > 0) {
870 		x = tx[3] >> 4;
871 		for (i = 0; i < 4 && atr_len > 0; i++) {
872 	                if (x & (1 << i)) {
873 	                        tx[i] = *p;
874 	                        p++;
875 	                        atr_len--;
876 	                } else
877 	                        tx[i] = -1;
878 		}
879 	}
880 	if (atr_len <= 0)
881 		return SC_SUCCESS;
882 	if (n_hist > atr_len)
883 		n_hist = atr_len;
884 	reader->atr_info.hist_bytes_len = n_hist;
885 	reader->atr_info.hist_bytes = p;
886 	return SC_SUCCESS;
887 }
888 
init_page_size()889 static void init_page_size()
890 {
891 	if (page_size == 0) {
892 #ifdef _WIN32
893 		SYSTEM_INFO system_info;
894 		GetSystemInfo(&system_info);
895 		page_size = system_info.dwPageSize;
896 #else
897 		page_size = sysconf(_SC_PAGESIZE);
898 		if ((long) page_size < 0) {
899 			page_size = 0;
900 		}
901 #endif
902 	}
903 }
904 
sc_mem_secure_alloc(size_t len)905 void *sc_mem_secure_alloc(size_t len)
906 {
907 	void *p;
908 
909 	init_page_size();
910 	if (page_size > 0) {
911 		size_t pages = (len + page_size - 1) / page_size;
912 		len = pages * page_size;
913 	}
914 
915 	p = calloc(1, len);
916 	if (p == NULL) {
917 		return NULL;
918 	}
919 #ifdef _WIN32
920 	VirtualLock(p, len);
921 #else
922 	mlock(p, len);
923 #endif
924 
925 	return p;
926 }
927 
sc_mem_secure_free(void * ptr,size_t len)928 void sc_mem_secure_free(void *ptr, size_t len)
929 {
930 #ifdef _WIN32
931 	VirtualUnlock(ptr, len);
932 #else
933 	munlock(ptr, len);
934 #endif
935 	free(ptr);
936 }
937 
sc_mem_clear(void * ptr,size_t len)938 void sc_mem_clear(void *ptr, size_t len)
939 {
940 	if (len > 0)   {
941 #ifdef HAVE_MEMSET_S
942 		memset_s(ptr, len, 0, len);
943 #elif _WIN32
944 		SecureZeroMemory(ptr, len);
945 #elif HAVE_EXPLICIT_BZERO
946 		explicit_bzero(ptr, len);
947 #elif ENABLE_OPENSSL
948 		OPENSSL_cleanse(ptr, len);
949 #else
950 		memset(ptr, 0, len);
951 #endif
952 	}
953 }
954 
sc_mem_reverse(unsigned char * buf,size_t len)955 int sc_mem_reverse(unsigned char *buf, size_t len)
956 {
957 	unsigned char ch;
958 	size_t ii;
959 
960 	if (!buf || !len)
961 		return SC_ERROR_INVALID_ARGUMENTS;
962 
963 	for (ii = 0; ii < len / 2; ii++)   {
964 		ch = *(buf + ii);
965 		*(buf + ii) = *(buf + len - 1 - ii);
966 		*(buf + len - 1 - ii) = ch;
967 	}
968 
969 	return SC_SUCCESS;
970 }
971 
972 static int
sc_remote_apdu_allocate(struct sc_remote_data * rdata,struct sc_remote_apdu ** new_rapdu)973 sc_remote_apdu_allocate(struct sc_remote_data *rdata,
974 		struct sc_remote_apdu **new_rapdu)
975 {
976 	struct sc_remote_apdu *rapdu = NULL, *rr;
977 
978 	if (!rdata)
979 		return SC_ERROR_INVALID_ARGUMENTS;
980 
981 	rapdu = calloc(1, sizeof(struct sc_remote_apdu));
982 	if (rapdu == NULL)
983 		return SC_ERROR_OUT_OF_MEMORY;
984 
985 	rapdu->apdu.data = &rapdu->sbuf[0];
986 	rapdu->apdu.resp = &rapdu->rbuf[0];
987 	rapdu->apdu.resplen = sizeof(rapdu->rbuf);
988 
989 	if (new_rapdu)
990 		*new_rapdu = rapdu;
991 
992 	if (rdata->data == NULL)   {
993 		rdata->data = rapdu;
994 		rdata->length = 1;
995 		return SC_SUCCESS;
996 	}
997 
998 	for (rr = rdata->data; rr->next; rr = rr->next)
999 		;
1000 	rr->next = rapdu;
1001 	rdata->length++;
1002 
1003 	return SC_SUCCESS;
1004 }
1005 
1006 static void
sc_remote_apdu_free(struct sc_remote_data * rdata)1007 sc_remote_apdu_free (struct sc_remote_data *rdata)
1008 {
1009 	struct sc_remote_apdu *rapdu = NULL;
1010 
1011 	if (!rdata)
1012 		return;
1013 
1014 	rapdu = rdata->data;
1015 	while(rapdu)   {
1016 		struct sc_remote_apdu *rr = rapdu->next;
1017 
1018 		free(rapdu);
1019 		rapdu = rr;
1020 	}
1021 }
1022 
sc_remote_data_init(struct sc_remote_data * rdata)1023 void sc_remote_data_init(struct sc_remote_data *rdata)
1024 {
1025 	if (!rdata)
1026 		return;
1027 	memset(rdata, 0, sizeof(struct sc_remote_data));
1028 
1029 	rdata->alloc = sc_remote_apdu_allocate;
1030 	rdata->free = sc_remote_apdu_free;
1031 }
1032 
1033 static unsigned long  sc_CRC_tab32[256];
1034 static int sc_CRC_tab32_initialized = 0;
sc_crc32(const unsigned char * value,size_t len)1035 unsigned sc_crc32(const unsigned char *value, size_t len)
1036 {
1037 	size_t ii, jj;
1038 	unsigned long crc;
1039 	unsigned long index, long_c;
1040 
1041 	if (!sc_CRC_tab32_initialized)   {
1042 		for (ii=0; ii<256; ii++) {
1043 			crc = (unsigned long) ii;
1044 			for (jj=0; jj<8; jj++) {
1045 				if ( crc & 0x00000001L )
1046 					crc = ( crc >> 1 ) ^ 0xEDB88320l;
1047 				else
1048 					crc =   crc >> 1;
1049 			}
1050 			sc_CRC_tab32[ii] = crc;
1051 		}
1052 		sc_CRC_tab32_initialized = 1;
1053 	}
1054 
1055 	crc = 0xffffffffL;
1056 	for (ii=0; ii<len; ii++)   {
1057 		long_c = 0x000000ffL & (unsigned long) (*(value + ii));
1058 		index = crc ^ long_c;
1059 		crc = (crc >> 8) ^ sc_CRC_tab32[ index & 0xff ];
1060 	}
1061 
1062 	crc ^= 0xffffffff;
1063 	return  crc%0xffff;
1064 }
1065 
sc_compacttlv_find_tag(const u8 * buf,size_t len,u8 tag,size_t * outlen)1066 const u8 *sc_compacttlv_find_tag(const u8 *buf, size_t len, u8 tag, size_t *outlen)
1067 {
1068 	if (buf != NULL) {
1069 		size_t idx;
1070 		u8 plain_tag = tag & 0xF0;
1071 		size_t expected_len = tag & 0x0F;
1072 
1073 	        for (idx = 0; idx < len; idx++) {
1074 			if ((buf[idx] & 0xF0) == plain_tag && idx + expected_len < len &&
1075 			    (expected_len == 0 || expected_len == (buf[idx] & 0x0F))) {
1076 				if (outlen != NULL)
1077 					*outlen = buf[idx] & 0x0F;
1078 				return buf + (idx + 1);
1079 			}
1080 			idx += (buf[idx] & 0x0F);
1081                 }
1082         }
1083 	return NULL;
1084 }
1085 
1086 /**************************** mutex functions ************************/
1087 
sc_mutex_create(const sc_context_t * ctx,void ** mutex)1088 int sc_mutex_create(const sc_context_t *ctx, void **mutex)
1089 {
1090 	if (ctx == NULL)
1091 		return SC_ERROR_INVALID_ARGUMENTS;
1092 	if (ctx->thread_ctx != NULL && ctx->thread_ctx->create_mutex != NULL)
1093 		return ctx->thread_ctx->create_mutex(mutex);
1094 	else
1095 		return SC_SUCCESS;
1096 }
1097 
sc_mutex_lock(const sc_context_t * ctx,void * mutex)1098 int sc_mutex_lock(const sc_context_t *ctx, void *mutex)
1099 {
1100 	if (ctx == NULL)
1101 		return SC_ERROR_INVALID_ARGUMENTS;
1102 	if (ctx->thread_ctx != NULL && ctx->thread_ctx->lock_mutex != NULL)
1103 		return ctx->thread_ctx->lock_mutex(mutex);
1104 	else
1105 		return SC_SUCCESS;
1106 }
1107 
sc_mutex_unlock(const sc_context_t * ctx,void * mutex)1108 int sc_mutex_unlock(const sc_context_t *ctx, void *mutex)
1109 {
1110 	if (ctx == NULL)
1111 		return SC_ERROR_INVALID_ARGUMENTS;
1112 	if (ctx->thread_ctx != NULL && ctx->thread_ctx->unlock_mutex != NULL)
1113 		return ctx->thread_ctx->unlock_mutex(mutex);
1114 	else
1115 		return SC_SUCCESS;
1116 }
1117 
sc_mutex_destroy(const sc_context_t * ctx,void * mutex)1118 int sc_mutex_destroy(const sc_context_t *ctx, void *mutex)
1119 {
1120 	if (ctx == NULL)
1121 		return SC_ERROR_INVALID_ARGUMENTS;
1122 	if (ctx->thread_ctx != NULL && ctx->thread_ctx->destroy_mutex != NULL)
1123 		return ctx->thread_ctx->destroy_mutex(mutex);
1124 	else
1125 		return SC_SUCCESS;
1126 }
1127 
sc_thread_id(const sc_context_t * ctx)1128 unsigned long sc_thread_id(const sc_context_t *ctx)
1129 {
1130 	if (ctx == NULL || ctx->thread_ctx == NULL ||
1131 	    ctx->thread_ctx->thread_id == NULL)
1132 		return 0UL;
1133 	else
1134 		return ctx->thread_ctx->thread_id();
1135 }
1136 
sc_free(void * p)1137 void sc_free(void *p)
1138 {
1139 	free(p);
1140 }
1141