Example #1
0
static int do_ls(int argc, char **argv)
{
	u8 buf[256], *cur = buf;
	int r, count;

	r = sc_list_files(card, buf, sizeof(buf));
	if (r < 0) {
		check_ret(r, SC_AC_OP_LIST_FILES, "unable to receive file listing", current_file);
		return -1;
	}
	count = r;
	printf("FileID\tType  Size\n");
	while (count >= 2) {
		sc_path_t path;
		sc_file_t *file = NULL;
		char filename[10];
		int i = 0;
		int matches = 0;

		/* construct file name */
		sprintf(filename, "%02X%02X", cur[0], cur[1]);

		 /* compare file name against patterns */
		for (i = 0; i < argc; i++) {
			if (pattern_match(argv[i], filename)) {
				matches = 1;
				break;
			}
		}

		/* if any filename pattern were given, filter only matching file names */
		if (argc == 0 || matches) {
			if (current_path.type != SC_PATH_TYPE_DF_NAME) {
				path = current_path;
				sc_append_path_id(&path, cur, 2);
			} else {
				if (sc_path_set(&path, SC_PATH_TYPE_FILE_ID, cur, 2, 0, 0) != SC_SUCCESS) {
					printf("unable to set path.\n");
					die(1);
				}
			}

			r = sc_select_file(card, &path, &file);
			if (r) {
				printf(" %02X%02X unable to select file, %s\n", cur[0], cur[1], sc_strerror(r));
			} else {
				file->id = (cur[0] << 8) | cur[1];
					print_file(file);
				sc_file_free(file);
			}
		}
		cur += 2;
		count -= 2;
		select_current_path_or_die();
	}
	return 0;
}
static int arg_to_path(const char *arg, sc_path_t *path, int is_id)
{
	memset(path, 0, sizeof(sc_path_t));

	if (strncasecmp(arg, "aid:", strlen("aid:")) == 0) {
		/* DF aid */
		const char *p = arg + strlen("aid:");
		int r;

		path->type = SC_PATH_TYPE_DF_NAME;
		path->len  = sizeof(path->value);
		if ((r = sc_hex_to_bin(p, path->value, &path->len)) < 0) {
			printf("Error parsing AID: %s\n", p);
			return r;
		}
	} else {
		/* file id */
		unsigned int buf[2];
		u8 cbuf[2];

		if (strlen(arg) != 4) {
			printf("Wrong ID length.\n");
			return -1;
		}
		if (sscanf(arg, "%02X%02X", &buf[0], &buf[1]) != 2) {
			printf("Invalid ID.\n");
			return -1;
		}
		cbuf[0] = buf[0];
		cbuf[1] = buf[1];
		if ((cbuf[0] == 0x3F && cbuf[1] == 0x00) || is_id) {
			path->len = 2;
			memcpy(path->value, cbuf, 2);
			path->type = (is_id) ? SC_PATH_TYPE_FILE_ID : SC_PATH_TYPE_PATH;
		} else {
			*path = current_path;
			if (path->type == SC_PATH_TYPE_DF_NAME)   {
				if (path->len > sizeof(path->aid.value))   {
					printf("Invalid length of DF_NAME path\n");
					return -1;
				}

				memcpy(path->aid.value, path->value, path->len);
				path->aid.len = path->len;

				path->type = SC_PATH_TYPE_FILE_ID;
				path->len = 0;
			}
			sc_append_path_id(path, cbuf, 2);
		}
	}

	return 0;
}
static int dump_unusedspace(void)
{
	u8 *buf = NULL;
	size_t buf_len;
	sc_path_t path;
	sc_pkcs15_unusedspace_t *us;
	int r;

	if (p15card->file_unusedspace != NULL)
		path = p15card->file_unusedspace->path;
	else {
		path = p15card->file_app->path;
		sc_append_path_id(&path, (const u8 *) "\x50\x33", 2);
	}
	path.count = -1;

	sc_ctx_suppress_errors_on(p15card->card->ctx);
	r = sc_pkcs15_read_file(p15card, &path, &buf, &buf_len, NULL);
	sc_ctx_suppress_errors_off(p15card->card->ctx);
	if (r < 0) {
		if (r == SC_ERROR_FILE_NOT_FOUND) {
			printf("\nNo EF(UnusedSpace) file\n");
			r = 0;
		}
		else
			printf("\nError reading file \"%s\": %s\n",
				sc_print_path(&path), sc_strerror(r));
		goto err;
	}

	r = sc_pkcs15_parse_unusedspace(buf, buf_len, p15card);
	if (r != 0) {
		printf("\nError parsing EF(UnusedSpace): %s\n", sc_strerror(r));
		goto err;
	}

	if (p15card->unusedspace_list == NULL)
		printf("\nEF(UnusedSpace) file is empty\n");
	else {
		printf("\nContents of EF(UnusedSpace):\n");
		for (us = p15card->unusedspace_list; us != NULL; us = us->next)
		printf("  - path=%s, index=%d, length=%d  -- auth_id = %s\n",
			sc_print_path(&us->path), us->path.index, us->path.count,
			us->auth_id.len == 0 ? "<empty>" : sc_pkcs15_print_id(&us->auth_id));
	}

err:
	if (buf != NULL)
		free(buf);
	return r;
}
static int do_ls(int argc, char **argv)
{
	u8 buf[256], *cur = buf;
	int r, count;

	if (argc)
		goto usage;
	r = sc_list_files(card, buf, sizeof(buf));
	if (r < 0) {
		check_ret(r, SC_AC_OP_LIST_FILES, "unable to receive file listing", current_file);
		return -1;
	}
	count = r;
	printf("FileID\tType  Size\n");
	while (count >= 2) {
		sc_path_t path;
		sc_file_t *file = NULL;

		if (current_path.type != SC_PATH_TYPE_DF_NAME) {
			path = current_path;
			sc_append_path_id(&path, cur, 2);
		} else {
			if (sc_path_set(&path, SC_PATH_TYPE_FILE_ID, cur, 2, 0, 0) != SC_SUCCESS) {
				printf("unable to set path.\n");
				die(1);
			}
		}
			
		r = sc_select_file(card, &path, &file);
		if (r) {
			check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file);
			return -1;
		}
		file->id = (cur[0] << 8) | cur[1];
		cur += 2;
		count -= 2;
		print_file(file);
		sc_file_free(file);
		r = sc_select_file(card, &current_path, NULL);
		if (r) {
			printf("unable to select parent DF: %s\n", sc_strerror(r));
			die(1);
		}
	}
	return 0;
