Esempio n. 1
0
void sc_pkcs15_format_id(const char *str, struct sc_pkcs15_id *id)
{
	size_t len = sizeof(id->value);

	if (sc_hex_to_bin(str, id->value, &len) >= 0)
		id->len = len;
}
static int atrust_acos_match_card(struct sc_card *card)
{
	int		i, match = 0;
  

	for (i = 0; atrust_acos_atrs[i] != NULL; i++) 
	{
		u8 defatr[SC_MAX_ATR_SIZE];
		size_t len = sizeof(defatr);
		const char *atrp = atrust_acos_atrs[i];
      
		if (sc_hex_to_bin(atrp, defatr, &len))
			continue;
		/* we may only verify part of ATR since */
		/* part of the hist chars is variable */
		if (len > card->atr_len)
			continue;
		if (memcmp(card->atr, defatr, len) != 0)
			continue;

		match = 1;
		card->name = atrust_acos_names[i];

		break;
    }
	return match;
}
Esempio n. 3
0
static int get_conf_aid(sc_card_t *card, u8 *aid, size_t *len)
{
    sc_context_t		*ctx = card->ctx;
    scconf_block		*conf_block, **blocks;
    int			i;
    const char		*str_aid;

    SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

    conf_block = NULL;
    for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
        blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
                                    "card", "gemsafeV1");
        if (blocks[0] != NULL)
            conf_block = blocks[0];
        free(blocks);
    }

    if (!conf_block) {
        sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no card specific options configured, trying default AID\n");
        return SC_ERROR_INTERNAL;
    }

    str_aid = scconf_get_str(conf_block, "aid", NULL);
    if (!str_aid) {
        sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no aid configured, trying default AID\n");
        return SC_ERROR_INTERNAL;
    }
    return sc_hex_to_bin(str_aid, aid, len);
}
Esempio n. 4
0
int sc_pkcs15_encode_tokeninfo(sc_context_t *ctx,
			       sc_pkcs15_tokeninfo_t *ti,
			       u8 **buf, size_t *buflen)
{
	int r;
	int version = ti->version;
	size_t serial_len, mnfid_len, label_len, flags_len, last_upd_len;
	
	struct sc_asn1_entry asn1_toki[14], asn1_tokeninfo[2];

	sc_copy_asn1_entry(c_asn1_toki, asn1_toki);
	sc_copy_asn1_entry(c_asn1_tokeninfo, asn1_tokeninfo);
	version--;
	sc_format_asn1_entry(asn1_toki + 0, &version, NULL, 1);
	if (ti->serial_number != NULL) {
		u8 serial[128];
		serial_len = 0;
		if (strlen(ti->serial_number)/2 > sizeof(serial))
			return SC_ERROR_BUFFER_TOO_SMALL;
		serial_len = sizeof(serial);
		if (sc_hex_to_bin(ti->serial_number, serial, &serial_len) < 0)
			return SC_ERROR_INVALID_ARGUMENTS;
		sc_format_asn1_entry(asn1_toki + 1, serial, &serial_len, 1);
	} else
		sc_format_asn1_entry(asn1_toki + 1, NULL, NULL, 0);
	if (ti->manufacturer_id != NULL) {
		mnfid_len = strlen(ti->manufacturer_id);
		sc_format_asn1_entry(asn1_toki + 2, ti->manufacturer_id, &mnfid_len, 1);
	} else
		sc_format_asn1_entry(asn1_toki + 2, NULL, NULL, 0);
	if (ti->label != NULL) {
		label_len = strlen(ti->label);
		sc_format_asn1_entry(asn1_toki + 3, ti->label, &label_len, 1);
	} else
		sc_format_asn1_entry(asn1_toki + 3, NULL, NULL, 0);
	if (ti->flags) {
		flags_len = sizeof(ti->flags);
		sc_format_asn1_entry(asn1_toki + 5, &ti->flags, &flags_len, 1);
	} else
		sc_format_asn1_entry(asn1_toki + 5, NULL, NULL, 0);
	sc_format_asn1_entry(asn1_toki + 6, NULL, NULL, 0);
	sc_format_asn1_entry(asn1_toki + 7, NULL, NULL, 0);
	sc_format_asn1_entry(asn1_toki + 8, NULL, NULL, 0);
	sc_format_asn1_entry(asn1_toki + 9, NULL, NULL, 0);
	sc_format_asn1_entry(asn1_toki + 10, NULL, NULL, 0);
	if (ti->last_update != NULL) {
		last_upd_len = strlen(ti->last_update);
		sc_format_asn1_entry(asn1_toki + 11, ti->last_update, &last_upd_len, 1);
	} else
		sc_format_asn1_entry(asn1_toki + 11, NULL, NULL, 0);
	sc_format_asn1_entry(asn1_toki + 12, NULL, NULL, 0);
	sc_format_asn1_entry(asn1_tokeninfo, asn1_toki, NULL, 1);

	r = sc_asn1_encode(ctx, asn1_tokeninfo, buf, buflen);
	if (r) {
		sc_error(ctx, "sc_asn1_encode() failed: %s\n", sc_strerror(r));
		return r;
	}
	return 0;
}
static int arg_to_path(const char *arg, sc_path_t *path, int is_id)
{
	memset(path, 0, sizeof(sc_path_t));

	if (strncasecmp(arg, "aid:", strlen("aid:")) == 0) {
		/* DF aid */
		const char *p = arg + strlen("aid:");
		int r;

		path->type = SC_PATH_TYPE_DF_NAME;
		path->len  = sizeof(path->value);
		if ((r = sc_hex_to_bin(p, path->value, &path->len)) < 0) {
			printf("Error parsing AID: %s\n", p);
			return r;
		}
	} else {
		/* file id */
		unsigned int buf[2];
		u8 cbuf[2];

		if (strlen(arg) != 4) {
			printf("Wrong ID length.\n");
			return -1;
		}
		if (sscanf(arg, "%02X%02X", &buf[0], &buf[1]) != 2) {
			printf("Invalid ID.\n");
			return -1;
		}
		cbuf[0] = buf[0];
		cbuf[1] = buf[1];
		if ((cbuf[0] == 0x3F && cbuf[1] == 0x00) || is_id) {
			path->len = 2;
			memcpy(path->value, cbuf, 2);
			path->type = (is_id) ? SC_PATH_TYPE_FILE_ID : SC_PATH_TYPE_PATH;
		} else {
			*path = current_path;
			if (path->type == SC_PATH_TYPE_DF_NAME)   {
				if (path->len > sizeof(path->aid.value))   {
					printf("Invalid length of DF_NAME path\n");
					return -1;
				}

				memcpy(path->aid.value, path->value, path->len);
				path->aid.len = path->len;

				path->type = SC_PATH_TYPE_FILE_ID;
				path->len = 0;
			}
			sc_append_path_id(path, cbuf, 2);
		}
	}

	return 0;
}
Esempio n. 6
0
/**
 * Delete key, for OpenPGP card.
 * This function is not complete and is reserved for future version (> 2) of OpenPGP card.
 **/
