コード例 #1
0
ファイル: pkcs15-sc-hsm.c プロジェクト: PhoenixBaymax/OpenSC
static int read_file(sc_pkcs15_card_t * p15card, u8 fid[2],
		u8 *efbin, size_t *len)
{
	sc_path_t path;
	int r;

	sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, 2, 0, 0);
	/* look this up with our AID */
	path.aid = sc_hsm_aid;
	/* we don't have a pre-known size of the file */
	path.count = -1;
	if (!p15card->opts.use_file_cache
			|| SC_SUCCESS != sc_pkcs15_read_cached_file(p15card, &path, &efbin, len)) {
		/* avoid re-selection of SC-HSM */
		path.aid.len = 0;
		r = sc_select_file(p15card->card, &path, NULL);
		LOG_TEST_RET(p15card->card->ctx, r, "Could not select EF");

		r = sc_read_binary(p15card->card, 0, efbin, *len, 0);
		LOG_TEST_RET(p15card->card->ctx, r, "Could not read EF");

		*len = r;

		if (p15card->opts.use_file_cache) {
			/* save this with our AID */
			path.aid = sc_hsm_aid;
			sc_pkcs15_cache_file(p15card, &path, efbin, *len);
		}
	}

	return SC_SUCCESS;
}
コード例 #2
0
int sc_pkcs15_read_file(struct sc_pkcs15_card *p15card,
			const sc_path_t *in_path,
			u8 **buf, size_t *buflen,
			sc_file_t **file_out)
{
	sc_file_t *file = NULL;
	u8	*data = NULL;
	size_t	len = 0, offset = 0;
	int	r;

	assert(p15card != NULL && in_path != NULL && buf != NULL);

	if (p15card->card->ctx->debug >= 1) {
		char pbuf[SC_MAX_PATH_STRING_SIZE];

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

		sc_debug(p15card->card->ctx, "called, path=%s, index=%u, count=%d\n",
			pbuf, in_path->index, in_path->count);
	}

	r = -1; /* file state: not in cache */
	if (p15card->opts.use_cache) {
		r = sc_pkcs15_read_cached_file(p15card, in_path, &data, &len);
	}
	if (r) {
		r = sc_lock(p15card->card);
		SC_TEST_RET(p15card->card->ctx, r, "sc_lock() failed");
		r = sc_select_file(p15card->card, in_path, &file);
		if (r)
			goto fail_unlock;

		/* Handle the case where the ASN.1 Path object specified
		 * index and length values */
		if (in_path->count < 0) {
			len = file->size;
			offset = 0;
		} else {
			offset = in_path->index;
			len = in_path->count;
			/* Make sure we're within proper bounds */
			if (offset >= file->size
			 || offset + len > file->size) {
				r = SC_ERROR_INVALID_ASN1_OBJECT;
				goto fail_unlock;
			}
		}
		data = (u8 *) malloc(len);
		if (data == NULL) {
			r = SC_ERROR_OUT_OF_MEMORY;
			goto fail_unlock;
		}
		if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE_TLV) {
			int i;
			size_t l, record_len;
			unsigned char *head;

			head = data;
			for (i=1;  ; i++) {
				l = len - (head - data);
				if (l > 256) { l = 256; }
				p15card->card->ctx->suppress_errors++;
				r = sc_read_record(p15card->card, i, head, l,
						SC_RECORD_BY_REC_NR);
				p15card->card->ctx->suppress_errors--;
				if (r == SC_ERROR_RECORD_NOT_FOUND)
					break;
				if (r < 0) {
					free(data);
					goto fail_unlock;
				}
				if (r < 2)
					break;
				record_len = head[1];
				if (record_len != 0xff) {
					memmove(head,head+2,r-2);
					head += (r-2);
				} else {
					if (r < 4)
						break;
					record_len = head[2] * 256 + head[3];
					memmove(head,head+4,r-4);
					head += (r-4);
				}
			}
			len = head-data;
			r = len;
		} else {
			r = sc_read_binary(p15card->card, offset, data, len, 0);
			if (r < 0) {
				free(data);
				goto fail_unlock;
			}
			/* sc_read_binary may return less than requested */
			len = r;
		} 
		sc_unlock(p15card->card);

		/* Return of release file */
		if (file_out != NULL)
			*file_out = file;
		else
			sc_file_free(file);
	}
	*buf = data;
	*buflen = len;
	return 0;

fail_unlock:
	if (file)
		sc_file_free(file);
	sc_unlock(p15card->card);
	return r;
}