Example #1
0
static unsigned int t1_build(t1_state_t * t1, unsigned char *block,
			     unsigned char dad, unsigned char pcb,
			     ct_buf_t * bp, size_t * lenp)
{
	unsigned int len;

	len = bp ? ct_buf_avail(bp) : 0;
	if (len > t1->ifsc) {
		pcb |= T1_MORE_BLOCKS;
		len = t1->ifsc;
	}

	/* Add the sequence number */
	switch (t1_block_type(pcb)) {
	case T1_R_BLOCK:
		pcb |= t1->nr << T1_R_SEQ_SHIFT;
		break;
	case T1_I_BLOCK:
		pcb |= t1->ns << T1_I_SEQ_SHIFT;
		break;
	}

	block[0] = dad;
	block[1] = pcb;
	block[2] = len;

	if (len)
		memcpy(block + 3, ct_buf_head(bp), len);
	if (lenp)
		*lenp = len;

	return t1_compute_checksum(t1, block, len + 3);
}
Example #2
0
File: conf.c Project: OpenSC/openct
/*
 * Eat initial white space from buffer
 */
static int skipws(void)
{
	unsigned int m, n, in_comment = 0;
	char *s;

      again:
	s = (char *)ct_buf_head(&config_buf);
	n = ct_buf_avail(&config_buf);

	for (m = 0; m < n; m++, s++) {
		if (*s == '#') {
			in_comment = 1;
		} else if (!in_comment && !isspace((int)*s)) {
			break;
		} else if (*s == '\n') {
			config_line++;
			in_comment = 0;
		}
	}

	ct_buf_get(&config_buf, NULL, m);
	if (in_comment) {
		if (ct_buf_read(&config_buf, config_fd) < 0) {
			ct_error("%s: error while reading file: %m",
				 config_filename);
			return -1;
		}
		goto again;
	}

	return 0;
}
Example #3
0
static int do_transact_old(ifd_reader_t * reader, int unit, ct_buf_t * args,
			   ct_buf_t * resp)
{
	int rc;

	rc = ifd_card_command(reader, unit,
			      ct_buf_head(args), ct_buf_avail(args),
			      ct_buf_tail(resp), ct_buf_tailroom(resp));
	if (rc < 0)
		return rc;

	ct_buf_put(resp, NULL, rc);
	return 0;
}
Example #4
0
static int t0_send(ifd_protocol_t * prot, ct_buf_t * bp, int count)
{
	int n, avail;

	avail = ct_buf_avail(bp);
	if (count < 0)
		count = avail;
	if (count > avail || !avail)
		return -1;
	n = ifd_send_command(prot, ct_buf_head(bp), count);
	if (n >= 0)
		ct_buf_get(bp, NULL, count);
	return n;
}
Example #5
0
File: conf.c Project: OpenSC/openct
/*
 * Tokenizer
 */
static int get_token(char **tok)
{
	static char buffer[512];
	unsigned int m, n, copy, retry = 1;
	char *s;

	/* consume initial white space */
	if (skipws() < 0)
		return -1;

      again:
	s = (char *)ct_buf_head(&config_buf);
	n = ct_buf_avail(&config_buf);

	if (n && issepa(*s)) {
		m = 1;
	} else {
		for (m = 0; !isspace((int)s[m]) && !issepa(s[m]) && m < n;
		     m++) ;
	}

	/* If we hit the end of the buffer while scanning
	 * for white space, read more data and try 
	 * again */
	if (m >= n && retry) {
		if (ct_buf_read(&config_buf, config_fd) < 0) {
			ct_error("%s: error while reading file: %m",
				 config_filename);
			return -1;
		}
		retry = 0;
		goto again;
	}

	if (m == 0)
		return -1;

	if ((copy = m) >= sizeof(buffer))
		copy = sizeof(buffer) - 1;
	memcpy(buffer, s, copy);
	buffer[copy] = '\0';
	ct_buf_get(&config_buf, NULL, m);

	ifd_debug(5, "ifd_config_parse: token=\"%s\"", buffer);

	*tok = buffer;
	return 0;
}
unsigned int t1_build(t1_state_t * t1, unsigned char *block,
	unsigned char dad, unsigned char pcb,
	ct_buf_t *bp, size_t *lenp)
{
	unsigned int len;
	char more = FALSE;

	len = bp ? ct_buf_avail(bp) : 0;
	if (len > t1->ifsc) {
		pcb |= T1_MORE_BLOCKS;
		len = t1->ifsc;
		more = TRUE;
	}

	/* Add the sequence number */
	switch (t1_block_type(pcb)) {
	case T1_R_BLOCK:
		pcb |= t1->nr << T1_R_SEQ_SHIFT;
		break;
	case T1_I_BLOCK:
		pcb |= t1->ns << T1_I_SEQ_SHIFT;
		t1->more = more;
		DEBUG_COMM2("more bit: %d", more);
		break;
	}

	block[0] = dad;
	block[1] = pcb;
	block[2] = len;

	if (len)
		memcpy(block + 3, ct_buf_head(bp), len);
	if (lenp)
		*lenp = len;

	len = t1_compute_checksum(t1, block, len + 3);

	/* memorize the last sent block */
	/* only 4 bytes since we are only interesed in R-blocks */
	memcpy(t1->previous_block, block, 4);

	return len;
}
Example #7
0
File: tlv.c Project: OpenSC/openct
/*
 * Parse TLV data
 */