int delete_key_openpgp(sc_card_t *card, u8 in_key_id)
{
	char *del_fingerprint = "00:DA:00:C6:14:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00";
	char *del_creationtime = "00:DA:00:CD:04:00:00:00:00";
	/* We need to replace the 4th byte later */
	char *apdustring = NULL;
	u8 buf[SC_MAX_APDU_BUFFER_SIZE];
	u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
	sc_apdu_t apdu;
	size_t len0;
	int i;
	int r = SC_SUCCESS;

	for (i = 0; i < 2; i++) {
		if (i == 0)    /* Reset fingerprint */
			apdustring = del_fingerprint;
		else           /* Reset creation time */
			apdustring = del_creationtime;
		/* Convert the string to binary array */
		len0 = sizeof(buf);
		sc_hex_to_bin(apdustring, buf, &len0);

		/* Replace DO tag, subject to key ID */
		buf[3] = buf[3] + in_key_id;

		/* Build APDU from binary array */
		r = sc_bytes2apdu(card->ctx, buf, len0, &apdu);
		if (r) {
			util_error("failed to build APDU: %s", sc_strerror(r));
			return r;
		}
		apdu.resp = rbuf;
		apdu.resplen = sizeof(rbuf);

		/* Send APDU to card */
		r = sc_transmit_apdu(card, &apdu);
		if (r) {
			util_error("transmitting APDU failed: %s", sc_strerror(r));
			return r;
		}
	}
	/* TODO: Rewrite Extended Header List.
	 * Not support by OpenGPG v2 yet */
	return r;
}
Esempio n. 7
0
static int do_apdu(int argc, char **argv)
{
	sc_apdu_t apdu;
	u8 buf[SC_MAX_APDU_BUFFER_SIZE];
	u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
	size_t len, len0, r, ii;

	if (argc < 1) {
		puts("Usage: apdu [apdu:hex:codes:...]");
		return -1;
	}

	for (ii = 0, len = 0; ii < (unsigned) argc; ii++)   {
		len0 = strlen(argv[ii]);
		sc_hex_to_bin(argv[ii], buf + len, &len0);
		len += len0;
	}

	r = sc_bytes2apdu(card->ctx, buf, len, &apdu);
	if (r) {
		fprintf(stderr, "Invalid APDU: %s\n", sc_strerror(r));
		return 2;
	}

	apdu.resp = rbuf;
	apdu.resplen = sizeof(rbuf);

	printf("Sending: ");
	for (r = 0; r < len0; r++)
		printf("%02X ", buf[r]);
	printf("\n");
	r = sc_transmit_apdu(card, &apdu);
	if (r) {
		fprintf(stderr, "APDU transmit failed: %s\n", sc_strerror(r));
		return 1;
	}
	printf("Received (SW1=0x%02X, SW2=0x%02X)%s\n", apdu.sw1, apdu.sw2,
	       apdu.resplen ? ":" : "");
	if (apdu.resplen)
		util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);

	return 0;
}
Esempio n. 8
0
static int
sm_gp_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info)
{
	scconf_block *sm_conf_block = NULL, **blocks;
	struct sm_gp_keyset *gp_keyset = &sm_info->session.gp.gp_keyset;

	const char *kmc = NULL;
	unsigned char hex[48];
	size_t hex_len = sizeof(hex);
	int rv, ii;

	sc_log(ctx, "SM get KMC from config section '%s'", sm_info->config_section);
        for (ii = 0; ctx->conf_blocks[ii]; ii++) {
		blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[ii], "secure_messaging", sm_info->config_section);
		if (blocks) {
			sm_conf_block = blocks[0];
			free(blocks);
		}

		if (sm_conf_block)
			break;
	}

	kmc = scconf_get_str(sm_conf_block, "kmc", NULL);
	if (!kmc)
		return SC_ERROR_SM_KEYSET_NOT_FOUND;

	rv = sc_hex_to_bin(kmc, hex, &hex_len);
	if (rv)   {
		sc_log(ctx, "SM get KMC: hex to bin failed for '%s'; error %i", kmc, rv);
		return SC_ERROR_UNKNOWN_DATA_RECEIVED;
	}

	sc_log(ctx, "SM type:%X, KMC(%i) %s", sm_info->sm_type, hex_len, sc_dump_hex(hex, hex_len));
	if (hex_len != 16 && hex_len != 48 )
		return SC_ERROR_INVALID_DATA;

	memcpy(gp_keyset->kmc, hex, hex_len);
	gp_keyset->kmc_len = hex_len;

	return SC_SUCCESS;
}
Esempio n. 9
0
static void write_dg(sc_card_t *card, unsigned char sfid, const char *dg_str,
        const char *dg_hex)
{
    unsigned char dg[0xff];
    size_t dg_len = sizeof dg;
    int r;

    r = sc_hex_to_bin(dg_hex, dg, &dg_len);
    if (r < 0) {
        fprintf(stderr, "Could not parse DG %02u %s (%s)\n",
                sfid, dg_str, sc_strerror(r));
    } else {
        r = write_binary_rec(card, sfid, dg, dg_len);
        if (r < 0)
            fprintf(stderr, "Could not write DG %02u %s (%s)\n",
                    sfid, dg_str, sc_strerror(r));
        else
            printf("Wrote DG %02u %s\n", sfid, dg_str);
    }
}
Esempio n. 10
0
static int
do_aid(struct state *cur, int argc, char **argv)
{
	struct sc_file	*file = cur->file->file;
	const char	*name = argv[0];
	unsigned int	len;
	int		res = 0;

	if (*name == '=') {
		len = strlen(++name);
		if (len > sizeof(file->name)) {
			parse_error(cur, "AID \"%s\" too long\n", name);
			return 1;
		}
		memcpy(file->name, name, len);
		file->namelen = len;
	} else {
		file->namelen = sizeof(file->name);
		res = sc_hex_to_bin(name, file->name, &file->namelen);
	}
	return res;
}
Esempio n. 11
0
static int parse_string_or_hexdata(const char *in, u8 *out, size_t *outlen)
{
	if (in == NULL)
		return SC_ERROR_INVALID_ARGUMENTS;

	if (*in == '"') {
		u8 quote = *in++;
		size_t count = 0;

		while (*in != quote && *in != '\0' && count < *outlen)
			out[count++] = *in++;
		if (*in == '\0')
			return SC_ERROR_INVALID_ARGUMENTS;
		if (count >= *outlen)
			return SC_ERROR_BUFFER_TOO_SMALL;

		*outlen = count;
		return 0;
	}
	else
		return sc_hex_to_bin(in, out, outlen);
}
Esempio n. 12
0
static int
do_key_value(struct state *cur, int argc, char **argv)
{
	struct auth_info *ai = cur->key;
	const char	*key = argv[0];
	size_t		key_len;
	unsigned char	keybuf[32];

	if (key[0] == '=') {
		++key;
		key_len = strlen(key);
		memcpy(keybuf, key, key_len);
	} else {
		key_len = sizeof(keybuf);
		if (sc_hex_to_bin(key, keybuf, &key_len)) {
			parse_error(cur, "Error parsing PIN/key \"%s\"\n", key);
			return 1;
		}
	}

	memcpy(ai->key, keybuf, key_len);
	ai->key_len = key_len;
	return 0;
}
Esempio n. 13
0
static void initialize(sc_card_t *card, const char *so_pin, const char *user_pin, int retry_counter, int dkek_shares)
{
	sc_cardctl_sc_hsm_init_param_t param;
	size_t len;
	char *_so_pin = NULL, *_user_pin = NULL;
	int r;

	if (so_pin == NULL) {
		printf("Enter SO-PIN (16 hexadecimal characters) : ");
		util_getpass(&_so_pin, NULL, stdin);
		printf("\n");
	} else {
		_so_pin = (char *)so_pin;
	}

	len = sizeof(param.init_code);
	r = sc_hex_to_bin(_so_pin, param.init_code, &len);
	if (r < 0) {
		fprintf(stderr, "Error decoding initialization code (%s)\n", sc_strerror(r));
		return;
	}

	if (len != 8) {
		fprintf(stderr, "SO-PIN must be a hexadecimal string of 16 characters\n");
		return;
	}

	if (user_pin == NULL) {
		printf("Enter initial User-PIN (6 - 16 characters) : ");
		util_getpass(&_user_pin, NULL, stdin);
		printf("\n");
	} else {
		_user_pin = (char *)user_pin;
	}

	param.user_pin_len = strlen(_user_pin);

	if (param.user_pin_len < 6) {
		fprintf(stderr, "PIN must be at least 6 characters long\n");
		return;
	}

	if (param.user_pin_len > 16) {
		fprintf(stderr, "PIN must not be longer than 16 characters\n");
		return;
	}

	if ((param.user_pin_len == 6) && (retry_counter > 3)) {
		fprintf(stderr, "Retry counter must not exceed 3 for a 6 digit PIN. Use a longer PIN for a higher retry counter.\n");
		return;
	}

	if ((param.user_pin_len == 7) && (retry_counter > 5)) {
		fprintf(stderr, "Retry counter must not exceed 5 for a 7 digit PIN. Use a longer PIN for a higher retry counter.\n");
		return;
	}

	if (retry_counter > 10) {
		fprintf(stderr, "Retry counter must not exceed 10\n");
		return;
	}

	param.user_pin = (u8 *)_user_pin;

	param.user_pin_retry_counter = (u8)retry_counter;

	param.options[0] = 0x00;
	param.options[1] = 0x01;

	param.dkek_shares = (char)dkek_shares;

	r = sc_card_ctl(card, SC_CARDCTL_SC_HSM_INITIALIZE, (void *)&param);
	if (r < 0) {
		fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_SC_HSM_INITIALIZE, *) failed with %s\n", sc_strerror(r));
	}
}
static int send_apdu(void)
{
	sc_apdu_t apdu;
	u8 buf[SC_MAX_APDU_BUFFER_SIZE], sbuf[SC_MAX_APDU_BUFFER_SIZE],
	   rbuf[SC_MAX_APDU_BUFFER_SIZE], *p;
	size_t len, len0, r;
	int c;

	for (c = 0; c < opt_apdu_count; c++) {
		len0 = sizeof(buf);
		sc_hex_to_bin(opt_apdus[c], buf, &len0);
		if (len0 < 4) {
			fprintf(stderr, "APDU too short (must be at least 4 bytes).\n");
			return 2;
		}
		len = len0;
		p = buf;
		memset(&apdu, 0, sizeof(apdu));
		apdu.cla = *p++;
		apdu.ins = *p++;
		apdu.p1 = *p++;
		apdu.p2 = *p++;
		apdu.resp = rbuf;
		apdu.resplen = sizeof(rbuf);
		len -= 4;
		if (len > 1) {
			apdu.lc = *p++;
			len--;
			memcpy(sbuf, p, apdu.lc);
			apdu.data = sbuf;
			apdu.datalen = apdu.lc;
			if (len < apdu.lc) {
				fprintf(stderr, "APDU too short (need %lu bytes).\n",
					(unsigned long) apdu.lc-len);
				return 2;
			}
			len -= apdu.lc;
			p   += apdu.lc;
			if (len) {
				apdu.le = *p++;
				if (apdu.le == 0)
					apdu.le = 256;
				len--;
				apdu.cse = SC_APDU_CASE_4_SHORT;
			} else
				apdu.cse = SC_APDU_CASE_3_SHORT;
			if (len) {
				fprintf(stderr, "APDU too long (%lu bytes extra).\n",
					(unsigned long) len);
				return 2;
			}
		} else if (len == 1) {
			apdu.le = *p++;
			if (apdu.le == 0)
				apdu.le = 256;
			len--;
			apdu.cse = SC_APDU_CASE_2_SHORT;
		} else
			apdu.cse = SC_APDU_CASE_1;
		printf("Sending: ");
		for (r = 0; r < len0; r++)
			printf("%02X ", buf[r]);
		printf("\n");
		r = sc_transmit_apdu(card, &apdu);
		if (r) {
			fprintf(stderr, "APDU transmit failed: %s\n", sc_strerror(r));
			return 1;
		}
		printf("Received (SW1=0x%02X, SW2=0x%02X)%s\n", apdu.sw1, apdu.sw2,
		       apdu.resplen ? ":" : "");
		if (apdu.resplen)
			hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);
	}
	return 0;
}
Esempio n. 15
0
static int cardos_change_startkey(const char *change_startkey_apdu)
{
	#define MAX_APDU 60
	unsigned char cardos_version[2];
	unsigned char apdu_bin[MAX_APDU];
	size_t apdu_len=MAX_APDU;
	unsigned char checksum[SHA_DIGEST_LENGTH];

	static const unsigned char cardos_43b_checksum[SHA_DIGEST_LENGTH] =
		{  0x5C, 0xD6, 0x8C, 0x2C, 0x24, 0x77, 0x3C, 0xDC,
		   0x93, 0x73, 0xD8, 0x4B, 0x47, 0x29, 0x19, 0x70,
		   0x9F, 0xA2, 0x42, 0xB4  };
	sc_apdu_t apdu;
	u8 rbuf[256];
	int r;
	
	if (verbose)	{
		printf ("Change StartKey APDU:\n");
		util_hex_dump_asc(stdout, (unsigned char *)change_startkey_apdu,
			strlen(change_startkey_apdu), -1);
		}
	
	/* use GET DATA for version - 00 ca 01 82
	 * returns e.g. c8 09 for 4.2B
	 */

	memset(&apdu, 0, sizeof(apdu));
	apdu.cla = 0x00;
	apdu.ins = 0xca;
	apdu.p1 = 0x01;
	apdu.p2 = 0x82;
	apdu.resp = rbuf;
	apdu.resplen = sizeof(rbuf);
	apdu.lc = 0;
	apdu.le = 256;
	apdu.cse = SC_APDU_CASE_2_SHORT;
	r = sc_transmit_apdu(card, &apdu);
	if (r) {
		fprintf(stderr, "APDU transmit failed: %s\n",
			sc_strerror(r));
		return 1;
	}
	if (apdu.sw1 != 0x90 || apdu.sw2 != 00 || verbose) {
		fprintf(stderr, "Received (SW1=0x%02X, SW2=0x%02X)%s\n",
			apdu.sw1, apdu.sw2, apdu.resplen ? ":" : "");
		if (apdu.resplen)
			util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);
		return 1;
	}
	if (apdu.resplen != 0x02) {
		printf("did not receive version info, aborting\n");
		return 1;
	}

	/* check all supported versions here. need a checksum check
	   for each of them below */
	if ( (rbuf[0] != 0xc8 || rbuf[1] != 0x08) ) { /* M4.3B */
		printf("currently only CardOS M4.01, M4.2B, M4.2C and M4.3B are supported, aborting\n");
		return 1;
	}
	cardos_version[0] = rbuf[0];
	cardos_version[1] = rbuf[1];

	/* GET DATA for startkey index - 00 ca 01 96
	 * returns 6 bytes PackageLoadKey.Version, PackageLoadKey.Retry
	 * Startkey.Version, Startkey.Retry, 2 internal data byes */

	memset(&apdu, 0, sizeof(apdu));
	apdu.cla = 0x00;
	apdu.ins = 0xca;
	apdu.p1 = 0x01;
	apdu.p2 = 0x96;
	apdu.resp = rbuf;
	apdu.resplen = sizeof(rbuf);
	apdu.lc = 0;
	apdu.le = 256;
	apdu.cse = SC_APDU_CASE_2_SHORT;
	r = sc_transmit_apdu(card, &apdu);
	if (r) {
		fprintf(stderr, "APDU transmit failed: %s\n",
			sc_strerror(r));
		return 1;
	}
	if (apdu.sw1 != 0x90 || apdu.sw2 != 00 || verbose) {
		fprintf(stderr, "Received (SW1=0x%02X, SW2=0x%02X)%s\n",
			apdu.sw1, apdu.sw2, apdu.resplen ? ":" : "");
		if (apdu.resplen)
			util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);
		return 1;
	}
	if (apdu.resplen < 0x04) {
		printf("expected 4-6 bytes form GET DATA for startkey data, but got only %ld\n", apdu.resplen);
		printf("aborting\n");
		return 1;
	}

	if (apdu.resp[2] != 0x00) {
		printf("startkey version is 0x%02x, currently we support only 0x00\n", (int) apdu.resp[3]);
		printf("aborting\n");
		return 1;
	}

	if (apdu.resp[3] < 5) {
		printf("startkey has only %d tries left. to be safe: aborting\n", apdu.resp[3]);
		return 1;
	}	

	/* now check if the correct APDU was passed */
	if (sc_hex_to_bin(change_startkey_apdu, apdu_bin, &apdu_len) != 0) {
		printf("can't convert startkey apdu to binary format: aborting\n");
		return 1;
	}
	SHA1(apdu_bin, apdu_len, checksum);

	if (cardos_version[0] == 0xc8 && cardos_version[1] == 0x08) {
		if (memcmp(checksum, cardos_43b_checksum, SHA_DIGEST_LENGTH) != 0) {
			printf("change startkey apdu is wrong, checksum doesn't match\n");
			util_hex_dump_asc(stdout, checksum, SHA_DIGEST_LENGTH, -1);  
			util_hex_dump_asc(stdout, cardos_43b_checksum, SHA_DIGEST_LENGTH, -1);  
			printf("aborting\n");
			return 1;
		}
		goto change_startkey;
	}
	
	printf("checksum for your card not yet implemented, aborting\n");
	return 1;
	
