Esempio n. 1
0
static int rutoken_cipher(sc_card_t *card, u8 keyid,
		const u8 *in, size_t inlen,
		u8 *out, size_t outlen, int oper)
{
	int r;
	struct sc_rutoken_decipherinfo inf = { in, inlen, out, outlen };
	sc_security_env_t env;
	int cmd = (oper == OP_ENCRYPT) ?
			SC_CARDCTL_RUTOKEN_GOST_ENCIPHER :
			SC_CARDCTL_RUTOKEN_GOST_DECIPHER;

	memset(&env, 0, sizeof(env));
	env.key_ref[0] = keyid;
	env.key_ref_len = 1;
	env.algorithm = SC_ALGORITHM_GOST;
	env.operation = SC_SEC_OPERATION_DECIPHER;

	/*  set security env  */
	r = sc_set_security_env(card, &env, 0);
	if (r) {
		fprintf(stderr, "Error: Cipher failed (set security environment): %s\n",
		        sc_strerror(r));
		return -1;
	}
	/*  cipher  */
	r = sc_card_ctl(card, cmd, &inf);
	if (r) {
		fprintf(stderr, "Error: Cipher failed: %s\n", sc_strerror(r));
		return -1;
	}
	return 0;
}
Esempio n. 2
0
int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len)
{
	int r;
	sc_cardctl_openpgp_keygen_info_t key_info;
	u8 fingerprints[60];
	sc_path_t path;
	sc_file_t *file;

	if (key_id < 1 || key_id > 3) {
		printf("Unknown key ID %d.\n", key_id);
		return 1;
	}
	memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keygen_info_t));
	key_info.keytype = key_id;
	key_info.modulus_len = key_len;
	key_info.modulus = malloc(key_len/8);
	r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info);
	free(key_info.modulus);
	if (r < 0) {
		printf("Failed to generate key. Error %s.\n", sc_strerror(r));
		return 1;
	}
	sc_format_path("006E007300C5", &path);
	r = sc_select_file(card, &path, &file);
	r = sc_read_binary(card, 0, fingerprints, 60, 0);
	if (r < 0) {
		printf("Failed to retrieve fingerprints. Error %s.\n", sc_strerror(r));
		return 1;
	}
	printf("Fingerprint:\n%s\n", (char *)sc_dump_hex(fingerprints + 20*(key_id - 1), 20));
	return 0;
}
static void handle_change( sc_card_t *card, int        pin1, int        pin2,
	int        do_change, u8        *newpin, int        newlen)
{
	sc_path_t p;
	sc_file_t *f;
	struct sc_apdu a;
	u8 ref;
	int i;

	printf("\n%s %s with %s: ", do_change ? "Changing" : "Unblocking", pinlist[pin1].label, pinlist[pin2].label);

	sc_format_path(pinlist[pin1].path,&p);
	if((i=sc_select_file(card,&p,&f))<0){
		printf("\nCannot select %s, %s\n", pinlist[pin1].label, sc_strerror(i));
		return;
	}
	ref=f->prop_attr[2] | (strlen(pinlist[pin1].path)>8 ? 0x80 : 0x00);

	if(do_change){
		sc_format_apdu(card, &a, SC_APDU_CASE_3_SHORT, 0x24, 0x01, ref);
		a.data=newpin, a.lc=a.datalen=newlen;
	} else {
		sc_format_apdu(card, &a, SC_APDU_CASE_1, 0x2C, 0x03, ref);
	}
	if((i=sc_transmit_apdu(card, &a))<0){
		printf("\nsc_transmit_apdu() failed, %s\n", sc_strerror(i));
		return;
	}
	if(a.sw1!=0x90 && a.sw2!=0x00){
		printf("%02X%02X\n", a.sw1, a.sw2);
		return;
	}
	printf("OK\n");
}
Esempio n. 4
0
int sc_disconnect_card(sc_card_t *card)
{
	sc_context_t *ctx;

	if (!card)
		return SC_ERROR_INVALID_ARGUMENTS;

	ctx = card->ctx;
	LOG_FUNC_CALLED(ctx);

	if (card->lock_count != 0)
		return SC_ERROR_NOT_ALLOWED;
	if (card->ops->finish) {
		int r = card->ops->finish(card);
		if (r)
			sc_log(ctx, "card driver finish() failed: %s", sc_strerror(r));
	}

	if (card->reader->ops->disconnect) {
		int r = card->reader->ops->disconnect(card->reader);
		if (r)
			sc_log(ctx, "disconnect() failed: %s", sc_strerror(r));
	}

#ifdef ENABLE_SM
	/* release SM related resources */
	sc_card_sm_unload(card);
#endif

	sc_card_free(card);
	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
Esempio n. 5
0
static int rutoken_info(sc_card_t *card)
{	
	u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
	sc_serial_number_t serial;
	int r;
	
	r = sc_card_ctl(card, SC_CARDCTL_RUTOKEN_GET_INFO, rbuf);
	if (r) {
		fprintf(stderr, "Error: Get info failed: %s\n", sc_strerror(r));
		return -1;
	}
	printf("Type: %d\n", rbuf[0]);
	printf("Version: %d.%d\n", rbuf[1]>>4, rbuf[1] & 0x0F);
	printf("Memory: %d Kb\n", rbuf[2]*8);
	printf("Protocol version: %d\n", rbuf[3]);
	printf("Software version: %d\n", rbuf[4]);
	printf("Order: %d\n", rbuf[5]);
	
	r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
	if (r) {
		fprintf(stderr, "Error: Get serial failed: %s\n", sc_strerror(r));
		return -1;
	}
	printf("Serial number: ");
	util_hex_dump(stdout, serial.value, serial.len, NULL);
	putchar('\n');
	return 0;
}
Esempio n. 6
0
static int rutoken_mac(sc_card_t *card, u8 keyid,
		const u8 *in, size_t inlen,
		u8 *out, size_t outlen)
{
	int r;
	sc_security_env_t env;

	memset(&env, 0, sizeof(env));
	env.key_ref[0] = keyid;
	env.key_ref_len = 1;
	env.algorithm = SC_ALGORITHM_GOST;
	env.operation = SC_SEC_OPERATION_SIGN;

	/*  set security env  */
	r = sc_set_security_env(card, &env, 0);
	if (r) {
		fprintf(stderr, "Error: Computation signature (MAC) failed"
				" (set security environment): %s\n", sc_strerror(r));
		return -1;
	}
	/*  calculate hash  */
	r = sc_compute_signature(card, in, inlen, out, outlen);
	if (r) {
		fprintf(stderr, "Error: Computation signature (MAC) failed: %s\n",
				sc_strerror(r));
		return -1;
	}
	return 0;
}
Esempio n. 7
0
int main(int argc, char **argv)
{
	sc_context_t *ctx = NULL;
	sc_context_param_t ctx_param;
	sc_card_t *card = NULL;
	int r;

	/* get options */
	decode_options(argc, argv);

	/* connect to the card */
	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;
	}
	r = util_connect_card(ctx, &card, opt_reader, opt_wait, 0);
	if (r) {
		fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(r));
		return 1;
	}

	/* Check card type */
	if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V10 || card->type == SC_CARD_TYPE_MCRD_ESTEID_V11 || card->type == SC_CARD_TYPE_MCRD_ESTEID_V30)
		do_esteid(card);
	else if (card->type == SC_CARD_TYPE_BELPIC_EID)
		do_belpic(card);
	else {
		fprintf(stderr, "Not an EstEID or Belpic card!\n");
		goto out;
	}
	
	if (exec_program) {
		char *const largv[] = {exec_program, NULL};
		sc_unlock(card);
		sc_disconnect_card(card);
		sc_release_context(ctx);
		execv(exec_program, largv);
		/* we should not get here */
		perror("execv()");
		exit(1);
	}
	
