Exemplo n.º 1
0
static void display_data(const struct ef_name_map *map, u8 *data, size_t length)
{
	if (map != NULL && data != NULL) {
		char buffer[8192];
		char *value = NULL;

		if (opt_raw) {
			/* length-wise safe, but may cut off data (safe for OpenPGP cards 2.x) */
			if (length > sizeof(buffer))
				 length = sizeof(buffer);

			if (map->type == TYPE_HEX) {
				if (exec_program) {
					value = prettify_hex(data, length, buffer, sizeof(buffer));
				}
				else {
					sc_hex_dump(data, length, buffer, sizeof(buffer));
					/* remove trailing newline */
					if (*buffer != '\0' && buffer[strlen(buffer)-1] == '\n')
						buffer[strlen(buffer)-1] = '\0';
					value = buffer;
				}
			}
			else {
				value = (char *) data;
			}
		}
		else {
			if (map->prettify_value != NULL)
				value = map->prettify_value(data, length);
			else {
				value = (map->type == TYPE_HEX)
					? prettify_hex(data, length, buffer, sizeof(buffer))
					: (char *) data;
			}
		}

		if (value != NULL) {
			if (exec_program) {
				char *envvar= malloc(strlen(map->env_name) +
							strlen(value) + 2);

				if (envvar != NULL) {
					strcpy(envvar, map->env_name);
					strcat(envvar, "=");
					strcat(envvar, value);
					putenv(envvar);
					/* envvar deliberately kept: see putenv(3) */
				}
			}
			else {
				const char *label = map->name;
				int fill = (int) (INDENT - strlen(label));

				printf("%s:%*s%s\n", label, fill, "", value);
			}
		}
	}
}
Exemplo n.º 2
0
/* Return the SE number from the keyD for the FID.  If ref_data is not
   NULL the reference data is returned; this shoudl be an array of at
   least 2 bytes.  Returns -1 on error.  */