change_startkey:
	/* run change startkey apdu */

	memset(&apdu, 0, sizeof(apdu));
	apdu.cla = apdu_bin[0];
	apdu.ins = apdu_bin[1];
	apdu.p1 = apdu_bin[2];
	apdu.p2 = apdu_bin[3];
	apdu.lc = apdu_bin[4];
	apdu.data = &apdu_bin[5];
	apdu.datalen = apdu.lc;
	apdu.resp = 00;
	apdu.le = 00;
	apdu.cse = SC_APDU_CASE_3_SHORT;
	r = sc_transmit_apdu(card, &apdu);
	if (r) {
		fprintf(stderr, "APDU transmit failed: %s\n",
			sc_strerror(r));
		return 1;
	}
	if (apdu.sw1 != 0x90 || apdu.sw2 != 00 || verbose) {
		fprintf(stderr, "Received (SW1=0x%02X, SW2=0x%02X)%s\n",
			apdu.sw1, apdu.sw2, apdu.resplen ? ":" : "");
		if (apdu.resplen)
			util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);
		return 1;
	}

	printf("change startkey command issued with success\n");

	/* GET DATA for startkey index - 00 ca 01 96
	 * returns 6 bytes PackageLoadKey.Version, PackageLoadKey.Retry
	 * Startkey.Version, Startkey.Retry, 2 internal data byes */

	memset(&apdu, 0, sizeof(apdu));
	apdu.cla = 0x00;
	apdu.ins = 0xca;
	apdu.p1 = 0x01;
	apdu.p2 = 0x96;
	apdu.resp = rbuf;
	apdu.resplen = sizeof(rbuf);
	apdu.lc = 0;
	apdu.le = 256;
	apdu.cse = SC_APDU_CASE_2_SHORT;
	r = sc_transmit_apdu(card, &apdu);
	if (r) {
		fprintf(stderr, "APDU transmit failed: %s\n",
			sc_strerror(r));
		return 1;
	}
	if (apdu.sw1 != 0x90 || apdu.sw2 != 00 || verbose) {
		fprintf(stderr, "Received (SW1=0x%02X, SW2=0x%02X)%s\n",
			apdu.sw1, apdu.sw2, apdu.resplen ? ":" : "");
		if (apdu.resplen)
			util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);
		return 1;
	}
	if (apdu.resplen < 0x04) {
		printf("expected 4-6 bytes form GET DATA for startkey data, but got only %ld\n", apdu.resplen);
		printf("aborting\n");
		return 1;
	}

	if (apdu.resp[2] != 0xff) {
		printf("startkey version is 0x%02x, should have been changed to 0xff.\n", apdu.resp[2]);
		printf("aborting\n");
		return 1;
	}

	printf("startkey is now 0xff, success!\n");
	return 0;
}
Esempio n. 16
0
int npa_translate_apdus(sc_card_t *card, FILE *input)
{
    u8 buf[4 + 3 + 0xffff + 3];
    char *read = NULL;
    size_t readlen = 0, apdulen;
    sc_apdu_t apdu;
    ssize_t linelen;
    int r;

    memset(&apdu, 0, sizeof apdu);

    while (1) {
        if (input == stdin)
            printf("Enter unencrypted C-APDU (empty line to exit)\n");

        linelen = getline(&read, &readlen, input);
        if (linelen <= 1) {
            if (linelen < 0) {
                r = SC_ERROR_INTERNAL;
                sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,
                        "Could not read line");
            } else {
                r = SC_SUCCESS;
                printf("Thanks for flying with ccid\n");
            }
            break;
        }
        read[linelen - 1] = 0;

        apdulen = sizeof buf;
        if (sc_hex_to_bin(read, buf, &apdulen) < 0) {
            sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,
                    "Could not format binary string");
            continue;
        }
        if (input != stdin)
            bin_print(stdout, "Unencrypted C-APDU", buf, apdulen);

        r = sc_bytes2apdu(card->ctx, buf, apdulen, &apdu);
        if (r < 0) {
            bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid C-APDU", buf, apdulen);
            continue;
        }

        apdu.resp = buf;
        apdu.resplen = sizeof buf;

        r = sc_transmit_apdu(card, &apdu);
        if (r < 0) {
            sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,
                    "Could not send C-APDU: %s", sc_strerror(r));
            continue;
        }

        printf("Decrypted R-APDU sw1=%02x sw2=%02x\n", apdu.sw1, apdu.sw2);
        bin_print(stdout, "Decrypted R-APDU response data", apdu.resp, apdu.resplen);
        printf("======================================================================\n");
    }

    if (read)
        free(read);

    return r;
}
Esempio n. 17
0
int main(int argc, char * const argv[])
{
	int err = 0, r, c, long_optind = 0;
	int do_decipher = 0;
	int do_sign = 0;
	int action_count = 0;
        struct sc_pkcs15_object *key;
	sc_context_param_t ctx_param;

	while (1) {
		c = getopt_long(argc, argv, "sck:r:i:o:f:Rp:vw", options, &long_optind);
		if (c == -1)
			break;
		if (c == '?')
			util_print_usage_and_die(app_name, options, option_help, NULL);
		switch (c) {
		case 's':
			do_sign++;
			action_count++;
			break;
		case 'c':
			do_decipher++;
			action_count++;
			break;
		case 'k':
			opt_key_id = optarg;
			action_count++;
			break;
		case 'r':
			opt_reader = optarg;
			break;
		case 'i':
			opt_input = optarg;
			break;
		case 'o':
			opt_output = optarg;
			break;
		case 'f':
			opt_sig_format = optarg;
			break;
		case 'R':
			opt_raw = 1;
			break;
		case OPT_SHA1:
			opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1;
			break;
		case OPT_SHA256:
			opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256;
			break;
		case OPT_SHA384:
			opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384;
			break;
		case OPT_SHA512:
			opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512;
			break;
		case OPT_SHA224:
			opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA224;
			break;
		case OPT_MD5:
			opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5;
			break;
		case OPT_PKCS1:
			opt_crypt_flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
			break;
		case 'v':
			verbose++;
			break;
		case 'p':
			opt_pincode = optarg;
			break;
		case OPT_BIND_TO_AID:
			opt_bind_to_aid = optarg;
			break;
		case 'w':
			opt_wait = 1;
			break;
		}
	}
	if (action_count == 0)
		util_print_usage_and_die(app_name, options, option_help, NULL);

	if (!(opt_crypt_flags & SC_ALGORITHM_RSA_HASHES))
		opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_NONE;

	memset(&ctx_param, 0, sizeof(ctx_param));
	ctx_param.ver      = 0;
	ctx_param.app_name = app_name;

	r = sc_context_create(&ctx, &ctx_param);
	if (r) {
		fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r));
		return 1;
	}

	if (verbose > 1) {
		ctx->debug = verbose;
		sc_ctx_log_to_file(ctx, "stderr");
	}

	err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
	if (err)
		goto end;

	if (verbose)
		fprintf(stderr, "Trying to find a PKCS #15 compatible card...\n");
	if (opt_bind_to_aid)   {
		struct sc_aid aid;

		aid.len = sizeof(aid.value);
		if (sc_hex_to_bin(opt_bind_to_aid, aid.value, &aid.len))   {
			fprintf(stderr, "Invalid AID value: '%s'\n", opt_bind_to_aid);
			return 1;
		}

		r = sc_pkcs15_bind(card, &aid, &p15card);
	}
	else   {
		r = sc_pkcs15_bind(card, NULL, &p15card);
	}
	if (r) {
		fprintf(stderr, "PKCS #15 binding failed: %s\n", sc_strerror(r));
		err = 1;
		goto end;
	}
	if (verbose)
		fprintf(stderr, "Found %s!\n", p15card->tokeninfo->label);

	if (do_decipher) {
		if ((err = get_key(SC_PKCS15_PRKEY_USAGE_DECRYPT, &key))
		 || (err = decipher(key)))
			goto end;
		action_count--;
	}

	if (do_sign) {
		if ((err = get_key(SC_PKCS15_PRKEY_USAGE_SIGN|
				   SC_PKCS15_PRKEY_USAGE_SIGNRECOVER|
				   SC_PKCS15_PRKEY_USAGE_NONREPUDIATION, &key))
		 || (err = sign(key)))
			goto end;
		action_count--;
	}