out:
	sc_unlock(card);
	sc_disconnect_card(card);
	sc_release_context(ctx);
	exit(exit_status);
}
Esempio n. 8
0
static int read_data_object(void)
{
	int    r, i, count, oid_len = 0;
	struct sc_pkcs15_object *objs[32];
	struct sc_object_id      oid;

	r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, objs, 32);
	if (r < 0) {
		fprintf(stderr, "Data object enumeration failed: %s\n", sc_strerror(r));
		return 1;
	}
	count = r;

	r = sc_format_oid(&oid, opt_data);
	if (r == SC_SUCCESS) {
		while (oid.value[oid_len] >= 0) oid_len++;
	}

	for (i = 0; i < count; i++) {
		struct sc_pkcs15_data_info *cinfo = (struct sc_pkcs15_data_info *) objs[i]->data;
		struct sc_pkcs15_data *data_object;

		if (oid_len) {
			if (memcmp(oid.value, cinfo->app_oid.value, sizeof(int) * oid_len))
				continue;
		} else {
			if (strcmp(opt_data, cinfo->app_label) && strcmp(opt_data, objs[i]->label))
				continue;
		}
			
		if (verbose)
			printf("Reading data object with label '%s'\n", opt_data);
		r = authenticate(objs[i]);
		if (r >= 0) {
			r = sc_pkcs15_read_data_object(p15card, cinfo, &data_object);
			if (r) {
				fprintf(stderr, "Data object read failed: %s\n", sc_strerror(r));
				if (r == SC_ERROR_FILE_NOT_FOUND)
					continue; /* DEE emulation may say there is a file */
				return 1;
			}
			r = print_data_object("Data Object", data_object->data, data_object->data_len);
			sc_pkcs15_free_data_object(data_object);
			return r;
		} else {
			fprintf(stderr, "Authentication error: %s\n", sc_strerror(r));
			return 1;
		}
	}
	fprintf(stderr, "Data object with label '%s' not found.\n", opt_data);
	return 2;
}
static int do_cd(int argc, char **argv)
{
	sc_path_t path;
	sc_file_t *file;
	int r;

	if (argc != 1)
		goto usage;
	if (strcmp(argv[0], "..") == 0) {
		if (current_path.len < 4) {
			printf("unable to go up, already in MF.\n");
			return -1;
		}
		path = current_path;
		path.len -= 2;
		r = sc_select_file(card, &path, &file);
		if (r) {
			printf("unable to go up: %s\n", sc_strerror(r));
			return -1;
		}
		sc_file_free(current_file);
		current_file = file;
		current_path = path;
		return 0;
	}
	if (arg_to_path(argv[0], &path, 0) != 0) 
		goto usage;

	r = sc_select_file(card, &path, &file);
	if (r) {
		check_ret(r, SC_AC_OP_SELECT, "unable to select DF", current_file);
		return -1;
	}
	if ((file->type != SC_FILE_TYPE_DF) && !(card->caps & SC_CARD_CAP_NO_FCI)) {
		printf("Error: file is not a DF.\n");
		sc_file_free(file);
		r = sc_select_file(card, &current_path, NULL);
		if (r) {
			printf("unable to select parent file: %s\n", sc_strerror(r));
			die(1);
		}
		return -1;
	}
	current_path = path;
	sc_file_free(current_file);
	current_file = file;

	return 0;
usage:
	puts("Usage: cd <file_id>|aid:<DF name>");
	return -1;
}
Esempio n. 10
0
static int format_data(sc_card_t *card, const struct iso_sm_ctx *ctx,
        const u8 *data, size_t datalen,
        struct sc_asn1_entry *formatted_encrypted_data_entry,
        u8 **formatted_data, size_t *formatted_data_len)
{
    int r;
    u8 *pad_data = NULL;
    size_t pad_data_len = 0;

    if (!ctx || !formatted_data || !formatted_data_len) {
        r = SC_ERROR_INVALID_ARGUMENTS;
        goto err;
    }

    r = add_padding(ctx, data, datalen, &pad_data);
    if (r < 0) {
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not add padding to data: %s",
                sc_strerror(r));
        goto err;
    }
    pad_data_len = r;

    bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Data to encrypt", pad_data, pad_data_len);
    r = ctx->encrypt(card, ctx, pad_data, pad_data_len, formatted_data);
    if (r < 0) {
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not encrypt the data");
        goto err;
    }
    bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Cryptogram", *formatted_data, r);

    r = prefix_buf(ctx->padding_indicator, *formatted_data, r, formatted_data);
    if (r < 0) {
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not prepend padding indicator to formatted "
                "data: %s", sc_strerror(r));
        goto err;
    }

    *formatted_data_len = r;
    sc_format_asn1_entry(formatted_encrypted_data_entry,
            *formatted_data, formatted_data_len, SC_ASN1_PRESENT);

    r = SC_SUCCESS;

