示例#1
0
文件: card.c 项目: AktivCo/OpenSC
int sc_write_binary(sc_card_t *card, unsigned int idx,
		    const u8 *buf, size_t count, unsigned long flags)
{
	size_t max_lc = sc_get_max_send_size(card);
	int r;

	if (card == NULL || card->ops == NULL || buf == NULL) {
		return SC_ERROR_INVALID_ARGUMENTS;
	}
	sc_log(card->ctx, "called; %"SC_FORMAT_LEN_SIZE_T"u bytes at index %d",
	       count, idx);
	if (count == 0)
		LOG_FUNC_RETURN(card->ctx, 0);
	if (card->ops->write_binary == NULL)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);

	if (count > max_lc) {
		int bytes_written = 0;
		const u8 *p = buf;

		r = sc_lock(card);
		LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
		while (count > 0) {
			size_t n = count > max_lc? max_lc : count;
			r = sc_write_binary(card, idx, p, n, flags);
			if (r < 0) {
				sc_unlock(card);
				LOG_TEST_RET(card->ctx, r, "sc_write_binary() failed");
			}
			p += r;
			idx += r;
			bytes_written += r;
			count -= r;
			if (r == 0) {
				sc_unlock(card);
				LOG_FUNC_RETURN(card->ctx, bytes_written);
			}
		}
		sc_unlock(card);
		LOG_FUNC_RETURN(card->ctx, bytes_written);
	}

	r = card->ops->write_binary(card, idx, buf, count, flags);
	LOG_FUNC_RETURN(card->ctx, r);
}
示例#2
0
文件: card.c 项目: DDvO/OpenSC
int sc_write_binary(sc_card_t *card, unsigned int idx,
		    const u8 *buf, size_t count, unsigned long flags)
{
	size_t max_lc = sc_get_max_send_size(card);
	int r;

	assert(card != NULL && card->ops != NULL && buf != NULL);
	sc_log(card->ctx, "called; %d bytes at index %d", count, idx);
	if (count == 0)
		LOG_FUNC_RETURN(card->ctx, 0);
	if (card->ops->write_binary == NULL)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);

	if (count > max_lc) {
		int bytes_written = 0;
		const u8 *p = buf;

		r = sc_lock(card);
		LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
		while (count > 0) {
			size_t n = count > max_lc? max_lc : count;
			r = sc_write_binary(card, idx, p, n, flags);
			if (r < 0) {
				sc_unlock(card);
				LOG_TEST_RET(card->ctx, r, "sc_write_binary() failed");
			}
			p += r;
			idx += r;
			bytes_written += r;
			count -= r;
			if (r == 0) {
				sc_unlock(card);
				LOG_FUNC_RETURN(card->ctx, bytes_written);
			}
		}
		sc_unlock(card);
		LOG_FUNC_RETURN(card->ctx, bytes_written);
	}

	r = card->ops->write_binary(card, idx, buf, count, flags);
	LOG_FUNC_RETURN(card->ctx, r);
}
示例#3
0
文件: card.c 项目: securez/opendnie
int sc_write_binary(sc_card_t *card, unsigned int idx,
		    const u8 *buf, size_t count, unsigned long flags)
{
	size_t max_lc = card->max_send_size > 0 ? card->max_send_size : 255;
	int r;

	assert(card != NULL && card->ops != NULL && buf != NULL);
	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
		"called; %d bytes at index %d\n", count, idx);
	if (count == 0)
		return 0;
	if (card->ops->write_binary == NULL)
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED);
	if (count > max_lc) {
		int bytes_written = 0;
		const u8 *p = buf;

		r = sc_lock(card);
		SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_lock() failed");
		while (count > 0) {
			size_t n = count > max_lc? max_lc : count;
			r = sc_write_binary(card, idx, p, n, flags);
			if (r < 0) {
				sc_unlock(card);
				SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_write_binary() failed");
			}
			p += r;
			idx += r;
			bytes_written += r;
			count -= r;
			if (r == 0) {
				sc_unlock(card);
				SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, bytes_written);
			}
		}
		sc_unlock(card);
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, bytes_written);
	}
	r = card->ops->write_binary(card, idx, buf, count, flags);
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
}
示例#4
0
/*
 * Initialize pin file
 */