end:
	if (p15card)
		sc_pkcs15_unbind(p15card);
	if (card) {
		sc_unlock(card);
		sc_disconnect_card(card);
	}
	if (ctx)
		sc_release_context(ctx);
	return err;
}
Esempio n. 18
0
int main(int argc, char * const argv[])
{
	int err = 0, r, c, long_optind = 0;
	int do_list_sdos = 0;
	int do_list_apps = 0;
	int action_count = 0;
	sc_context_param_t ctx_param;

	setbuf(stderr, NULL);
	setbuf(stdout, NULL);

	while (1) {
		c = getopt_long(argc, argv, "v", options, &long_optind);
		if (c == -1)
			break;
		if (c == '?')
			util_print_usage_and_die(app_name, options, option_help, NULL);
		switch (c) {
                case OPT_LIST_SDOS:
                        do_list_sdos = 1;
                        opt_sdo_tag = optarg;
                        action_count++;
                        break;
		case OPT_LIST_APPLICATIONS:
			do_list_apps = 1;
			action_count++;
			break;
                case OPT_BIND_TO_AID:
			opt_bind_to_aid = optarg;
			break;
		case OPT_READER:
			opt_reader = optarg;
			break;
		case 'v':
			verbose++;
			break;
		}
	}
	if (action_count == 0)
		util_print_usage_and_die(app_name, options, option_help, NULL);

	memset(&ctx_param, 0, sizeof(sc_context_param_t));
	ctx_param.app_name = app_name;

	r = sc_context_create(&ctx, &ctx_param);
	if (r != SC_SUCCESS) {
		fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r));
		return 1;
	}

	/* Only change if not in opensc.conf */
	if (verbose > 1 && ctx->debug == 0) {
		ctx->debug = verbose;
		sc_ctx_log_to_file(ctx, "stderr");
	}

	if (action_count <= 0)
		goto end;

	err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
	if (err)
		goto end;

        if (opt_bind_to_aid)   {
		struct sc_aid aid;

		aid.len = sizeof(aid.value);
		if (sc_hex_to_bin(opt_bind_to_aid, aid.value, &aid.len))   {
			fprintf(stderr, "Invalid AID value: '%s'\n", opt_bind_to_aid);
			return 1;
		}

		r = sc_pkcs15_bind(card, &aid, &p15card);
	}
	else   if (!do_list_sdos) {
		r = sc_pkcs15_bind(card, NULL, &p15card);
	}

	if (do_list_sdos) {
		if ((err = list_sdos(opt_sdo_tag)))
			goto end;
		action_count--;
	}
	if (do_list_apps) {
		if ((err = list_apps(stdout)))
			goto end;
		action_count--;
	}