usage:
	puts("Usage: ls");
	return -1;
}
Example #5
0
/* sets a TLV encoded path as returned from GET DATA in a sc_path_t object
 */
static int asepcos_tlvpath_to_scpath(sc_path_t *out, const u8 *in, size_t in_len)
{
	int    r;
	size_t len = in_len;

	memset(out, 0, sizeof(sc_path_t));

	while (len != 0) {
		if (len < 4)
			return SC_ERROR_INTERNAL;
		if (in[0] != 0x8b || in[1] != 0x02)
			return SC_ERROR_INVALID_ASN1_OBJECT;
		/* append file id to the path */
		r = sc_append_path_id(out, &in[2], 2);
		if (r != SC_SUCCESS)
			return r;
		len -= 4;
		in  += 4;
	}
	out->type = SC_PATH_TYPE_PATH;

	return SC_SUCCESS;
}
static int arg_to_path(const char *arg, sc_path_t *path, int is_id)
{
	if (strncasecmp(arg, "aid:", strlen("aid:")) == 0) {
		/* DF aid */
		const char *p = arg + strlen("aid:");
		path->len  = hex2binary(path->value, sizeof(path->value), p);
		path->type = SC_PATH_TYPE_DF_NAME;
	} else {
		/* file id */
		int buf[2];
		u8 cbuf[2];
	
		if (strlen(arg) != 4) {
			printf("Wrong ID length.\n");
			return -1;
		}
		if (sscanf(arg, "%02X%02X", &buf[0], &buf[1]) != 2) {
			printf("Invalid ID.\n");
			return -1;
		}
		cbuf[0] = buf[0];
		cbuf[1] = buf[1];
		if ((cbuf[0] == 0x3F && cbuf[1] == 0x00) || is_id) {
			path->len = 2;
			memcpy(path->value, cbuf, 2);
			if (is_id)
				path->type = SC_PATH_TYPE_FILE_ID;
			else
				path->type = SC_PATH_TYPE_PATH;
		} else {
			*path = current_path;
			sc_append_path_id(path, cbuf, 2);
		}
	}

	return 0;	
}
static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card)
{
	unsigned char *buf = NULL;
	int    err, ok = 0;
	size_t len;
	sc_path_t tmppath;
	sc_card_t    *card = p15card->card;
	sc_context_t *ctx  = card->ctx;
	sc_pkcs15_tokeninfo_t tokeninfo;

	if (ctx->debug > 4)
		sc_debug(ctx, "trying normal pkcs15 processing\n");

	/* Enumerate apps now */
	if (card->app_count < 0) {
		err = sc_enum_apps(card);
		if (err < 0 && err != SC_ERROR_FILE_NOT_FOUND) {
			sc_error(ctx, "unable to enumerate apps: %s\n", sc_strerror(err));
			goto end;
		}
	}
	p15card->file_app = sc_file_new();
	if (p15card->file_app == NULL) {
		err = SC_ERROR_OUT_OF_MEMORY;
		goto end;
	}
	sc_format_path("3F005015", &p15card->file_app->path);
	if (card->app_count > 0) {
		const sc_app_info_t *info;
		
		info = sc_find_pkcs15_app(card);
		if (info != NULL) {
			if (info->path.len)
				p15card->file_app->path = info->path;
			if (info->ddo != NULL)
				parse_ddo(p15card, info->ddo, info->ddo_len);
		}
	}

	/* Check if pkcs15 directory exists */
	sc_ctx_suppress_errors_on(card->ctx);
	err = sc_select_file(card, &p15card->file_app->path, NULL);
#if 1
	/* If the above test failed on cards without EF(DIR),
	 * try to continue read ODF from 3F005031. -aet
	 */
	if ((err == SC_ERROR_FILE_NOT_FOUND) &&
	    (card->app_count < 1)) {
		sc_format_path("3F00", &p15card->file_app->path);
		err = SC_NO_ERROR;
	}
#endif
	sc_ctx_suppress_errors_off(card->ctx);
	if (err < 0)
		goto end;

	if (p15card->file_odf == NULL) {
		/* check if an ODF is present; suppress errors as we
		 * don't know yet whether we have a pkcs15 card */
		tmppath = p15card->file_app->path;
		sc_append_path_id(&tmppath, (const u8 *) "\x50\x31", 2);
		sc_ctx_suppress_errors_on(card->ctx);
		err = sc_select_file(card, &tmppath, &p15card->file_odf);
		sc_ctx_suppress_errors_off(card->ctx);
		
	} else {
		tmppath = p15card->file_odf->path;
		sc_file_free(p15card->file_odf);
		p15card->file_odf = NULL;
		err = sc_select_file(card, &tmppath, &p15card->file_odf);
	}
	if (err != SC_SUCCESS) {
		char pbuf[SC_MAX_PATH_STRING_SIZE];

		int r = sc_path_print(pbuf, sizeof(pbuf), &tmppath);
		if (r != SC_SUCCESS)
			pbuf[0] = '\0';

		sc_debug(ctx, "EF(ODF) not found in '%s'\n", pbuf);
		goto end;
	}

	if ((len = p15card->file_odf->size) == 0) {
		sc_error(card->ctx, "EF(ODF) is empty\n");
		goto end;
	}
	buf = malloc(len);
	if(buf == NULL)
		return SC_ERROR_OUT_OF_MEMORY;
	err = sc_read_binary(card, 0, buf, len, 0);
	if (err < 0)
		goto end;
	if (err < 2) {
		err = SC_ERROR_PKCS15_APP_NOT_FOUND;
		goto end;
	}
	len = err;
	if (parse_odf(buf, len, p15card)) {
		err = SC_ERROR_PKCS15_APP_NOT_FOUND;
		sc_error(card->ctx, "Unable to parse ODF\n");
		goto end;
	}
	free(buf);
	buf = NULL;

	if (card->ctx->debug) {
		sc_pkcs15_df_t *df;

		sc_debug(card->ctx, "The following DFs were found:\n");
		for (df = p15card->df_list; df; df = df->next) {
			char pbuf[SC_MAX_PATH_STRING_SIZE];

			int r = sc_path_print(pbuf, sizeof(pbuf), &df->path);
			if (r != SC_SUCCESS)
				pbuf[0] = '\0';

			sc_debug(card->ctx,
				"  DF type %u, path %s, index %u, count %d\n",
				df->type, pbuf, df->path.index, df->path.count);
		}
	}

	if (p15card->file_tokeninfo == NULL) {
		tmppath = p15card->file_app->path;
		sc_append_path_id(&tmppath, (const u8 *) "\x50\x32", 2);
	} else {
		tmppath = p15card->file_tokeninfo->path;
		sc_file_free(p15card->file_tokeninfo);
		p15card->file_tokeninfo = NULL;
	}
	err = sc_select_file(card, &tmppath, &p15card->file_tokeninfo);
	if (err)
		goto end;

	if ((len = p15card->file_tokeninfo->size) == 0) {
		sc_error(card->ctx, "EF(TokenInfo) is empty\n");
		goto end;
	}
	buf = malloc(len);
	if(buf == NULL)
		return SC_ERROR_OUT_OF_MEMORY;
	err = sc_read_binary(card, 0, buf, len, 0);
	if (err < 0)
		goto end;
	if (err <= 2) {
		err = SC_ERROR_PKCS15_APP_NOT_FOUND;
		goto end;
	}

	memset(&tokeninfo, 0, sizeof(tokeninfo));
	err = sc_pkcs15_parse_tokeninfo(ctx, &tokeninfo, buf, (size_t)err);
	if (err != SC_SUCCESS)
		goto end;
	p15card->version         = tokeninfo.version;
	p15card->label           = tokeninfo.label;
	p15card->serial_number   = tokeninfo.serial_number;
	p15card->manufacturer_id = tokeninfo.manufacturer_id;
	p15card->last_update     = tokeninfo.last_update;
	p15card->flags           = tokeninfo.flags;
	p15card->preferred_language = tokeninfo.preferred_language;
	p15card->seInfo          = tokeninfo.seInfo;
	p15card->num_seInfo      = tokeninfo.num_seInfo;

	/* for cardos cards initialized by Siemens: sign with decrypt */
	if (strcmp(p15card->card->driver->short_name,"cardos") == 0
                && ( strcmp(p15card->manufacturer_id,"Siemens AG (C)") == 0
			|| strcmp(p15card->manufacturer_id,"Prime") == 0 ))
		p15card->flags |= SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT;

	ok = 1;
end:
	if(buf != NULL)
		free(buf);
	if (!ok) {
		sc_pkcs15_card_clear(p15card);
		return err;
	}

	return SC_SUCCESS;
}
Example #8
0
static int do_find(int argc, char **argv)
{
	u8 fid[2], end[2];
	sc_path_t path;
	int r;

	fid[0] = 0;
	fid[1] = 0;
	end[0] = 0xFF;
	end[1] = 0xFF;
	switch (argc) {
	case 2:
		if (arg_to_fid(argv[1], end) != 0)
			return usage(do_find);
		/* fall through */
	case 1:
		if (arg_to_fid(argv[0], fid) != 0)
			return usage(do_find);
		/* fall through */
	case 0:
		break;
	default:
		return usage(do_find);
	}

	printf("FileID\tType  Size\n");
	while (1) {
		sc_file_t *file = NULL;

		printf("(%02X%02X)\r", fid[0], fid[1]);
		fflush(stdout);

		if (current_path.type != SC_PATH_TYPE_DF_NAME) {
			path = current_path;
			sc_append_path_id(&path, fid, sizeof fid);
		} else {
			if (sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, 2, 0, 0) != SC_SUCCESS) {
				printf("unable to set path.\n");
				die(1);
			}
		}

		r = sc_select_file(card, &path, &file);
		switch (r) {
		case SC_SUCCESS:
			file->id = (fid[0] << 8) | fid[1];
			print_file(file);
			sc_file_free(file);
			select_current_path_or_die();
			break;
		case SC_ERROR_NOT_ALLOWED:
		case SC_ERROR_SECURITY_STATUS_NOT_SATISFIED:
			printf("(%02X%02X)\t%s\n", fid[0], fid[1], sc_strerror(r));
			break;
		}

		if (fid[0] == end[0] && fid[1] == end[1])
			break;
		fid[1] = fid[1] + 1;
		if (fid[1] == 0)
			fid[0] = fid[0] + 1;
	}
	return 0;
}