static int
gpk_init_pinfile(struct sc_profile *profile, sc_pkcs15_card_t *p15card,
		sc_file_t *file)
{
	const sc_acl_entry_t *acl;
	unsigned char	buffer[GPK_MAX_PINS * 8], *blk;
	struct sc_file	*pinfile;
	unsigned int	so_attempts[2], user_attempts[2];
	unsigned int	npins, i, j, cks;
	int		r;

	SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
	/* Set defaults */
	so_attempts[0] = sc_profile_get_pin_retries(profile, SC_PKCS15INIT_SO_PIN);
	so_attempts[1] = sc_profile_get_pin_retries(profile, SC_PKCS15INIT_SO_PUK);
	user_attempts[0] = sc_profile_get_pin_retries(profile, SC_PKCS15INIT_USER_PIN);
	user_attempts[1] = sc_profile_get_pin_retries(profile, SC_PKCS15INIT_USER_PUK);

	sc_file_dup(&pinfile, file);
	if (pinfile == NULL)
		return SC_ERROR_OUT_OF_MEMORY;

	/* Create the PIN file. */
	acl = sc_file_get_acl_entry(pinfile, SC_AC_OP_WRITE);
	if (acl->method != SC_AC_NEVER) {
		sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL,
			"PIN file most be protected by WRITE=NEVER");
		sc_file_free(pinfile);
		return SC_ERROR_INVALID_ARGUMENTS;
	}
	sc_file_add_acl_entry(pinfile, SC_AC_OP_WRITE, SC_AC_NONE, 0);

	if (pinfile->size == 0)
		pinfile->size = GPK_MAX_PINS * 8;

	sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Now create file");
	/* Now create the file */
	if ((r = sc_pkcs15init_create_file(profile, p15card, pinfile)) < 0
	 || (r = sc_select_file(p15card->card, &pinfile->path, NULL)) < 0)   {
		goto out;
	}

	/* Set up the PIN file contents.
	 * We assume the file will contain pairs of PINs/PUKs */
	npins = pinfile->size / 8;
	memset(buffer, 0, sizeof(buffer));
	for (i = 0, blk = buffer; i < npins; blk += 8, i += 1) {
		/* Determine the number of PIN/PUK presentation
		 * attempts. If the profile defines a SO PIN,
		 * it will be stored in the first PIN/PUK pair.
		 */
		blk[0] = user_attempts[i & 1];
		if (i < 2 && so_attempts[0])
			blk[0] = so_attempts[i & 1];
		if ((i & 1) == 0) {
			/* This is a PIN. If there's room in the file,
			 * the next will be a PUK so take note of the
			 * unlock code */
			if (i + 1 < npins)
				blk[2] = GPK_PIN_SCOPE | (i + 1);
		}

		/* Compute the CKS */
		for (j = 0, cks = 0; j < 8; j++)
			cks ^= blk[j];
		blk[3] = ~cks;
	}

	r = sc_write_binary(p15card->card, 0, buffer, npins * 8, 0);
	if (r >= 0)
		r = gpk_lock_pinfile(profile, p15card, pinfile);

out:	sc_file_free(pinfile);
	SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r);
}
示例#5
0
文件: scutil.c 项目: consp/vsmartcard
int write_binary_rec(sc_card_t *card, unsigned char sfid,
        u8 *ef, size_t ef_len)
{
    int r;
    size_t write = MAX_SM_APDU_DATA_SIZE, wrote = 0;
    sc_apdu_t apdu;
#ifdef ENABLE_SM
    struct iso_sm_ctx *iso_sm_ctx = card->sm_ctx.info.cmd_data;
#endif

    if (!card) {
        r = SC_ERROR_INVALID_ARGUMENTS;
        goto err;
    }

#ifdef ENABLE_SM
    if (write > SC_MAX_APDU_BUFFER_SIZE-2
            || (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT
                && write > (((SC_MAX_APDU_BUFFER_SIZE-2
                    /* for encrypted APDUs we usually get authenticated status
                     * bytes (4B), a MAC (11B) and a cryptogram with padding
                     * indicator (3B without data).  The cryptogram is always
                     * padded to the block size. */
                    -18) / iso_sm_ctx->block_length)
                    * iso_sm_ctx->block_length - 1)))
        sc_format_apdu(card, &apdu, SC_APDU_CASE_3_EXT,
                ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0);
    else
#endif
        sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT,
                ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0);

    if (write > ef_len) {
        apdu.datalen = ef_len;
        apdu.lc = ef_len;
    } else {
        apdu.datalen = write;
        apdu.lc = write;
    }
    apdu.data = ef;


    r = sc_transmit_apdu(card, &apdu);
    /* emulate the behaviour of sc_write_binary */
    if (r >= 0)
        r = apdu.datalen;

    while (1) {
        if (r < 0 || r > ef_len) {
            sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not write EF.");
            goto err;
        }
        wrote += r;
        apdu.data += r;
        if (wrote >= ef_len)
            break;

        r = sc_write_binary(card, wrote, ef, write, 0);
    }

    r = SC_SUCCESS;

err:
    return r;
}