end:
	if (p15card)
		sc_pkcs15_unbind(p15card);

	if (card) {
		sc_unlock(card);
		sc_disconnect_card(card);
	}
	if (ctx)
		sc_release_context(ctx);

	return err;
}
Esempio n. 19
0
static int do_unblock(int argc, char **argv)
{
	int ref, r;
	u8 puk_buf[30], *puk = NULL;
	u8 newpin_buf[30], *newpin = NULL;
	const char *s;
	size_t puklen = sizeof(puk_buf), i;
	size_t newpinlen = sizeof(newpin_buf);
	
	if (argc < 1 || argc > 3)
		goto usage;
	if (strncasecmp(argv[0], "CHV", 3)) {
		printf("Invalid type.\n");
		goto usage;
	}
	if (sscanf(argv[0] + 3, "%d", &ref) != 1) {
		printf("Invalid key reference.\n");
		goto usage;
	}
	argc--;
	argv++;

	if (argc == 0) {
		puklen = 0;
		puk = NULL;
	} else {
		if (argv[0][0] == '"') {
			for (s = argv[0] + 1, i = 0;
			     i < sizeof(puk_buf) && *s && *s != '"'; i++) 
				puk_buf[i] = *s++;
			puklen = i;
		} else if (sc_hex_to_bin(argv[0], puk_buf, &puklen) != 0) {
			printf("Invalid key value.\n");
			goto usage;
		}
		puk = &puk_buf[0];

		argc--;
		argv++;
	}

	if (argc)   {
		if (argv[0][0] == '"') {
			for (s = argv[0] + 1, i = 0;
			     i < sizeof(newpin_buf) && *s && *s != '"'; i++) 
				newpin_buf[i] = *s++;
			newpinlen = i;
		} else if (sc_hex_to_bin(argv[0], newpin_buf, &newpinlen) != 0) {
			printf("Invalid key value.\n");
			goto usage;
		}

		newpin = &newpin_buf[0];
	}
	else   {
		newpinlen = 0;
		newpin = NULL;
	}

	r = sc_reset_retry_counter (card, SC_AC_CHV, ref,
                                      puk, puklen,
                                      newpin, newpinlen);
	if (r) {
		if (r == SC_ERROR_PIN_CODE_INCORRECT)
			printf("Incorrect code.\n");
		printf("Unable to unblock PIN code: %s\n", sc_strerror(r));
		return -1;
	}
	printf("PIN unblocked.\n");
	return 0;
usage:
	printf("Usage: unblock CHV<pin ref> [<puk>] [<new pin>]\n");
	printf("PUK and PIN values can be hexadecimal, ASCII, empty (\"\") or absent\n");
	printf("Examples:\n");
	printf("\tUnblock PIN and set a new value:   unblock CHV2 00:00:00:00:00:00 \"foobar\"\n");
	printf("\tUnblock PIN keeping the old value: unblock CHV2 00:00:00:00:00:00 \"\"\n");
	printf("\tSet new PIN value:                 unblock CHV2 \"\" \"foobar\"\n");
	printf("Examples with pinpad:\n");
	printf("\tUnblock PIN: new PIN value is prompted by pinpad:                   unblock CHV2 00:00:00:00:00:00\n");
	printf("\tSet PIN: new PIN value is prompted by pinpad:                       unblock CHV2 \"\"\n");
	printf("\tUnblock PIN: unblock code and new PIN value are prompted by pinpad: unblock CHV2\n");
	return -1;
}
Esempio n. 20
0
static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_password_shares) {

	int r, i;
	BIGNUM prime;
	BIGNUM secret;
	BIGNUM *p;
	char inbuf[64];
	char bin[64];
	int binlen = 0;
	char *ip;
	secret_share_t *shares = NULL;
	secret_share_t *sp;

	/*
	 * Initialize prime and secret
	 */
	BN_init(&prime);
	BN_init(&secret);

	// Allocate data buffer for the shares
	shares = malloc(num_of_password_shares * sizeof(secret_share_t));

	printf("\nDeciphering the DKEK for import into the SmartCard-HSM requires %i key custodians", num_of_password_shares);
	printf("\nto present their share. Only the first key custodian needs to enter the public prime.");
	printf("\nPlease remember to present the share id as well as the share value.");
	printf("\n\nPlease enter prime: ");
	memset(inbuf, 0, sizeof(inbuf));
	fgets(inbuf, sizeof(inbuf), stdin);
	binlen = 64;
	sc_hex_to_bin(inbuf, bin, &binlen);
	BN_bin2bn(bin, binlen, &prime);

	sp = shares;
	for (i = 0; i < num_of_password_shares; i++) {
		clearScreen();

		printf("Press <enter> to enter share %i of %i\n\n", i + 1, num_of_password_shares);
		waitForEnterKeyPressed();

		clearScreen();

		BN_init(&(sp->x));
		BN_init(&(sp->y));

		printf("Share %i of %i\n\n", i + 1, num_of_password_shares);

		printf("Please enter share ID: ");
		memset(inbuf, 0, sizeof(inbuf));
		fgets(inbuf, sizeof(inbuf), stdin);
		p = &(sp->x);
		BN_hex2bn(&p, inbuf);

		printf("Please enter share value: ");
		memset(inbuf, 0, sizeof(inbuf));
		fgets(inbuf, sizeof(inbuf), stdin);
		binlen = 64;
		sc_hex_to_bin(inbuf, bin, &binlen);
		BN_bin2bn(bin, binlen, &(sp->y));

		sp++;
	}

	clearScreen();

	r = reconstructSecret(shares, num_of_password_shares, prime, &secret);

	if (r < 0) {
		printf("\nError during reconstruction of secret. Wrong shares?\n");
		return r;
	}

	/*
	 * Encode the secret value
	 */
	ip = inbuf;
	*pwdlen = BN_bn2bin(&secret, ip);
	*pwd = calloc(1, *pwdlen);
	memcpy(*pwd, ip, *pwdlen);

	cleanUpShares(shares, num_of_password_shares);

	BN_clear_free(&prime);
	BN_clear_free(&secret);

	return 0;
}
Esempio n. 21
0
static int
sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info)
{
	struct sm_cwa_session *cwa_session = &sm_info->session.cwa;
	struct sm_cwa_keyset *cwa_keyset = &sm_info->session.cwa.cwa_keyset;
	scconf_block *sm_conf_block = NULL, **blocks;
	struct sc_crt *crt_at = &sm_info->session.cwa.params.crt_at;
	const char *value = NULL;
	char name[128];
	unsigned char hex[48];
	size_t hex_len = sizeof(hex);
	int rv, ii, ref = crt_at->refs[0] & IASECC_OBJECT_REF_MAX;

	for (ii = 0; ctx->conf_blocks[ii]; ii++) {
		blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[ii], "secure_messaging", sm_info->config_section);
		if (blocks) {
			sm_conf_block = blocks[0];
			free(blocks);
		}

		if (sm_conf_block)
			break;
	}

	sc_log(ctx, "CRT(algo:%X,ref:%X)", crt_at->algo, crt_at->refs[0]);
	/* Keyset ENC */
	if (sm_info->current_aid.len && (crt_at->refs[0] & IASECC_OBJECT_REF_LOCAL))
		snprintf(name, sizeof(name), "keyset_%s_%02i_enc",
				sc_dump_hex(sm_info->current_aid.value, sm_info->current_aid.len), ref);
	else
		snprintf(name, sizeof(name), "keyset_%02i_enc", ref);
	value = scconf_get_str(sm_conf_block, name, NULL);
	if (!value)   {
		sc_log(ctx, "No %s value in OpenSC config", name);
		return SC_ERROR_SM_KEYSET_NOT_FOUND;
	}

	sc_log(ctx, "keyset::enc(%i) %s", strlen(value), value);
	if (strlen(value) == 16)   {
		memcpy(cwa_keyset->enc, value, 16);
	}
	else   {
		hex_len = sizeof(hex);
		rv = sc_hex_to_bin(value, hex, &hex_len);
		if (rv)   {
			sc_log(ctx, "SM get %s: hex to bin failed for '%s'; error %i", name, value, rv);
			return SC_ERROR_UNKNOWN_DATA_RECEIVED;
		}

		sc_log(ctx, "ENC(%i) %s", hex_len, sc_dump_hex(hex, hex_len));
		if (hex_len != 16)
			return SC_ERROR_INVALID_DATA;

		memcpy(cwa_keyset->enc, hex, hex_len);
	}
	sc_log(ctx, "%s %s", name, sc_dump_hex(cwa_keyset->enc, 16));

	/* Keyset MAC */
	if (sm_info->current_aid.len && (crt_at->refs[0] & IASECC_OBJECT_REF_LOCAL))
		snprintf(name, sizeof(name), "keyset_%s_%02i_mac",
				sc_dump_hex(sm_info->current_aid.value, sm_info->current_aid.len), ref);
	else
		snprintf(name, sizeof(name), "keyset_%02i_mac", ref);
	value = scconf_get_str(sm_conf_block, name, NULL);
	if (!value)   {
		sc_log(ctx, "No %s value in OpenSC config", name);
		return SC_ERROR_SM_KEYSET_NOT_FOUND;
	}

	sc_log(ctx, "keyset::mac(%i) %s", strlen(value), value);
	if (strlen(value) == 16)   {
		memcpy(cwa_keyset->mac, value, 16);
	}
	else   {
		hex_len = sizeof(hex);
		rv = sc_hex_to_bin(value, hex, &hex_len);
		if (rv)   {
			sc_log(ctx, "SM get '%s': hex to bin failed for '%s'; error %i", name, value, rv);
			return SC_ERROR_UNKNOWN_DATA_RECEIVED;
		}

		sc_log(ctx, "MAC(%i) %s", hex_len, sc_dump_hex(hex, hex_len));
		if (hex_len != 16)
			return SC_ERROR_INVALID_DATA;

		memcpy(cwa_keyset->mac, hex, hex_len);
	}
	sc_log(ctx, "%s %s", name, sc_dump_hex(cwa_keyset->mac, 16));

	cwa_keyset->sdo_reference = crt_at->refs[0];


	/* IFD parameters */
	//memset(cwa_session, 0, sizeof(struct sm_cwa_session));
	value = scconf_get_str(sm_conf_block, "ifd_serial", NULL);
	if (!value)
		return SC_ERROR_SM_IFD_DATA_MISSING;
	hex_len = sizeof(hex);
	rv = sc_hex_to_bin(value, hex, &hex_len);
	if (rv)   {
		sc_log(ctx, "SM get 'ifd_serial': hex to bin failed for '%s'; error %i", value, rv);
		return SC_ERROR_UNKNOWN_DATA_RECEIVED;
	}

	if (hex_len != sizeof(cwa_session->ifd.sn))   {
		sc_log(ctx, "SM get 'ifd_serial': invalid IFD serial length: %i", hex_len);
		return SC_ERROR_UNKNOWN_DATA_RECEIVED;
	}

	memcpy(cwa_session->ifd.sn, hex, hex_len);

        rv = RAND_bytes(cwa_session->ifd.rnd, 8);
        if (!rv)   {
		sc_log(ctx, "Generate random error: %i", rv);
		return SC_ERROR_SM_RAND_FAILED;
	}

        rv = RAND_bytes(cwa_session->ifd.k, 32);
        if (!rv)   {
		sc_log(ctx, "Generate random error: %i", rv);
		return SC_ERROR_SM_RAND_FAILED;
	}
	sc_log(ctx, "IFD.Serial: %s", sc_dump_hex(cwa_session->ifd.sn, sizeof(cwa_session->ifd.sn)));
	sc_log(ctx, "IFD.Rnd: %s", sc_dump_hex(cwa_session->ifd.rnd, sizeof(cwa_session->ifd.rnd)));
	sc_log(ctx, "IFD.K: %s", sc_dump_hex(cwa_session->ifd.k, sizeof(cwa_session->ifd.k)));

	return SC_SUCCESS;
}
Esempio n. 22
0
static int changeAdminKey(sc_card_t* card, const char *so_pin, const char* new_key) {
	char *_so_pin = NULL, *_new_key = NULL;
	size_t len;
	u8 key[24];
	int r;

	if (so_pin == NULL) {
		printf("============================================================\n");
		printf("WARNING\n");
		printf("Entering an incorrect admin key can break your card\n");
		printf("WARNING\n");
		printf("============================================================\n");
		printf("Enter admin key (48 hexadecimal characters) : ");
		util_getpass(&_so_pin, NULL, stdin);
		printf("\n");
	} else {
		_so_pin = (char *)so_pin;
	}

	len = sizeof(key);
	r = sc_hex_to_bin(_so_pin, key, &len);
	if (r < 0) {
		fprintf(stderr, "Error decoding initialization code (%s)\n", sc_strerror(r));
		return -1;
	}

	if (len != 24) {
		fprintf(stderr, "admin key must be a hexadecimal string of 48 characters\n");
		return -1;
	}

	r = sc_card_ctl(card, SC_CARDCTL_GIDS_AUTHENTICATE_ADMIN, (void *)key);
	if (r < 0) {
		fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_GIDS_AUTHENTICATE_ADMIN, *) failed with %s\n", sc_strerror(r));
		return -1;
	}

	if (new_key == NULL) {
		printf("Enter new admin key (48 hexadecimal characters) : ");
		util_getpass(&_so_pin, NULL, stdin);
		printf("\n");
	} else {
		_new_key = (char *)new_key;
	}

	len = sizeof(key);
	r = sc_hex_to_bin(_new_key, key, &len);
	if (r < 0) {
		fprintf(stderr, "Error decoding initialization code (%s)\n", sc_strerror(r));
		return -1;
	}

	if (len != 24) {
		fprintf(stderr, "admin key must be a hexadecimal string of 48 characters\n");
		return -1;
	}

	r = sc_card_ctl(card, SC_CARDCTL_GIDS_SET_ADMIN_KEY, (void *)key);
	sc_logout(card);
	if (r < 0) {
		fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_GIDS_SET_ADMIN_KEY, *) failed with %s\n", sc_strerror(r));
		return -1;
	}
	return 0;
}
Esempio n. 23
0
int
sm_gp_decode_card_answer(struct sc_context *ctx, struct sc_remote_data *rdata, unsigned char *out, size_t out_len)
{
#if 0
	struct sc_asn1_entry asn1_authentic_card_response[4], asn1_card_response[2];
	struct sc_hash *hash = NULL;
	unsigned char *hex = NULL;
	size_t hex_len;
	int rv, offs;
	unsigned char card_data[SC_MAX_APDU_BUFFER_SIZE];
	size_t card_data_len = sizeof(card_data), len_left = 0;

	LOG_FUNC_CALLED(ctx);

	if (!out || !out_len)
		LOG_FUNC_RETURN(ctx, 0);
	if (strstr(str_data, "DATA="))   {
		rv = sc_hash_parse(ctx, str_data, strlen(str_data), &hash);
		LOG_TEST_RET(ctx, rv, "SM GP decode card answer: parse input data error");

		str_data = sc_hash_get(hash, "DATA");
	}

	if (!strlen(str_data))
		LOG_FUNC_RETURN(ctx, 0);

	hex_len = strlen(str_data) / 2;
	hex = calloc(1, hex_len);
	if (!hex)
		LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "SM GP decode card answer: hex allocate error");

	sc_log(ctx, "SM GP decode card answer: hex length %i", hex_len);
	rv = sc_hex_to_bin(str_data, hex, &hex_len);
	LOG_TEST_RET(ctx, rv, "SM GP decode card answer: data 'HEX to BIN' conversion error");
	sc_log(ctx, "SM GP decode card answer: hex length %i", hex_len);

	if (hash)
		sc_hash_free(hash);

	for (offs = 0, len_left = hex_len; len_left; )   {
		int num, status;

		sc_copy_asn1_entry(c_asn1_authentic_card_response, asn1_authentic_card_response);
		sc_copy_asn1_entry(c_asn1_card_response, asn1_card_response);
		sc_format_asn1_entry(asn1_authentic_card_response + 0, &num, NULL, 0);
		sc_format_asn1_entry(asn1_authentic_card_response + 1, &status, NULL, 0);
		card_data_len = sizeof(card_data);
		sc_format_asn1_entry(asn1_authentic_card_response + 2, &card_data, &card_data_len, 0);
		sc_format_asn1_entry(asn1_card_response + 0, asn1_authentic_card_response, NULL, 0);

		rv = sc_asn1_decode(ctx, asn1_card_response, hex + hex_len - len_left, len_left, NULL, &len_left);
		if (rv) {
			sc_log(ctx, "SM GP decode card answer: ASN.1 parse error: %s", sc_strerror(rv));
			return rv;
		}
		if (status != 0x9000)
			continue;

		if (asn1_authentic_card_response[2].flags & SC_ASN1_PRESENT)   {
			sc_log(ctx, "SM GP decode card answer: card_data_len %i", card_data_len);
			if (out_len < offs + card_data_len)
				LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "SM GP decode card answer: buffer too small");

			memcpy(out + offs, card_data, card_data_len);
			offs += card_data_len;
		}

		sc_log(ctx, "SM GP decode card answer: offs:%i,left:%i", offs, len_left);
	}

	free(hex);
	LOG_FUNC_RETURN(ctx, offs);