static int get_se_num_from_keyd(sc_card_t * card, unsigned short fid,
				u8 * ref_data)
{
	sc_context_t *ctx = card->ctx;
	struct df_info_s *dfi;
	struct keyd_record_s *keyd;
	size_t len, taglen;
	const u8 *p, *tag;
	char dbgbuf[2048];
	u8 fidbuf[2];

	fidbuf[0] = fid >> 8;
	fidbuf[1] = fid;

	dfi = get_df_info(card);
	if (!dfi || !dfi->keyd_file) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "EF_keyD not loaded\n");
		return -1;
	}

	for (keyd = dfi->keyd_file; keyd; keyd = keyd->next) {
		p = keyd->data;
		len = keyd->datalen;

		sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL,
			p, len, dbgbuf, sizeof dbgbuf);
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "keyd no %d:\n%s", keyd->recno, dbgbuf);

		tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen);
		if (!tag || taglen != 4 ||
		    !(tag[2] == fidbuf[0] && tag[3] == fidbuf[1]))
			continue;
		/* Found a matching record. */
		if (ref_data) {
			ref_data[0] = tag[0];
			ref_data[1] = tag[1];
		}
		/* Look for the SE-DO */
		tag = sc_asn1_find_tag(ctx, p, len, 0x7B, &taglen);
		if (!tag || !taglen)
			continue;
		p = tag;
		len = taglen;
		/* And now look for the referenced SE. */
		tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen);
		if (!tag || taglen != 1)
			continue;
		return *tag;	/* found. */
	}
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "EF_keyD for %04hx not found\n", fid);
	return -1;
}
Exemplo n.º 3
0
void sc_apdu_log(sc_context_t *ctx, int level, const u8 *data, size_t len, int is_out)
{
	size_t blen = len * 5 + 128;
	char   *buf = malloc(blen);
	if (buf == NULL)
		return;

	sc_hex_dump(ctx, level, data, len, buf, blen);

	sc_debug(ctx, level, "\n%s APDU data [%5u bytes] =====================================\n"
		"%s"
		"======================================================================\n",
		is_out != 0 ? "Outgoing" : "Incoming", len,
		buf);
	free(buf);
}
Exemplo n.º 4
0
void _bin_log(sc_context_t *ctx, int type, const char *file, int line,
        const char *func, const char *label, const u8 *data, size_t len,
        FILE *f)
{
    if (!f) {
        char buf[1800];
        if (data)
            sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, data, len, buf, sizeof buf);
        else
            buf[0] = 0;
        sc_do_log(ctx, type, file, line, func,
                "\n%s (%u byte%s)%s%s",
                label, (unsigned int) len, len==1?"":"s", len==0?"":":\n", buf);
    } else {
        fprintf(f, "%s (%u byte%s)%s%s\n",
                label, (unsigned int) len, len==1?"":"s", len==0?"":":\n", sc_dump_hex(data, len));
    }
}
Exemplo n.º 5
0
Arquivo: log.c Projeto: DDvO/OpenSC
void _sc_debug_hex(sc_context_t *ctx, int type, const char *file, int line,
        const char *func, const char *label, const u8 *data, size_t len)
{
	size_t blen = len * 5 + 128;
	char *buf = malloc(blen);
	if (buf == NULL)
		return;

    sc_hex_dump(ctx, type, data, len, buf, blen);

    if (label)
        sc_do_log(ctx, type, file, line, func,
                "\n%s (%u byte%s):\n%s",
                label, (unsigned int) len, len==1?"":"s", buf);
    else
        sc_do_log(ctx, type, file, line, func,
                "%u byte%s:\n%s",
                (unsigned int) len, len==1?"":"s", buf);

	free(buf);
}
Exemplo n.º 6
0
/* Process an ARR (7816-9/8.5.4) and setup the ACL. */
static void process_arr(sc_card_t * card, sc_file_t * file,
			const u8 * buf, size_t buflen)
{
	sc_context_t *ctx = card->ctx;
	struct df_info_s *dfi;
	struct rule_record_s *rule;
	size_t left, taglen;
	unsigned int cla, tag;
	const u8 *p;
	int skip;
	char dbgbuf[2048];

	/* Currently we support only the short for. */
	if (buflen != 1) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "can't handle long ARRs\n");
		return;
	}

	dfi = get_df_info(card);
	for (rule = dfi ? dfi->rule_file : NULL; rule && rule->recno != *buf;
	     rule = rule->next) ;
	if (!rule) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "referenced EF_rule record %d not found\n", *buf);
		return;
	}

	sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL,
		rule->data, rule->datalen, dbgbuf, sizeof dbgbuf);
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
		"rule for record %d:\n%s", *buf, dbgbuf);

	p = rule->data;
	left = rule->datalen;
	skip = 1;		/* Skip over initial unknown SC DOs. */
	for (;;) {
		buf = p;
		if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) !=
		    SC_SUCCESS)
			break;
		left -= (p - buf);
		tag |= cla;

		if (tag == 0x80 && taglen != 1) {
			skip = 1;
		} else if (tag == 0x80) {	/* AM byte. */
			sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "  AM_DO: %02x\n", *p);
			skip = 0;
		} else if (tag >= 0x81 && tag <= 0x8f) {	/* Cmd description */
			sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, p, taglen, dbgbuf, sizeof dbgbuf);
			sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "  AM_DO: cmd[%s%s%s%s] %s",
				 (tag & 8) ? "C" : "",
				 (tag & 4) ? "I" : "",
				 (tag & 2) ? "1" : "",
				 (tag & 1) ? "2" : "", dbgbuf);
			skip = 0;
		} else if (tag == 0x9C) {	/* Proprietary state machine descrip. */
			skip = 1;
		} else if (!skip) {
			sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, p, taglen, dbgbuf, sizeof dbgbuf);
			switch (tag) {
			case 0x90:	/* Always */
				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "     SC: always\n");
				break;
			case 0x97:	/* Never */
				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "     SC: never\n");
				break;
			case 0xA4:	/* Authentication, value is a CRT. */
				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "     SC: auth %s", dbgbuf);
				break;

			case 0xB4:
			case 0xB6:
			case 0xB8:	/* Cmd or resp with SM, value is a CRT. */
				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "     SC: cmd/resp %s", dbgbuf);
				break;

			case 0x9E:	/* Security Condition byte. */
				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "     SC: condition %s", dbgbuf);
				break;

			case 0xA0:	/* OR template. */
				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "     SC: OR\n");
				break;
			case 0xAF:	/* AND template. */
				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "     SC: AND\n");
				break;
			}
		}
		left -= taglen;
		p += taglen;
	}

}
Exemplo n.º 7
0
static int
sm_oberthur_diversify_keyset(struct sc_context *ctx, struct sm_info *sm_info,
		unsigned char *idata, size_t idata_len)
{
	struct sm_gp_session *gp_session = &sm_info->session.gp;
	struct sm_gp_keyset *gp_keyset = &sm_info->session.gp.gp_keyset;
	unsigned char master_key[16] = {
		0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
	};
	unsigned char *keys[3] = {
		gp_keyset->enc,
		gp_keyset->mac,
		gp_keyset->kek
	};
	unsigned char key_buff[16];
	unsigned char *tmp;
	int rv = 0, ii, tmp_len;

	if (gp_keyset->kmc_len == 48)   {
		for (ii=0; ii<3; ii++)
			memcpy(keys[ii], gp_keyset->kmc + 16*ii, 16);
	}
	else if (gp_keyset->kmc_len == 16 || gp_keyset->kmc_len == 0)   {
		if (gp_keyset->kmc_len == 16)
			memcpy(master_key, gp_keyset->kmc, 16);
		sc_log(ctx, "KMC: %s", sc_dump_hex(master_key, sizeof(master_key)));
		for (ii=0; ii<3; ii++)   {
			key_buff[0] = key_buff[8] = 0;
			key_buff[1] = key_buff[9] = 0;
			key_buff[2] = key_buff[10] = *(idata + 6);
			key_buff[3] = key_buff[11] = *(idata + 7);
			key_buff[4] = key_buff[12] = *(idata + 8);
			key_buff[5] = key_buff[13] = *(idata + 9);
			key_buff[6] = 0xF0,  key_buff[14] = 0x0F;
			key_buff[7] = key_buff[15] = ii+1;

			sc_log(ctx, "key_buf:%s", sc_dump_hex(key_buff, 16));

			rv = sm_encrypt_des_ecb3(master_key, key_buff, sizeof(key_buff), &tmp, &tmp_len);
			LOG_TEST_RET(ctx, rv, "GP init session: cannot derivate key");

			memcpy(keys[ii], tmp, sizeof(gp_keyset->enc));
			free(tmp);
		}
	}
	else   {
		LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "GP init session: invalid KMC data");
	}

	if (!rv && ctx)   {
		char dump_buf[2048];

		sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL,
				gp_session->card_challenge, sizeof(gp_session->card_challenge), dump_buf, sizeof(dump_buf));
		sc_log(ctx, "Card challenge: %s", dump_buf);

		sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL,
				gp_session->host_challenge, sizeof(gp_session->host_challenge), dump_buf, sizeof(dump_buf));
		sc_log(ctx, "Host challenge: %s", dump_buf);

		sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, gp_keyset->enc, sizeof(gp_keyset->enc), dump_buf, sizeof(dump_buf));
		sc_log(ctx, "ENC: %s", dump_buf);

		sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, gp_keyset->mac, sizeof(gp_keyset->mac), dump_buf, sizeof(dump_buf));
		sc_log(ctx, "MAC: %s", dump_buf);

		sc_hex_dump(ctx, SC_LOG_DEBUG_NORMAL, gp_keyset->kek, sizeof(gp_keyset->kek), dump_buf, sizeof(dump_buf));
		sc_log(ctx, "KEK: %s", dump_buf);
	}

	return rv;

}