err:
    if (pad_data) {
        sc_mem_clear(pad_data, pad_data_len);
        free(pad_data);
    }

    return r;
}
Esempio n. 11
0
static int dump_unusedspace(void)
{
	u8 *buf = NULL;
	size_t buf_len;
	sc_path_t path;
	sc_pkcs15_unusedspace_t *us;
	int r;

	if (p15card->file_unusedspace != NULL)
		path = p15card->file_unusedspace->path;
	else {
		path = p15card->file_app->path;
		sc_append_path_id(&path, (const u8 *) "\x50\x33", 2);
	}
	path.count = -1;

	sc_ctx_suppress_errors_on(p15card->card->ctx);
	r = sc_pkcs15_read_file(p15card, &path, &buf, &buf_len, NULL);
	sc_ctx_suppress_errors_off(p15card->card->ctx);
	if (r < 0) {
		if (r == SC_ERROR_FILE_NOT_FOUND) {
			printf("\nNo EF(UnusedSpace) file\n");
			r = 0;
		}
		else
			printf("\nError reading file \"%s\": %s\n",
				sc_print_path(&path), sc_strerror(r));
		goto err;
	}

	r = sc_pkcs15_parse_unusedspace(buf, buf_len, p15card);
	if (r != 0) {
		printf("\nError parsing EF(UnusedSpace): %s\n", sc_strerror(r));
		goto err;
	}

	if (p15card->unusedspace_list == NULL)
		printf("\nEF(UnusedSpace) file is empty\n");
	else {
		printf("\nContents of EF(UnusedSpace):\n");
		for (us = p15card->unusedspace_list; us != NULL; us = us->next)
		printf("  - path=%s, index=%d, length=%d  -- auth_id = %s\n",
			sc_print_path(&us->path), us->path.index, us->path.count,
			us->auth_id.len == 0 ? "<empty>" : sc_pkcs15_print_id(&us->auth_id));
	}

err:
	if (buf != NULL)
		free(buf);
	return r;
}
Esempio n. 12
0
static int do_apdu(int argc, char **argv)
{
	sc_apdu_t apdu;
	u8 buf[SC_MAX_APDU_BUFFER_SIZE * 2];
	u8 rbuf[SC_MAX_APDU_BUFFER_SIZE * 2];
	size_t len, i;
	int r;

	if (argc < 1)
		return usage(do_apdu);

	for (i = 0, len = 0; i < (unsigned) argc; i++)   {
		size_t len0 = strlen(argv[i]);

		if ((r = parse_string_or_hexdata(argv[i], buf + len, &len0)) < 0) {
			fprintf(stderr, "error parsing %s: %s\n", argv[i], sc_strerror(r));
			return r;
		};
		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: ");
	util_hex_dump(stdout, buf, len, " ");
	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);

	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	if (r)
		printf("Failure: %s\n", sc_strerror(r));
	else
		printf("Success!\n");

	return 0;
}
Esempio n. 13
0
static int do_info(sc_card_t *card, const struct ef_name_map *map)
{
	int i;
	u8 buf[2048];

	for (i = 0; map[i].ef != NULL; i++) {
		sc_path_t path;
		sc_file_t *file;
		size_t count;
		int r;

		sc_format_path(map[i].ef, &path);
		r = sc_select_file(card, &path, &file);
		if (r) {
			util_error("failed to select EF %s: %s", map[i].ef, sc_strerror(r));
			return EXIT_FAILURE;
		}

		count = file->size;
		if (!count)
			continue;

		if (count > sizeof(buf) - 1) {
			util_error("too small buffer to read the OpenPGP map");
			return EXIT_FAILURE;
		}

		r = sc_read_binary(card, 0, buf, count, 0);
		if (r < 0) {
			util_error("failed to read %s: %s", map[i].ef, sc_strerror(r));
			return EXIT_FAILURE;
		}
		if (r != (signed) count || (size_t) r < map[i].offset + map[i].length) {
			util_error("%s: expecting %"SC_FORMAT_LEN_SIZE_T"d bytes, got only %d",
				map[i].ef, count, r);
			return EXIT_FAILURE;
		}
		if (map[i].offset > 0) {
			memmove(buf, buf + map[i].offset, map[i].length);
			count -= map[i].offset;
		}
		if (map[i].length > 0 && count > map[i].length)
			count = map[i].length;
		if (map[i].type == TYPE_STRING)
			buf[count] = '\0';

		display_data(&map[i], buf, count);
	}

	return EXIT_SUCCESS;
}
static void show_initial_puk(sc_card_t *card)
{
	sc_path_t p;
	sc_file_t *f;
	struct sc_apdu a;
	u8 buf1[128], buf2[128];
	int i;

	printf("\nReading crypted Initial-PUK-file: ");
	sc_format_path("3F004350",&p);
	if((i=sc_select_file(card,&p,&f))<0){
		printf("Cannot select crypted Initial-PUK-file, %s\n", sc_strerror(i));
		return;
	}
	if((i=sc_read_binary(card,0,buf1,128,0))!=128){
		printf("Cannot read crypted Initial-PUK-file, %s\n", sc_strerror(i));
		return;
	}

	printf("OK\nDecrypting crypted Initial-PUK-file: ");
	sc_format_path("3F00DF01",&p);
	if((i=sc_select_file(card,&p,&f))<0){
		printf("Cannot select DF01, %s\n", sc_strerror(i));
		return;
	}
	sc_format_apdu(card, &a, SC_APDU_CASE_3_SHORT, 0x22, 0xC1, 0xB8);
	buf2[0]=0x80, buf2[1]=0x01, buf2[2]=0x10, buf2[3]=0x84, buf2[4]=0x01, buf2[5]=0x81;
	a.data=buf2, a.lc=a.datalen=6;
	if((i=sc_transmit_apdu(card, &a))<0){
		printf("sc_transmit_apdu(MSE) failed, %s\n", sc_strerror(i));
		return;
	}
	if(a.sw1!=0x90 && a.sw2!=0x00){
		printf("MSE=%02X%02X\n", a.sw1, a.sw2);
		return;
	}
	sc_format_apdu(card, &a, SC_APDU_CASE_4_SHORT, 0x2A, 0x84, 0x80);
	a.data=buf1, a.lc=a.datalen=128;
	a.resp=buf2, a.le=a.resplen=128;
	if((i=sc_transmit_apdu(card, &a))<0){
		printf("sc_transmit_apdu(PSO) failed, %s\n", sc_strerror(i));
		return;
	}
	if(a.sw1!=0x90 && a.sw2!=0x00){
		printf("PSO=%02X%02X\n", a.sw1, a.sw2);
		return;
	}
	printf("OK ==> Initial-PUK:"); for(i=120;i<128;++i) printf("%c",buf2[i]); printf("\n");
}
Esempio n. 15
0
static int list_data_objects(void)
{
	int r, i, count;
	struct sc_pkcs15_object *objs[32];

	r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, objs, 32);
	if (r < 0) {
		fprintf(stderr, "Data object enumeration failed: %s\n", sc_strerror(r));
		return 1;
	}
	count = r;
	for (i = 0; i < count; i++) {
		int idx;
		struct sc_pkcs15_data_info *cinfo = (struct sc_pkcs15_data_info *) objs[i]->data;

		printf("Reading data object <%i>\n", i);
		printf("applicationName: %s\n", cinfo->app_label);
		printf("Label:           %s\n", objs[i]->label);
		printf("applicationOID:  ");
		if (cinfo->app_oid.value[0] >= 0) {
			printf("%i", cinfo->app_oid.value[0]);
			idx = 1;
			while (idx < SC_MAX_OBJECT_ID_OCTETS) {
				if (cinfo->app_oid.value[idx] < 0)
					break;
				printf(".%i", cinfo->app_oid.value[idx++]);
			}
			printf("\n");
		} else
			printf("NONE\n");
		printf("Path:            %s\n", sc_print_path(&cinfo->path));
		if (objs[i]->auth_id.len == 0) {
			struct sc_pkcs15_data *data_object;
			r = sc_pkcs15_read_data_object(p15card, cinfo, &data_object);
			if (r) {
				fprintf(stderr, "Data object read failed: %s\n", sc_strerror(r));
				if (r == SC_ERROR_FILE_NOT_FOUND)
					 continue; /* DEE emulation may say there is a file */
				return 1;
			}
			r = list_data_object("Data Object", data_object->data, data_object->data_len);
			sc_pkcs15_free_data_object(data_object);
		} else {
			printf("Auth ID:         %s\n", sc_pkcs15_print_id(&objs[i]->auth_id));
		}
	}
	return 0;
}
Esempio n. 16
0
static int create_sysdf(sc_profile_t *profile, sc_card_t *card, const char *name)
{
	sc_file_t *file;
	sc_path_t path;
	int r;

	assert(profile && card && card->ctx && name);
	r = sc_profile_get_file(profile, name, &file);
	if (r == SC_SUCCESS)
	{
		assert(file);
		path = file->path;
		assert(path.len > 2);
		if (path.len > 2)
			path.len -= 2;
		r = sc_select_file(card, &path, NULL);
		if (r == SC_SUCCESS)
			r = sc_file_add_acl_entry(file, SC_AC_OP_CREATE,
					SC_AC_CHV, RTECP_USER_PIN_REF);
		if (r == SC_SUCCESS)
			r = sc_file_add_acl_entry(file, SC_AC_OP_DELETE,
					SC_AC_NEVER, SC_AC_KEY_REF_NONE);
		if (r == SC_SUCCESS)
			r = sc_create_file(card, file);
		assert(file);
		sc_file_free(file);
	}
	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
		"Create %s failed: %s\n", name, sc_strerror(r));
	return r;
}
Esempio n. 17
0
static void do_random()
{
	unsigned char buffer[128];
	int r, count = 128;
	int n = 128;
	int n_bits = 1024;

        struct rand_pool_info *output;
	int fd = open(DEV_RANDOM, O_WRONLY);
	if (fd == -1) {
		syslog(LOG_ERR,"Failed to open %s", DEV_RANDOM);
	}
	while (1) {

		r = sc_get_challenge(card, buffer, count);
		if (r < 0) {
			syslog(LOG_ERR,"Failed to get random bytes: %s\n", sc_strerror(r));
		}
        	output = (struct rand_pool_info *)malloc(sizeof(struct rand_pool_info) + n);
		output -> entropy_count = n_bits;
		output -> buf_size      = n;
		memcpy(&(output -> buf[0]), buffer, n);
		if (ioctl(fd, RNDADDENTROPY, output) == -1) {
			syslog(LOG_ERR,"ioctl(RNDADDENTROPY) failed!");
		}
		free(output);
		sleep(1);
	}
	close(fd);
}
Esempio n. 18
0
static int generate_gostkey(sc_card_t *card, u8 keyid, u8 keyoptions)
{
	const sc_SecAttrV2_t gk_sec_attr = 
		{0x44, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 2};
	sc_DOHdrV2_t paramkey;
	int r;

	memset(&paramkey, 0, sizeof(paramkey));
	paramkey.wDOBodyLen         = SC_RUTOKEN_DEF_LEN_DO_GOST;
	paramkey.OTID.byObjectType  = SC_RUTOKEN_TYPE_KEY;
	paramkey.OTID.byObjectID    = keyid;
	paramkey.OP.byObjectOptions = keyoptions;

	/* assert(sizeof(*gk_sec_attr)); */
	/* assert(sizeof(*paramkey.SA_V2)); */
	/* assert(sizeof(paramkey.SA_V2) == sizeof(gk_sec_attr)); */
	memcpy(paramkey.SA_V2, gk_sec_attr, sizeof(gk_sec_attr));

        r = sc_card_ctl(card, SC_CARDCTL_RUTOKEN_GENERATE_KEY_DO, &paramkey);
	if (r) {
		fprintf(stderr, "Error: Generate GOST key failed: %s\n", sc_strerror(r));
		return -1;
	}
	return 0;
}
Esempio n. 19
0
static int
do_random(int argc, char **argv)
{
	unsigned char buffer[128];
	int r, count;

	if (argc != 1)
		goto usage;

	count = atoi(argv[0]);
	if (count < 0 || count > 128) {
		printf("Number must be in range 0..128\n");
		return -1;
	}

	r = sc_get_challenge(card, buffer, count);
	if (r < 0) {
		printf("Failed to get random bytes: %s\n", sc_strerror(r));
		return -1;
	}

	util_hex_dump_asc(stdout, buffer, count, 0);
	return 0;

usage:
	printf("Usage: random count\n");
	return -1;
}
Esempio n. 20
0
static int enum_pins(struct sc_pkcs15_object ***ret)
{
	struct sc_pkcs15_object **objs;
	int i, n;

	n = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, NULL, 0);
	if (n < 0) {
		fprintf(stderr, "Error enumerating PIN codes: %s\n",
			sc_strerror(n));
		return 1;
	}
	if (n == 0) {
		fprintf(stderr, "No PIN codes found!\n");
		return 0;
	}
	objs = calloc(n, sizeof(*objs));
	if (!objs) {
		fprintf(stderr, "Not enough memory!\n");
		return 1;
	}
	if (0 > sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, n)) {
		fprintf(stderr, "Error enumerating PIN codes\n");
		free(objs);
		return 1;
	}
	for (i = 0; i < n; i++) {
		sc_test_print_object(objs[i]);
	}
	*ret = objs;
	return n;
}
Esempio n. 21
0
static int ask_and_verify_pin(struct sc_pkcs15_object *obj)
{
	struct sc_pkcs15_pin_info *pin;
	int i = 0;
	char prompt[80];
	u8 *pass;

	pin = (struct sc_pkcs15_pin_info *) obj->data;
	if (pin->flags & SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN) {
		printf("Skipping unblocking pin [%s]\n", obj->label);
		return 0;
	}

	sprintf(prompt, "Please enter PIN code [%s]: ", obj->label);
	pass = (u8 *) getpass(prompt);

	sc_lock(card);
	i = sc_pkcs15_verify_pin(p15card, pin, pass, strlen((char *) pass));
	sc_unlock(card);
	if (i) {
		if (i == SC_ERROR_PIN_CODE_INCORRECT)
			fprintf(stderr,
				"Incorrect PIN code (%d tries left)\n",
				pin->tries_left);
		else
			fprintf(stderr,
				"PIN verifying failed: %s\n",
				sc_strerror(i));
		return 1;
	} else
		printf("PIN code correct.\n");

	return 0;
}
Esempio n. 22
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;
}
Esempio n. 23
0
static void
check_ret(int r, int op, const char *err, const sc_file_t *file)
{
	fprintf(stderr, "%s: %s\n", err, sc_strerror(r));
	if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED)
		fprintf(stderr, "ACL for operation: %s\n", util_acl_to_str(sc_file_get_acl_entry(file, op)));
}
Esempio n. 24
0
static int do_sm(int argc, char **argv)
{
	int r = SC_ERROR_NOT_SUPPORTED, ret = -1;

	if (argc != 1)
		return usage(do_sm);

#ifdef ENABLE_SM
	if (!strcmp(argv[0],"open"))   {
		if (!card->sm_ctx.ops.open)   {
			printf("Not supported\n");
			return -1;
		}
		r = card->sm_ctx.ops.open(card);
	}
	else if (!strcmp(argv[0],"close"))   {
		if (!card->sm_ctx.ops.close)   {
			printf("Not supported\n");
			return -1;
		}
		r = card->sm_ctx.ops.close(card);
	}
#endif
	if (r == SC_SUCCESS)   {
		ret = 0;
		printf("Success!\n");
	}
	else   {
		printf("Failure: %s\n", sc_strerror(r));
	}

	return ret;
}
Esempio n. 25
0
char *
sc_get_key_label(Key *key)
{
	int r;
	const struct sc_priv_data *priv;
	struct sc_pkcs15_object *key_obj;

	priv = (const struct sc_priv_data *) RSA_get_app_data(key->rsa);
	if (priv == NULL || p15card == NULL) {
		logit("SmartCard key not loaded");
		/* internal error => return default label */
		return xstrdup("smartcard key");
	}
	r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj);
	if (r) {
		logit("Unable to find private key from SmartCard: %s",
		      sc_strerror(r));
		return xstrdup("smartcard key");
	}
	if (key_obj == NULL || key_obj->label == NULL)
		/* the optional PKCS#15 label does not exists
		 * => return the default label */
		return xstrdup("smartcard key");
	return xstrdup(key_obj->label);
}
Esempio n. 26
0
static int do_change(int argc, char **argv)
{
	int ref, r, tries_left = -1;
	u8 oldpin[64];
	u8 newpin[64];
	size_t oldpinlen = 0;
	size_t newpinlen = 0;
	struct sc_pin_cmd_data data;

	memset(&data, 0, sizeof(data));
	data.cmd = SC_PIN_CMD_CHANGE;

	if (argc < 1 || argc > 3)
		return usage(do_change);
	if (strncasecmp(argv[0], "CHV", 3)) {
		printf("Invalid type.\n");
		return usage(do_change);
	}
	if (sscanf(argv[0] + 3, "%d", &ref) != 1) {
		printf("Invalid key reference.\n");
		return usage(do_change);
	}

	if (argc == 3) {
		oldpinlen = sizeof(oldpin);
		if (parse_string_or_hexdata(argv[1], oldpin, &oldpinlen) != 0) {
			printf("Invalid key value.\n");
			return usage(do_change);
		}
	}

	if (argc >= 2) {
		newpinlen = sizeof(newpin);
		if (parse_string_or_hexdata(argv[argc-1], newpin, &newpinlen) != 0) {
			printf("Invalid key value.\n");
			return usage(do_change);
		}
	}

	data.pin_type = SC_AC_CHV;
	data.pin_reference = ref;
	data.pin1.data = oldpinlen ? oldpin : NULL;
	data.pin1.len = oldpinlen;
	data.pin2.data = newpinlen ? newpin : NULL;
	data.pin2.len = newpinlen;

	r = sc_pin_cmd(card, &data, &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;
}
Esempio n. 27
0
static int do_get_data(int argc, char **argv)
{
	unsigned char buffer[256];
	unsigned int tag;
	FILE *fp;
	int r;

	if (argc != 1 && argc != 2)
		return usage(do_get_data);

	tag = strtoul(argv[0], NULL, 16);
	r = sc_get_data(card, tag, buffer, sizeof(buffer));
	if (r < 0) {
		printf("Failed to get data object: %s\n", sc_strerror(r));
		return -1;
	}

	if (argc == 2) {
		const char	*filename = argv[1];

		if (!(fp = fopen(filename, "w"))) {
			perror(filename);
			return -1;
		}
		fwrite(buffer, r, 1, fp);
		fclose(fp);
	} else {
		printf("Object %04x:\n", tag & 0xFFFF);
		util_hex_dump_asc(stdout, buffer, r, 0);
	}

	return 0;
}
Esempio n. 28
0
static int decipher(struct sc_pkcs15_object *obj)
{
	u8 buf[1024], out[1024];
	int r, c, len;

	if (opt_input == NULL) {
		fprintf(stderr, "No input file specified.\n");
		return 2;
	}
	c = read_input(buf, sizeof(buf));
	if (c < 0)
		return 2;

	len = sizeof(out);
	if (!((struct sc_pkcs15_prkey_info *) obj->data)->native) {
                fprintf(stderr, "Deprecated non-native key detected! Upgrade your smart cards.\n");
		return SC_ERROR_NOT_SUPPORTED;
	}

	r = sc_pkcs15_decipher(p15card, obj, opt_crypt_flags & SC_ALGORITHM_RSA_PAD_PKCS1, buf, c, out, len);
	if (r < 0) {
		fprintf(stderr, "Decrypt failed: %s\n", sc_strerror(r));
		return 1;
	}
	r = write_output(out, r);

	return 0;
}
Esempio n. 29
0
int main(int argc, char *argv[])
{
	int i;

	i = sc_test_init(&argc, argv);
	if (i < 0)
		return 1;
	printf("Looking for a PKCS#15 compatible Smart Card... ");
	fflush(stdout);
	sc_lock(card);
	i = sc_pkcs15_bind(card, &p15card);
	/* Keep card locked to prevent useless calls to sc_logout */
	if (i) {
		fprintf(stderr, "failed: %s\n", sc_strerror(i));
		return 1;
	}
	printf("found.\n");
	sc_test_print_card(p15card);

	dump_objects("PIN codes", SC_PKCS15_TYPE_AUTH_PIN);
	dump_objects("Private keys", SC_PKCS15_TYPE_PRKEY);
	dump_objects("Public keys", SC_PKCS15_TYPE_PUBKEY);
	dump_objects("X.509 certificates", SC_PKCS15_TYPE_CERT_X509);
	dump_objects("data objects", SC_PKCS15_TYPE_DATA_OBJECT);
	dump_unusedspace();

	sc_pkcs15_unbind(p15card);
	sc_unlock(card);
	sc_test_cleanup();
	return 0;
}
Esempio n. 30
0
static int do_unblock(int argc, char **argv)
{
	int ref, r;
	u8 puk[30];
	u8 newpin[30];
	size_t puklen = 0;
	size_t newpinlen = 0;

	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;
	}

	if (argc > 1) {
		puklen = sizeof(puk);
		if (parse_string_or_hexdata(argv[1], puk, &puklen) != 0) {
			printf("Invalid key value.\n");
			goto usage;
		}
	}

	if (argc > 2)   {
		newpinlen = sizeof(newpin);
		if (parse_string_or_hexdata(argv[2], newpin, &newpinlen) != 0) {
			printf("Invalid key value.\n");
			goto usage;
		}
	}

	r = sc_reset_retry_counter (card, SC_AC_CHV, ref,
                                      puklen ? puk : NULL, puklen,
                                      newpinlen ? newpin : NULL, 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;
}