#else
	LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
#endif
}
Esempio n. 24
0
static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_password_shares)
{
	int r, i;
	BIGNUM *prime;
	BIGNUM *secret;
	BIGNUM *p;
	char inbuf[64];
	unsigned char bin[64];
	size_t binlen = 0;
	unsigned char *ip;
	secret_share_t *shares = NULL;
	secret_share_t *sp;

	if (num_of_password_shares < 2) {
		fprintf(stderr, "--pwd-shares-total must 2 or larger\n");
		return -1;
	}

	// Allocate data buffer for the shares
	shares = malloc(num_of_password_shares * sizeof(secret_share_t));
	if (!shares)
		return -1;

	/*
	 * Initialize prime and secret
	 */
	prime = BN_new();
	secret = BN_new();

	printf("\nDeciphering the DKEK for import into the SmartCard-HSM requires %i key custodians", num_of_password_shares);
	printf("\nto present their share. Only the first key custodian needs to enter the public prime.");
	printf("\nPlease remember to present the share id as well as the share value.");
	printf("\n\nPlease enter prime: ");
	memset(inbuf, 0, sizeof(inbuf));
	if (fgets(inbuf, sizeof(inbuf), stdin) == NULL) {
		fprintf(stderr, "Input aborted\n");
		free(shares);
		return -1;
	}
	binlen = 64;
	sc_hex_to_bin(inbuf, bin, &binlen);
	BN_bin2bn(bin, binlen, prime);

	sp = shares;
	for (i = 0; i < num_of_password_shares; i++) {
		clearScreen();

		printf("Press <enter> to enter share %i of %i\n\n", i + 1, num_of_password_shares);
		waitForEnterKeyPressed();

		clearScreen();

		sp->x = BN_new();
		sp->y = BN_new();

		printf("Share %i of %i\n\n", i + 1, num_of_password_shares);

		printf("Please enter share ID: ");
		memset(inbuf, 0, sizeof(inbuf));
		if (fgets(inbuf, sizeof(inbuf), stdin) == NULL) {
			fprintf(stderr, "Input aborted\n");
			free(shares);
			return -1;
		}
		p = (sp->x);
		BN_hex2bn(&p, inbuf);

		printf("Please enter share value: ");
		memset(inbuf, 0, sizeof(inbuf));
		if (fgets(inbuf, sizeof(inbuf), stdin) == NULL) {
			fprintf(stderr, "Input aborted\n");
			free(shares);
			return -1;
		}
		binlen = 64;
		sc_hex_to_bin(inbuf, bin, &binlen);
		BN_bin2bn(bin, binlen, (sp->y));

		sp++;
	}

	clearScreen();

	r = reconstructSecret(shares, num_of_password_shares, prime, secret);

	if (r < 0) {
		printf("\nError during reconstruction of secret. Wrong shares?\n");
		cleanUpShares(shares, num_of_password_shares);
		return r;
	}

	/*
	 * Encode the secret value
	 */
	ip = (unsigned char *) inbuf;
	*pwdlen = BN_bn2bin(secret, ip);
	*pwd = calloc(1, *pwdlen);
	if (*pwd) {
		memcpy(*pwd, ip, *pwdlen);
	}

	cleanUpShares(shares, num_of_password_shares);

	BN_clear_free(prime);
	BN_clear_free(secret);

	return *pwd ? 0 : -1;
}
Esempio n. 25
0
static int match_atr_table(sc_context_t *ctx, const struct sc_atr_table *table, struct sc_atr *atr)
{
	u8 *card_atr_bin;
	size_t card_atr_bin_len;
	char card_atr_hex[3 * SC_MAX_ATR_SIZE];
	size_t card_atr_hex_len;
	unsigned int i = 0;

	if (ctx == NULL || table == NULL || atr == NULL)
		return -1;
	card_atr_bin = atr->value;
	card_atr_bin_len = atr->len;
	sc_bin_to_hex(card_atr_bin, card_atr_bin_len, card_atr_hex, sizeof(card_atr_hex), ':');
	card_atr_hex_len = strlen(card_atr_hex);

	sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ATR     : %s", card_atr_hex);

	for (i = 0; table[i].atr != NULL; i++) {
		const char *tatr = table[i].atr;
		const char *matr = table[i].atrmask;
		size_t tatr_len = strlen(tatr);
		u8 mbin[SC_MAX_ATR_SIZE], tbin[SC_MAX_ATR_SIZE];
		size_t mbin_len, tbin_len, s, matr_len;
		size_t fix_hex_len = card_atr_hex_len;
		size_t fix_bin_len = card_atr_bin_len;

		sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ATR try : %s", tatr);

		if (tatr_len != fix_hex_len) {
			sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ignored - wrong length");
			continue;
		}
		if (matr != NULL) {
			sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ATR mask: %s", matr);

			matr_len = strlen(matr);
			if (tatr_len != matr_len)
				continue;
			tbin_len = sizeof(tbin);
			sc_hex_to_bin(tatr, tbin, &tbin_len);
			mbin_len = sizeof(mbin);
			sc_hex_to_bin(matr, mbin, &mbin_len);
			if (mbin_len != fix_bin_len) {
				sc_debug(ctx, SC_LOG_DEBUG_MATCH, "length of atr and atr mask do not match - ignored: %s - %s", tatr, matr);
				continue;
			}
			for (s = 0; s < tbin_len; s++) {
				/* reduce tatr with mask */
				tbin[s] = (tbin[s] & mbin[s]);
				/* create copy of card_atr_bin masked) */
				mbin[s] = (card_atr_bin[s] & mbin[s]);
			}
			if (memcmp(tbin, mbin, tbin_len) != 0)
				continue;
		} else {
			if (strncasecmp(tatr, card_atr_hex, tatr_len) != 0)
				continue;
		}
		return i;
	}
	return -1;
}
Esempio n. 26
0
static int do_change(int argc, char **argv)
{
	int ref, r, tries_left = -1;
	u8 oldpin[30];
	u8 newpin[30];
	const char *s;
	size_t oldpinlen = sizeof(oldpin), i;
	size_t newpinlen = sizeof(newpin);
	
	if (argc < 1 || argc > 3)
		goto usage;
	if (strncasecmp(argv[0], "CHV", 3)) {
		printf("Invalid type.\n");
		goto usage;
	}
	if (sscanf(argv[0] + 3, "%d", &ref) != 1) {
		printf("Invalid key reference.\n");
		goto usage;
	}
	argc--;
	argv++;

	if (argc == 0) {
		/* set without verification */
		oldpinlen = 0;
		newpinlen = 0;
	} else if (argc == 1) {
		/* set without verification */
		oldpinlen = 0;
	} else {
		if (argv[0][0] == '"') {
			for (s = argv[0] + 1, i = 0;
			     i < sizeof(oldpin) && *s && *s != '"'; i++) 
				oldpin[i] = *s++;
			oldpinlen = i;
		} else if (sc_hex_to_bin(argv[0], oldpin, &oldpinlen) != 0) {
			printf("Invalid key value.\n");
			goto usage;
		}
		argc--;
		argv++;
	}

	if (argc)   {
		if (argv[0][0] == '"') {
			for (s = argv[0] + 1, i = 0;
			     i < sizeof(newpin) && *s && *s != '"'; i++) 
				newpin[i] = *s++;
			newpinlen = i;
		} else if (sc_hex_to_bin(argv[0], newpin, &newpinlen) != 0) {
			printf("Invalid key value.\n");
			goto usage;
		}
	}

	r = sc_change_reference_data (card, SC_AC_CHV, ref,
                                      oldpinlen ? oldpin : NULL, oldpinlen,
                                      newpinlen ? newpin : NULL, newpinlen,
                                      &tries_left);
	if (r) {
		if (r == SC_ERROR_PIN_CODE_INCORRECT) {
			if (tries_left >= 0) 
				printf("Incorrect code, %d tries left.\n", tries_left);
			else
				printf("Incorrect code.\n");
		}
		printf("Unable to change PIN code: %s\n", sc_strerror(r));
		return -1;
	}
	printf("PIN changed.\n");
	return 0;
usage:
	printf("Usage: change CHV<pin ref> [[<old pin>] <new pin>]\n");
	printf("Examples: \n");
	printf("\tChange PIN: change CHV2 00:00:00:00:00:00 \"foobar\"\n");
	printf("\tSet PIN: change CHV2 \"foobar\"\n");
	printf("\tChange PIN with pinpad': change CHV2\n");
	return -1;
}
Esempio n. 27
0
int main(/*@unused@*/ int argc, /*@unused@*/ char **argv)
{
	SCARDHANDLE hCard;
	SCARDCONTEXT hContext;
	SCARD_READERSTATE_A rgReaderStates[1];
	DWORD dwReaderLen, dwState, dwProt, dwAtrLen;
	DWORD dwPref, dwReaders = 0;
	char *pcReaders = NULL, *mszReaders;
#ifdef USE_AUTOALLOCATE
	unsigned char *pbAtr = NULL;
#else
	unsigned char pbAtr[MAX_ATR_SIZE];
#endif
	union {
		unsigned char as_char[100];
		DWORD as_DWORD;
		uint32_t as_uint32_t;
	} buf;
	DWORD dwBufLen;
	unsigned char *pbAttr = NULL;
	DWORD pcbAttrLen;
	char *mszGroups;
	DWORD dwGroups = 0;
	long rv;
	DWORD i;
	int p, iReader;
	int iList[16];
	SCARD_IO_REQUEST pioRecvPci;
	SCARD_IO_REQUEST pioSendPci;
	unsigned char bSendBuffer[MAX_BUFFER_SIZE];
	unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
	DWORD send_length, length;

	(void)argc;
	(void)argv;

	printf("\nMUSCLE PC/SC Lite unitary test Program\n\n");

	printf(MAGENTA "THIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL FOR END USERS!\n");
	printf("Do NOT use it unless you really know what you do.\n\n" NORMAL);

	printf("Testing SCardEstablishContext\t: ");
	rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardIsValidContext\t: ");
	rv = SCardIsValidContext(hContext);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardIsValidContext\t: ");
	rv = SCardIsValidContext(hContext+1);
	test_rv(rv, hContext, DONT_PANIC);

	printf("Testing SCardListReaderGroups\t: ");
#ifdef USE_AUTOALLOCATE
	dwGroups = SCARD_AUTOALLOCATE;
	rv = SCardListReaderGroups(hContext, (LPSTR)&mszGroups, &dwGroups);
#else
	rv = SCardListReaderGroups(hContext, NULL, &dwGroups);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardListReaderGroups\t: ");
	mszGroups = calloc(dwGroups, sizeof(char));
	rv = SCardListReaderGroups(hContext, mszGroups, &dwGroups);
#endif
	test_rv(rv, hContext, PANIC);

	/*
	 * Have to understand the multi-string here
	 */
	p = 0;
	for (i = 0; i+1 < dwGroups; i++)
	{
		++p;
		printf(GREEN "Group %02d: %s\n" NORMAL, p, &mszGroups[i]);
		while (mszGroups[++i] != 0) ;
	}

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, mszGroups);
	test_rv(rv, hContext, PANIC);