int ct_tlv_parse(ct_tlv_parser_t * parser, ct_buf_t * bp)
{
	unsigned int avail, len;
	unsigned char *p, tag;

	/* Code below relies on it */
	assert(((ifd_tag_t) - 1) == 255);

	while ((avail = ct_buf_avail(bp)) != 0) {
		unsigned int header = 2;

		if (avail < 2)
			return -1;

		p = (unsigned char *)ct_buf_head(bp);
		tag = p[0];
		len = p[1];

		if (tag & __CT_TAG_LARGE) {
			parser->use_large_tags = 1;
			tag &= ~__CT_TAG_LARGE;
			if (avail < 3)
				return -1;
			len = (len << 8) | p[header++];
		}

		if (len == 0 || header + len > avail)
			return -1;

		parser->val[tag] = p + header;
		parser->len[tag] = len;

		ct_buf_get(bp, NULL, header + len);
	}

	return 0;
}
Example #8
0
/*
 * Process commands from local clients (i.e. those allowed
 * to claim a device).
 */
static int ria_svc_app_handler(ct_socket_t * sock, header_t * hdr,
                               ct_buf_t * args, ct_buf_t * resp)
{
    unsigned char cmd;
    ria_peer_t *clnt, *peer;
    int rc;

    clnt = (ria_peer_t *) sock->user_data;
    ria_print_packet(sock, 2, "app >>", hdr, args);

    if (ct_buf_get(args, &cmd, 1) < 0)
        return IFD_ERROR_INVALID_MSG;

    switch (cmd) {
    case RIA_MGR_LIST:
        peer = &clients;
        ifd_debug(1, "%s requests a device listing",
                  clnt->device.address);
        while ((peer = peer->next) != &clients) {
            if (peer->device.name[0] != '\0')
                ct_buf_put(resp, &peer->device,
                           sizeof(peer->device));
        }
        return 0;

    case RIA_MGR_INFO:
        peer =
            ria_find_device((const char *)ct_buf_head(args),
                            ct_buf_avail(args));
        if (peer == NULL)
            return IFD_ERROR_UNKNOWN_DEVICE;
        ct_buf_put(resp, &peer->device, sizeof(peer->device));
        return 0;

    case RIA_MGR_CLAIM:
        peer =
            ria_find_device((const char *)ct_buf_head(args),
                            ct_buf_avail(args));
        if (peer == NULL)
            return IFD_ERROR_UNKNOWN_DEVICE;
        if (peer->peer)
            return IFD_ERROR_DEVICE_BUSY;
        ifd_debug(1, "%s claimed %s device %s/%s",
                  clnt->device.address,
                  peer->device.type,
                  peer->device.address, peer->device.name);
        ct_buf_put(resp, &peer->device, sizeof(peer->device));
        clnt->peer = peer;
        peer->peer = clnt;
        return 0;
    }

    if (cmd < __RIA_PEER_CMD_BASE)
        return IFD_ERROR_INVALID_CMD;

    /* All subsequent commands require a device */
    if ((peer = clnt->peer) == NULL)
        return IFD_ERROR_NOT_CONNECTED;

    /* Push back the command byte */
    ct_buf_push(args, &cmd, 1);
    rc = ct_socket_put_packet(peer->sock, hdr, args);

    /* Tell the caller not to send a response */
    hdr->xid = 0;
    return rc;
}