Beispiel #1
0
int sc_pkcs15_cache_file(struct sc_pkcs15_card *p15card,
			 const sc_path_t *path,
			 const u8 *buf, size_t bufsize)
{
	char fname[PATH_MAX];
	int r;
	FILE *f;
	size_t c;

	r = generate_cache_filename(p15card, path, fname, sizeof(fname));
	if (r != 0)
		return r;

	f = fopen(fname, "wb");
	/* If the open failed because the cache directory does
	 * not exist, create it and a re-try the fopen() call.
	 */
	if (f == NULL && errno == ENOENT) {
		if ((r = sc_make_cache_dir(p15card->card->ctx)) < 0)
			return r;
		f = fopen(fname, "wb");
	}
	if (f == NULL)
		return 0;

	c = fwrite(buf, 1, bufsize, f);
	fclose(f);
	if (c != bufsize) {
		sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "fwrite() wrote only %d bytes", c);
		unlink(fname);
		return SC_ERROR_INTERNAL;
	}
	return 0;
}
Beispiel #2
0
int sc_pkcs15_read_cached_file(struct sc_pkcs15_card *p15card,
			       const sc_path_t *path,
			       u8 **buf, size_t *bufsize)
{
	char fname[PATH_MAX];
	int r;
	FILE *f;
	size_t count, offset, got;
	struct stat stbuf;
	u8 *data = NULL;

	r = generate_cache_filename(p15card, path, fname, sizeof(fname));
	if (r != 0)
		return r;
	r = stat(fname, &stbuf);
	if (r)
		return SC_ERROR_FILE_NOT_FOUND;
	if (path->count < 0) {
		count = stbuf.st_size;
		offset = 0;
	} else {
		count = path->count;
		offset = path->index;
		if (offset + count > (size_t)stbuf.st_size)
			return SC_ERROR_FILE_NOT_FOUND; /* cache file bad? */
	}
	if (*buf == NULL) {
		data = malloc((size_t)stbuf.st_size);
		if (data == NULL)
			return SC_ERROR_OUT_OF_MEMORY;
	} else
		if (count > *bufsize)
			return SC_ERROR_BUFFER_TOO_SMALL;
	f = fopen(fname, "rb");
	if (f == NULL) {
		if (data)
			free(data);
		return SC_ERROR_FILE_NOT_FOUND;
	}
	if (offset) {
		if (0 != fseek(f, (long)offset, SEEK_SET)) {
			fclose(f);
			free(data);
			return SC_ERROR_FILE_NOT_FOUND;
		}
	}
	if (data)
		*buf = data;
	got = fread(*buf, 1, count, f);
	fclose(f);
	if (got != count) {
		if (data)
			free(data);
		return SC_ERROR_BUFFER_TOO_SMALL;
	}
	*bufsize = count;
	if (data)
		*buf = data;
	return 0;
}
Beispiel #3
0
int sc_pkcs15_read_cached_file(struct sc_pkcs15_card *p15card,
				const sc_path_t *path,
				u8 **buf, size_t *bufsize)
{
	char fname[PATH_MAX];
	int rv;
	FILE *f;
	size_t count;
	struct stat stbuf;
	u8 *data = NULL;

	if (path->len < 2)
		return SC_ERROR_INVALID_ARGUMENTS;

	/* Accept full path or FILE-ID path with AID */
	if ((path->type != SC_PATH_TYPE_PATH) && (path->type != SC_PATH_TYPE_FILE_ID || path->aid.len == 0))
		return SC_ERROR_INVALID_ARGUMENTS;

	sc_log(p15card->card->ctx, "try to read cache for %s", sc_print_path(path));
	rv = generate_cache_filename(p15card, path, fname, sizeof(fname));
	if (rv != SC_SUCCESS)
		return rv;
	sc_log(p15card->card->ctx, "read cached file %s", fname);

	f = fopen(fname, "rb");
	if (!f)
		return SC_ERROR_FILE_NOT_FOUND;
	if (fstat(fileno(f), &stbuf))   {
		fclose(f);
		return  SC_ERROR_FILE_NOT_FOUND;
	}

	if (path->count < 0) {
		count = stbuf.st_size;
	}
	else {
		count = path->count;
		if (path->index + count > (size_t)stbuf.st_size)   {
			rv = SC_ERROR_FILE_NOT_FOUND; /* cache file bad? */
			goto err;
		}

		if (0 != fseek(f, (long)path->index, SEEK_SET)) {
			rv = SC_ERROR_FILE_NOT_FOUND;
			goto err;
		}
	}

	if (*buf == NULL) {
		data = malloc((size_t)stbuf.st_size);
		if (data == NULL)   {
			rv = SC_ERROR_OUT_OF_MEMORY;
			goto err;
		}
	}
	else if (count > *bufsize)  {
		rv =  SC_ERROR_BUFFER_TOO_SMALL;
		goto err;
	}

	if (data)
		*buf = data;

	if (count != fread(*buf, 1, count, f)) {
		rv = SC_ERROR_BUFFER_TOO_SMALL;
		goto err;
	}
	*bufsize = count;

	rv = SC_SUCCESS;

err:
	if (rv != SC_SUCCESS)
		if (data)
			free(data);

	fclose(f);
	return rv;
}