#else
	free(mszGroups);
#endif

wait_for_card_again:
	mszGroups = NULL;
	printf("Testing SCardListReaders\t: ");
	rv = SCardListReaders(hContext, mszGroups, NULL, &dwReaders);
	test_rv(rv, hContext, DONT_PANIC);
	if (SCARD_E_NO_READERS_AVAILABLE == rv)
	{
		printf("Testing SCardGetStatusChange \n");
		printf("Please insert a working reader\t: ");
		(void)fflush(stdout);
		rgReaderStates[0].szReader = "\\\\?PnP?\\Notification";
		rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY;

		rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1);
		test_rv(rv, hContext, PANIC);
	}

	printf("Testing SCardListReaders\t: ");
#ifdef USE_AUTOALLOCATE
	dwReaders = SCARD_AUTOALLOCATE;
	rv = SCardListReaders(hContext, mszGroups, (LPSTR)&mszReaders, &dwReaders);
#else
	rv = SCardListReaders(hContext, mszGroups, NULL, &dwReaders);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardListReaders\t: ");
	mszReaders = calloc(dwReaders, sizeof(char));
	rv = SCardListReaders(hContext, mszGroups, mszReaders, &dwReaders);
#endif
	test_rv(rv, hContext, DONT_PANIC);

	/*
	 * Have to understand the multi-string here
	 */
	p = 0;
	for (i = 0; i+1 < dwReaders; i++)
	{
		++p;
		printf(GREEN "Reader %02d: %s\n" NORMAL, p, &mszReaders[i]);
		iList[p] = i;
		while (mszReaders[++i] != 0) ;
	}

	if (p > 1)
		do
		{
			char input[80];

			printf("Enter the reader number\t\t: ");
			(void)fgets(input, sizeof(input), stdin);
			(void)sscanf(input, "%d", &iReader);

			if (iReader > p || iReader <= 0)
				printf("Invalid Value - try again\n");
		}
		while (iReader > p || iReader <= 0);
	else
		iReader = 1;

	rgReaderStates[0].szReader = &mszReaders[iList[iReader]];
	rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY;

	printf("Waiting for card insertion\t: ");
	(void)fflush(stdout);
	rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1);
	test_rv(rv, hContext, PANIC);
	if (rgReaderStates[0].dwEventState & SCARD_STATE_UNKNOWN)
	{
		printf("\nA reader has been connected/disconnected\n");
		goto wait_for_card_again;
	}

	printf("Testing SCardConnect\t\t: ");
	rv = SCardConnect(hContext, &mszReaders[iList[iReader]],
		SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
		&hCard, &dwPref);
	test_rv(rv, hContext, PANIC);

	switch(dwPref)
	{
		case SCARD_PROTOCOL_T0:
			pioSendPci = *SCARD_PCI_T0;
			break;
		case SCARD_PROTOCOL_T1:
			pioSendPci = *SCARD_PCI_T1;
			break;
		case SCARD_PROTOCOL_RAW:
			pioSendPci = *SCARD_PCI_RAW;
			break;
		default:
			printf("Unknown protocol\n");
			return -1;
	}

	int bBreak = 0;

	while (1)
	{
		char inputCommand[1024];	
		char inputAPDU[1024];
		int inputAPDULen = sizeof(inputAPDU);
		printf("Enter APDU to send, (e.g. 00:A4:04:00:00)\n");
		printf("Command APDU: ");
		(void)fgets(inputCommand, sizeof(inputCommand), stdin);
		
		int stringlen = strlen(inputCommand);
		if( inputCommand[stringlen-1] == '\n' ) { inputCommand[stringlen-1] = 0; } //remove newline

		int bError = sc_hex_to_bin(inputCommand, inputAPDU, &inputAPDULen);
		//printf("debug - value bError: %i\n",bError);
		if (bError) { printf("Error parsing input\n\n"); continue; }

		send_length = inputAPDULen;
		if (inputAPDULen == 0) { break; }
		printf("debug inputAPDULen: %i\n",inputAPDULen); 
		memcpy(bSendBuffer, inputAPDU, send_length);
		length = sizeof(bRecvBuffer);

		printf("Testing SCardTransmit:\n "); printf("-> ");
		for (i=0; i<send_length; i++) { printf(" %02X", bSendBuffer[i]); }
		printf("\n");
		rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
			&pioRecvPci, bRecvBuffer, &length);
		test_rv(rv, hContext, PANIC);
		printf("<- " GREEN);
		for (i=0; i<length; i++)
			printf(" %02X", bRecvBuffer[i]);
		printf("\n" NORMAL);
	}

	testrun(&hCard, &hContext, &pioSendPci, 0);
	testrun(&hCard, &hContext, &pioSendPci, 1);
	testrun(&hCard, &hContext, &pioSendPci, 2);
	testrun(&hCard, &hContext, &pioSendPci, 3);

	printf("Testing SCardControl\t\t: ");
#ifdef PCSC_PRE_120
	{
		char buffer[1024] = "Foobar";
		DWORD cbRecvLength = sizeof(buffer);

		rv = SCardControl(hCard, buffer, 7, buffer, &cbRecvLength);
	}
#else
	{
		char buffer[1024] = { 0x02 };
		DWORD cbRecvLength = sizeof(buffer);

		rv = SCardControl(hCard, SCARD_CTL_CODE(1), buffer, 1, buffer,
			sizeof(buffer), &cbRecvLength);
		if (cbRecvLength && (SCARD_S_SUCCESS == rv))
		{
			for (i=0; i<cbRecvLength; i++)
				printf("%c", buffer[i]);
			printf(" ");
		}
	}
#endif
	test_rv(rv, hContext, DONT_PANIC);

	printf("Testing SCardGetAttrib\t\t: ");
#ifdef USE_AUTOALLOCATE
	pcbAttrLen = SCARD_AUTOALLOCATE;
	rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, (unsigned char *)&pbAttr,
		&pcbAttrLen);
#else
	rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, NULL, &pcbAttrLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
	{
		printf("SCARD_ATTR_DEVICE_FRIENDLY_NAME length: " GREEN "%ld\n" NORMAL, pcbAttrLen);
		pbAttr = malloc(pcbAttrLen);
	}

	printf("Testing SCardGetAttrib\t\t: ");
	rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, pbAttr, &pcbAttrLen);
#endif
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
		printf("SCARD_ATTR_DEVICE_FRIENDLY_NAME: " GREEN "%s\n" NORMAL, pbAttr);

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, pbAttr);
	test_rv(rv, hContext, PANIC);
#else
	if (pbAttr)
		free(pbAttr);
#endif

	printf("Testing SCardGetAttrib\t\t: ");
#ifdef USE_AUTOALLOCATE
	pcbAttrLen = SCARD_AUTOALLOCATE;
	rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, (unsigned char *)&pbAttr,
		&pcbAttrLen);
#else
	rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, NULL, &pcbAttrLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
	{
		printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen);
		pbAttr = malloc(pcbAttrLen);
	}

	printf("Testing SCardGetAttrib\t\t: ");
	rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, pbAttr, &pcbAttrLen);
#endif
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
	{
		printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen);
		printf("SCARD_ATTR_ATR_STRING: " GREEN);
		for (i = 0; i < pcbAttrLen; i++)
			printf("%02X ", pbAttr[i]);
		printf("\n" NORMAL);
	}

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, pbAttr);
	test_rv(rv, hContext, PANIC);
#else
	if (pbAttr)
		free(pbAttr);
#endif

	printf("Testing SCardGetAttrib\t\t: ");
	dwBufLen = sizeof(buf);
	rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_IFD_VERSION, buf.as_char, &dwBufLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
		printf("Vendor IFD version\t\t: " GREEN "0x%08lX\n" NORMAL,
			buf.as_DWORD);

	printf("Testing SCardGetAttrib\t\t: ");
	dwBufLen = sizeof(buf);
	rv = SCardGetAttrib(hCard, SCARD_ATTR_MAXINPUT, buf.as_char, &dwBufLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
	{
		if (dwBufLen == sizeof(uint32_t))
			printf("Max message length\t\t: " GREEN "%d\n" NORMAL,
				buf.as_uint32_t);
		else
			printf(RED "Wrong size" NORMAL);
	}

	printf("Testing SCardGetAttrib\t\t: ");
	dwBufLen = sizeof(buf);
	rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_NAME, buf.as_char, &dwBufLen);
	test_rv(rv, hContext, DONT_PANIC);
	if (rv == SCARD_S_SUCCESS)
		printf("Vendor name\t\t\t: " GREEN "%s\n" NORMAL, buf.as_char);

	printf("Testing SCardSetAttrib\t\t: ");
	rv = SCardSetAttrib(hCard, SCARD_ATTR_ATR_STRING, (LPCBYTE)"", 1);
	test_rv(rv, hContext, DONT_PANIC);

	printf("Testing SCardStatus\t\t: ");

#ifdef USE_AUTOALLOCATE
	dwReaderLen = SCARD_AUTOALLOCATE;
	dwAtrLen = SCARD_AUTOALLOCATE;
	rv = SCardStatus(hCard, (LPSTR)&pcReaders, &dwReaderLen, &dwState, &dwProt,
		(LPBYTE)&pbAtr, &dwAtrLen);
#else
	dwReaderLen = 100;
	pcReaders   = malloc(sizeof(char) * 100);
	dwAtrLen    = MAX_ATR_SIZE;

	rv = SCardStatus(hCard, pcReaders, &dwReaderLen, &dwState, &dwProt,
		pbAtr, &dwAtrLen);
#endif
	test_rv(rv, hContext, PANIC);

	printf("Current Reader Name\t\t: " GREEN "%s\n" NORMAL, pcReaders);
	printf("Current Reader State\t\t: " GREEN "0x%.4lx\n" NORMAL, dwState);
	printf("Current Reader Protocol\t\t: T=" GREEN "%ld\n" NORMAL, dwProt - 1);
	printf("Current Reader ATR Size\t\t: " GREEN "%ld" NORMAL " bytes\n",
		dwAtrLen);
	printf("Current Reader ATR Value\t: " GREEN);

	for (i = 0; i < dwAtrLen; i++)
	{
		printf("%02X ", pbAtr[i]);
	}
	printf(NORMAL "\n");

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, pcReaders);
	test_rv(rv, hContext, PANIC);
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, pbAtr);
	test_rv(rv, hContext, PANIC);
#else
	if (pcReaders)
		free(pcReaders);
#endif

	if (rv != SCARD_S_SUCCESS)
	{
		(void)SCardDisconnect(hCard, SCARD_RESET_CARD);
		(void)SCardReleaseContext(hContext);
	}

	printf("Press enter: ");
	(void)getchar();
	printf("Testing SCardReconnect\t\t: ");
	rv = SCardReconnect(hCard, SCARD_SHARE_SHARED,
		SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_UNPOWER_CARD, &dwPref);
	test_rv(rv, hContext, PANIC);

	printf("Testing SCardDisconnect\t\t: ");
	rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
	test_rv(rv, hContext, PANIC);

#ifdef USE_AUTOALLOCATE
	printf("Testing SCardFreeMemory\t\t: ");
	rv = SCardFreeMemory(hContext, mszReaders);
	test_rv(rv, hContext, PANIC);
#else
	free(mszReaders);
#endif

	printf("Testing SCardReleaseContext\t: ");
	rv = SCardReleaseContext(hContext);
	test_rv(rv, hContext, PANIC);

	printf("\n");
	printf("PC/SC Test Completed Successfully !\n");

	return 0;
}
Esempio n. 28
0
static int unblock(sc_card_t* card, const char *so_pin, const char *user_pin) {
	int r;
	char *_so_pin = NULL, *_user_pin = NULL;
	size_t len;
	u8 key[24];
	struct sc_pin_cmd_data data;

	memset(&data, 0, sizeof(struct sc_pin_cmd_data));

	if (so_pin == NULL) {
		printf("============================================================\n");
		printf("WARNING\n");
		printf("Entering an incorrect admin key can break your card\n");
		printf("WARNING\n");
		printf("============================================================\n");
		printf("Enter admin key (48 hexadecimal characters) : ");
		util_getpass(&_so_pin, NULL, stdin);
		printf("\n");
	} else {
		_so_pin = (char *)so_pin;
	}

	len = sizeof(key);
	r = sc_hex_to_bin(_so_pin, key, &len);
	if (r < 0) {
		fprintf(stderr, "Error decoding initialization code (%s)\n", sc_strerror(r));
		return -1;
	}

	if (len != 24) {
		fprintf(stderr, "admin key must be a hexadecimal string of 48 characters\n");
		return -1;
	}

	r = sc_card_ctl(card, SC_CARDCTL_GIDS_AUTHENTICATE_ADMIN, (void *)key);
	if (r < 0) {
		fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_GIDS_AUTHENTICATE_ADMIN, *) failed with %s\n", sc_strerror(r));
		return -1;
	}
	printf("Administrator authentication successful\n");
	printf("Setting the new PIN\n");

	if (user_pin == NULL) {
		printf("Enter User-PIN (4 - 16 characters) : ");
		util_getpass(&_user_pin, NULL, stdin);
		printf("\n");
	} else {
		_user_pin = (char *)user_pin;
	}

	data.pin_type = SC_AC_CHV;
	data.cmd = SC_PIN_CMD_UNBLOCK;
	data.pin2.len = strlen(_user_pin);
	data.pin2.data = (unsigned char*) _user_pin;
	data.pin_reference = 0x80;
	r = sc_pin_cmd(card, &data, NULL);
	if (r < 0) {
		fprintf(stderr, "reset pin failed with %s\n", sc_strerror(r));
		return -1;
	}
	printf("Unblock PIN done successfuly\n");
	// the card should have deauthenticated the admin, but to be sure:
	sc_logout(card);
	return 0;
}
Esempio n. 29
0
int sc_pkcs15_hex_string_to_id(const char *in, struct sc_pkcs15_id *out)
{
	out->len = sizeof(out->value);
	return sc_hex_to_bin(in, out->value, &out->len);
}
Esempio n. 30
0
static int initialize(sc_card_t *card, const char *so_pin, const char *user_pin, const char* serial)
{
	sc_cardctl_gids_init_param_t param;
	size_t len;
	char *_so_pin = NULL, *_user_pin = NULL, *_serial = NULL;
	int r;

	memset(&param, 0, sizeof(sc_cardctl_gids_init_param_t));

	if (so_pin == NULL) {
		printf("Enter admin key (48 hexadecimal characters) : \n");
		printf("Press Enter to set the admin key to 00...00\n");
		util_getpass(&_so_pin, NULL, stdin);
		printf("\n");
	} else {
		_so_pin = (char *)so_pin;
	}

	len = sizeof(param.init_code);
	r = sc_hex_to_bin(_so_pin, param.init_code, &len);
	if (r < 0) {
		fprintf(stderr, "Error decoding initialization code (%s)\n", sc_strerror(r));
		return -1;
	}

	if (len == 0) {
	} else if (len != 24) {
		fprintf(stderr, "The admin key must be a hexadecimal string of 48 characters\n");
		return -1;
	}

	if (user_pin == NULL) {
		printf("Enter initial User-PIN (4 - 16 characters) : ");
		util_getpass(&_user_pin, NULL, stdin);
		printf("\n");
	} else {
		_user_pin = (char *)user_pin;
	}

	if (serial == NULL) {
		printf("Enter serial number (32 hexadecimal characters): \n");
		printf("Press Enter to set a random serial number\n");
		util_getpass(&_serial, NULL, stdin);
		printf("\n");
	} else {
		_serial = (char *)serial;
	}

	if (_serial[0] == '\0') {
		memset(param.cardid, 0, sizeof(param.cardid));
	} else if (strlen(_serial) != 32) {
		fprintf(stderr, "the serial number must be a hexadecimal string of 32 characters\n");
		return -1;
	} else {
		len = sizeof(param.cardid);
		r = sc_hex_to_bin(_serial, param.cardid, &len);
		if (r < 0) {
			fprintf(stderr, "Error decoding serial number (%s)\n", sc_strerror(r));
			return -1;
		}
	}

	param.user_pin_len = strlen(_user_pin);

	if (param.user_pin_len < 4) {
		fprintf(stderr, "PIN must be at least 4 characters long\n");
		return -1;
	}

	if (param.user_pin_len > 16) {
		fprintf(stderr, "PIN must not be longer than 16 characters\n");
		return -1;
	}

	param.user_pin = (u8 *)_user_pin;

	r = sc_card_ctl(card, SC_CARDCTL_GIDS_INITIALIZE, (void *)&param);
	if (r < 0) {
		fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_GIDS_INITIALIZE, *) failed with %s\n", sc_strerror(r));
	}

	return 0;
}