コード例 #1
0
ファイル: pkcs15-pteid.c プロジェクト: martinpaljak/OpenSC
static
int dump_ef(sc_card_t * card, const char *path, u8 * buf, size_t * buf_len)
{
	int rv;
	sc_file_t *file = NULL;
	sc_path_t scpath;
	sc_format_path(path, &scpath);
	rv = sc_select_file(card, &scpath, &file);
	if (rv < 0) {
		if (file)
			sc_file_free(file);
		return rv;
	}
	if (file->size > *buf_len) {
		sc_file_free(file);
		return SC_ERROR_BUFFER_TOO_SMALL;
	}
	rv = sc_read_binary(card, 0, buf, file->size, 0);
	sc_file_free(file);
	if (rv < 0)
		return rv;
	*buf_len = rv;

	return SC_SUCCESS;
}
コード例 #2
0
ファイル: pkcs15-gpk.c プロジェクト: Hubitronic/OpenSC
/*
 * On-board key generation.
 */
static int
gpk_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
                        sc_pkcs15_object_t *obj,
                        sc_pkcs15_pubkey_t *pubkey)
{
	struct sc_cardctl_gpk_genkey args;
	sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
	unsigned int    keybits;
	sc_file_t	*keyfile;
	int             r, n;

	sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "path=%s, %d bits\n", sc_print_path(&key_info->path),
			key_info->modulus_length);

	if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
		sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "GPK supports generating only RSA keys.");
		return SC_ERROR_NOT_SUPPORTED;
	}

	/* The caller is supposed to have chosen a key file path for us */
	if (key_info->path.len == 0 || key_info->modulus_length == 0)
		return SC_ERROR_INVALID_ARGUMENTS;
	keybits = key_info->modulus_length;

	if ((r = sc_select_file(p15card->card, &key_info->path, &keyfile)) < 0)
		return r;

#ifndef PK_INIT_IMMEDIATELY
	r = gpk_pkfile_init_public(profile, p15card, keyfile, SC_ALGORITHM_RSA,
			keybits, key_info->usage);
	if (r < 0) {
		sc_file_free(keyfile);
		return r;
	}

	if ((r = gpk_pkfile_init_private(p15card->card, keyfile, 5 * ((3 + keybits / 16 + 7) & ~7UL))) < 0) {
		sc_file_free(keyfile);
		return r;
	}
#endif
	sc_file_free(keyfile);

	memset(&args, 0, sizeof(args));
	/*args.exponent = 0x10001;*/
	n = key_info->path.len;
	args.fid = (key_info->path.value[n-2] << 8) | key_info->path.value[n-1];
	args.privlen = keybits;

	r = sc_card_ctl(p15card->card, SC_CARDCTL_GPK_GENERATE_KEY, &args);
	if (r < 0)
		return r;

	/* This is fairly weird. The GENERATE RSA KEY command returns
	 * immediately, but obviously it needs more time to complete.
	 * This is why we sleep here. */
	sleep(20);

	pubkey->algorithm = SC_ALGORITHM_RSA;
	return gpk_read_rsa_key(p15card->card, &pubkey->u.rsa);
}
コード例 #3
0
ファイル: pkcs15-cflex.c プロジェクト: CendioOssman/OpenSC
/*
 * Generate key
 */
static int
cflex_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
			sc_pkcs15_object_t *obj,
			sc_pkcs15_pubkey_t *pubkey)
{
	struct sc_cardctl_cryptoflex_genkey_info args;
	sc_card_t *card = p15card->card;
	sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
	unsigned int	keybits;
	unsigned char	raw_pubkey[256];
	sc_file_t	*prkf = NULL, *pukf = NULL;
	int		r;

	if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Cryptoflex supports only RSA keys.");
		return SC_ERROR_NOT_SUPPORTED;
	}
	/* Get the public and private key file */
	r = cflex_get_keyfiles(profile, card, &key_info->path, &prkf, &pukf);
	if (r < 0)
		return r;
	if (! prkf)
		return SC_ERROR_NOT_SUPPORTED;

	/* Make sure we authenticate first */
	r = sc_pkcs15init_authenticate(profile, p15card, prkf, SC_AC_OP_CRYPTO);
	if (r < 0)
		goto out;

	keybits = key_info->modulus_length;

	/* Perform key generation */
	memset(&args, 0, sizeof(args));
	args.exponent = 0x10001;
	args.key_bits = keybits;
	args.key_num  = key_info->key_reference;
	r = sc_card_ctl(card, SC_CARDCTL_CRYPTOFLEX_GENERATE_KEY, &args);
	if (r < 0)
		goto out;

	/* extract public key */
	pubkey->algorithm = SC_ALGORITHM_RSA;
	pubkey->u.rsa.modulus.len   = keybits / 8;
	pubkey->u.rsa.modulus.data  = malloc(keybits / 8);
	pubkey->u.rsa.exponent.len  = 3;
	pubkey->u.rsa.exponent.data = malloc(3);
	memcpy(pubkey->u.rsa.exponent.data, "\x01\x00\x01", 3);
	if ((r = sc_select_file(card, &pukf->path, NULL)) < 0
	 || (r = sc_read_binary(card, 3, raw_pubkey, keybits / 8, 0)) < 0)
		goto out;

	invert_buf(pubkey->u.rsa.modulus.data, raw_pubkey, pubkey->u.rsa.modulus.len);

out:	if (pukf)
		sc_file_free(pukf);
	if (prkf)
		sc_file_free(prkf);
	return r;
}
コード例 #4
0
void sc_pkcs15_card_clear(sc_pkcs15_card_t *p15card)
{
	if (p15card == NULL)
		return;
	p15card->version = 0;
	p15card->flags   = 0;
	while (p15card->obj_list != NULL)
		sc_pkcs15_remove_object(p15card, p15card->obj_list);
	p15card->obj_list = NULL;
	while (p15card->df_list != NULL)
		sc_pkcs15_remove_df(p15card, p15card->df_list);
	p15card->df_list = NULL;
	if (p15card->file_app != NULL) {
		sc_file_free(p15card->file_app);
		p15card->file_app = NULL;
	}
	if (p15card->file_tokeninfo != NULL) {
		sc_file_free(p15card->file_tokeninfo);
		p15card->file_tokeninfo = NULL;
	}
	if (p15card->file_odf != NULL) {
		sc_file_free(p15card->file_odf);
		p15card->file_odf = NULL;
	}
	if (p15card->file_unusedspace != NULL) {
		sc_file_free(p15card->file_unusedspace);
		p15card->file_unusedspace = NULL;
	}
	if (p15card->label != NULL) {
		free(p15card->label);
		p15card->label = NULL;
	}
	if (p15card->serial_number != NULL) {
		free(p15card->serial_number);
		p15card->serial_number = NULL;
	}
	if (p15card->manufacturer_id != NULL) {
		free(p15card->manufacturer_id);
		p15card->manufacturer_id = NULL;
	}
	if (p15card->last_update != NULL) {
		free(p15card->last_update);
		p15card->last_update = NULL;
	}
	if (p15card->preferred_language != NULL) {
		free(p15card->preferred_language);
		p15card->preferred_language = NULL;
	}
	if (p15card->seInfo != NULL) {
		size_t i;
		for (i = 0; i < p15card->num_seInfo; i++)
			free(p15card->seInfo[i]);
		free(p15card->seInfo);
		p15card->seInfo     = NULL;
		p15card->num_seInfo = 0;
	}
}
コード例 #5
0
ファイル: westcos-tool.c プロジェクト: jpki/OpenSC
static int create_file_cert(sc_card_t *card)
{
	int r;
	int size = 0;
	sc_path_t path;
	sc_file_t *file = NULL;

	sc_format_path("3F00", &path);
	r = sc_select_file(card, &path, &file);
	if(r) goto out;

	if(file)
	{
		size = (file->size) - 32;
		sc_file_free(file);
		file = NULL;
	} else {
		size = 2048;
	}

	sc_format_path("0002", &path);
	r = sc_select_file(card, &path, NULL);
	if(r)
	{
		if(r != SC_ERROR_FILE_NOT_FOUND) goto out;

		file = sc_file_new();
		if(file == NULL)
		{
			printf("Memory error.\n");
			goto out;
		}

		file->type = SC_FILE_TYPE_WORKING_EF;
		file->ef_structure = SC_FILE_EF_TRANSPARENT;
		file->shareable = 0;

		file->size = size;

		r = sc_file_add_acl_entry(file, SC_AC_OP_READ, SC_AC_NONE, 0);
		if(r) goto out;
		r = sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, SC_AC_CHV, 0);
		if(r) goto out;
		r = sc_file_add_acl_entry(file, SC_AC_OP_ERASE, SC_AC_CHV, 0);
		if(r) goto out;

		file->path = path;
		r = sc_create_file(card, file);
		if(r) goto out;
	}

out:
	if(file)
		sc_file_free(file);

	return r;
}
コード例 #6
0
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) {
		path = current_path;
		if (path.len < 4) {
			printf("unable to go up, already in MF.\n");
			return -1;
		}

		if (path.type == SC_PATH_TYPE_DF_NAME)   {
			sc_format_path("3F00", &path);
		}
		else   {
			path.len -= 2;
		}

		r = sc_select_file(card, &path, &file);
		if (r) {
			printf("unable to go up: %s\n", sc_strerror(r));
			return -1;
		}
		if (current_file)
			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->type != SC_CARD_TYPE_BELPIC_EID)) {
		printf("Error: file is not a DF.\n");
		sc_file_free(file);
		select_current_path_or_die();
		return -1;
	}
	current_path = path;
	if (current_file)
		sc_file_free(current_file);
	current_file = file;

	return 0;
usage:
	puts("Usage: cd <file_id>|aid:<DF name>");
	return -1;
}
コード例 #7
0
ファイル: pkcs15-muscle.c プロジェクト: securez/opendnie
/*
 * Store a private key object.
 */
static int
muscle_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
			sc_pkcs15_object_t *obj,
			sc_pkcs15_prkey_t *key)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
	sc_file_t* prkf;
	struct sc_pkcs15_prkey_rsa *rsa;
	sc_cardctl_muscle_key_info_t info;
	int		r;
	
	if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Muscle supports RSA keys only.");
		return SC_ERROR_NOT_SUPPORTED;
	}
	/* Verification stuff */
	/* Used for verification AND for obtaining private key acls */
	r = sc_profile_get_file_by_path(profile, &key_info->path, &prkf);
	if(!prkf) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_NOT_SUPPORTED);
	r = sc_pkcs15init_authenticate(profile, p15card, prkf, SC_AC_OP_CRYPTO);
	if (r < 0) {
		sc_file_free(prkf);
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_NOT_SUPPORTED);
	}
	sc_file_free(prkf);
	r = muscle_select_key_reference(profile, p15card, key_info);
	if (r < 0) {
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,r);
	}
	rsa = &key->u.rsa;
	
	info.keySize = rsa->modulus.len << 3;
	info.keyType = 0x03; /* CRT type */
	info.keyLocation = key_info->key_reference * 2; /* Mult by 2 to preserve even/odd keynumber structure */
	
	info.pLength = rsa->p.len;
	info.pValue = rsa->p.data;
	info.qLength = rsa->q.len;
	info.qValue = rsa->q.data;
	
	info.pqLength = rsa->iqmp.len;
	info.pqValue = rsa->iqmp.data;
	
	info.dp1Length = rsa->dmp1.len;
	info.dp1Value = rsa->dmp1.data;
	info.dq1Length = rsa->dmq1.len;
	info.dq1Value = rsa->dmq1.data;
	
	r = sc_card_ctl(p15card->card, SC_CARDCTL_MUSCLE_IMPORT_KEY, &info);
	if (r < 0) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unable to import key");
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,r);
	}
	return r;
}
コード例 #8
0
ファイル: pkcs15-setcos.c プロジェクト: BradPID/OpenSC
/*
 * Create the MF and global pin file if they don't exist.
 */
static int
setcos_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_file_t *mf = profile->mf_info->file;
	sc_file_t *pinfile;
	int r;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

	/* Create the MF if it doesn't exist yet */
	r = sc_select_file(p15card->card, &mf->path, NULL);
	if (r == SC_ERROR_FILE_NOT_FOUND) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "MF doesn't exist, creating now");

		/* Fix up the file's ACLs */
		r = sc_pkcs15init_fixup_file(profile, p15card, mf);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "MF fixup failed");

		mf->status = SC_FILE_STATUS_CREATION;
		r = sc_create_file(p15card->card, mf);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "MF creation failed");
	}
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select MF");

	/* Create the global pin file if it doesn't exist yet */
	r = sc_profile_get_file(profile, "pinfile", &pinfile);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot get 'pinfile' from profile");

	r = sc_select_file(p15card->card, &pinfile->path, NULL);
	if (r == SC_ERROR_FILE_NOT_FOUND) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Global pin file doesn't exist, creating now");

		/* Fix up the file's ACLs */
		r = sc_pkcs15init_fixup_file(profile, p15card, pinfile);
		if (r < 0)
			sc_file_free(pinfile);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Pinfile fixup failed");

		/* Set life cycle state to SC_FILE_STATUS_CREATION,
		 * which means that all ACs are ignored. */
		pinfile->status = SC_FILE_STATUS_CREATION;
		r = sc_create_file(p15card->card, pinfile);
		if (r < 0)
			sc_file_free(pinfile);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Pinfile creation failed");
	}
	sc_file_free(pinfile);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Select pinfile failed");

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
コード例 #9
0
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;
}
コード例 #10
0
static int parse_ddo(struct sc_pkcs15_card *p15card, const u8 * buf, size_t buflen)
{
	struct sc_asn1_entry asn1_ddo[5];
	sc_path_t odf_path, ti_path, us_path;
	int r;

	sc_copy_asn1_entry(c_asn1_ddo, asn1_ddo);
	sc_format_asn1_entry(asn1_ddo + 1, &odf_path, NULL, 0);
	sc_format_asn1_entry(asn1_ddo + 2, &ti_path, NULL, 0);
	sc_format_asn1_entry(asn1_ddo + 3, &us_path, NULL, 0);

	r = sc_asn1_decode(p15card->card->ctx, asn1_ddo, buf, buflen, NULL, NULL);
	if (r) {
		sc_error(p15card->card->ctx, "DDO parsing failed: %s\n",
		      sc_strerror(r));
		return r;
	}
	if (asn1_ddo[1].flags & SC_ASN1_PRESENT) {
		p15card->file_odf = sc_file_new();
		if (p15card->file_odf == NULL)
			goto mem_err;
		p15card->file_odf->path = odf_path;
	}
	if (asn1_ddo[2].flags & SC_ASN1_PRESENT) {
		p15card->file_tokeninfo = sc_file_new();
		if (p15card->file_tokeninfo == NULL)
			goto mem_err;
		p15card->file_tokeninfo->path = ti_path;
	}
	if (asn1_ddo[3].flags & SC_ASN1_PRESENT) {
		p15card->file_unusedspace = sc_file_new();
		if (p15card->file_unusedspace == NULL)
			goto mem_err;
		p15card->file_unusedspace->path = us_path;
	}
	return 0;
mem_err:
	if (p15card->file_odf != NULL) {
		sc_file_free(p15card->file_odf);
		p15card->file_odf = NULL;
	}
	if (p15card->file_tokeninfo != NULL) {
		sc_file_free(p15card->file_tokeninfo);
		p15card->file_tokeninfo = NULL;
	}
	if (p15card->file_unusedspace != NULL) {
		sc_file_free(p15card->file_unusedspace);
		p15card->file_unusedspace = NULL;
	}
	return SC_ERROR_OUT_OF_MEMORY;
}
コード例 #11
0
ファイル: card-entersafe.c プロジェクト: hongquan/OpenSC-main
static int entersafe_select_fid(sc_card_t *card,
								unsigned int id_hi, unsigned int id_lo,
								sc_file_t **file_out)
{
	int r;
	sc_file_t *file=0;
	sc_path_t path;

	memset(&path, 0, sizeof(sc_path_t));

	path.type=SC_PATH_TYPE_FILE_ID;
	path.value[0]=id_hi;
	path.value[1]=id_lo;
	path.len=2;

	r = iso_ops->select_file(card,&path,&file);
	if(r && file) 
	{
		if(file)
			sc_file_free(file);
	}
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");

	/* update cache */
	if (file->type == SC_FILE_TYPE_DF) {
		 card->cache.current_path.type = SC_PATH_TYPE_PATH;
		 card->cache.current_path.value[0] = 0x3f;
		 card->cache.current_path.value[1] = 0x00;
		 if (id_hi == 0x3f && id_lo == 0x00){
			  card->cache.current_path.len = 2;
		 }else{
			  card->cache.current_path.len = 4;
			  card->cache.current_path.value[2] = id_hi;
			  card->cache.current_path.value[3] = id_lo;
		 }
	}
	
	if (file_out)
	{
		 *file_out = file;
	}
	else
	{
		if(file)
			sc_file_free(file);
	}

	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
}
コード例 #12
0
ファイル: pkcs15-cflex.c プロジェクト: CendioOssman/OpenSC
/*
 * Create a new key file
 */
static int
cflex_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj)
{
	sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
	sc_file_t	*prkf = NULL, *pukf = NULL;
	size_t		size;
	int		r;

	if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
		sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Cryptoflex supports only RSA keys.");
		return SC_ERROR_NOT_SUPPORTED;
	}

	/* Get the public and private key file */
	r = cflex_get_keyfiles(profile, p15card->card,  &key_info->path, &prkf, &pukf);
	if (r < 0)
		return r;

	/* Adjust the file sizes, if necessary */
	switch (key_info->modulus_length) {
	case  512: size = 166; break;
	case  768: size = 246; break;
	case 1024: size = 326; break;
	case 2048: size = 646; break;
	default:
		sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported key size %u\n",
				key_info->modulus_length);
		r = SC_ERROR_INVALID_ARGUMENTS;
		goto out;
	}

	if (prkf->size < size)
		prkf->size = size;
	if (pukf->size < size + 4)
		pukf->size = size + 4;

	/* Now create the files */
	if ((r = sc_pkcs15init_create_file(profile, p15card, prkf)) < 0
	 || (r = sc_pkcs15init_create_file(profile, p15card, pukf)) < 0)
		goto out;

	key_info->key_reference = 0;

out:	if (prkf)
		sc_file_free(prkf);
	if (pukf)
		sc_file_free(pukf);
	return r;
}
コード例 #13
0
static int do_update_record(int argc, char **argv)
{
	u8 buf[240];
	size_t buflen;
	int r, i, err = 1;
	int rec, offs;
	sc_path_t path;
	sc_file_t *file;

	if (argc != 4)
		return usage(do_update_record);
	if (arg_to_path(argv[0], &path, 0) != 0)
		return usage(do_update_record);
	rec  = strtol(argv[1],NULL,10);
	offs = strtol(argv[2],NULL,10);

	printf("in: %i; %i; %s\n", rec, offs, argv[3]);

	r = sc_select_file(card, &path, &file);
	if (r) {
		check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file);
		return -1;
	}

	if (file->ef_structure != SC_FILE_EF_LINEAR_VARIABLE)   {
		printf("EF structure should be SC_FILE_EF_LINEAR_VARIABLE\n");
		goto err;
	} else if (rec < 1 || rec > file->record_count)   {
		printf("Invalid record number %i\n", rec);
		goto err;
	}

	r = sc_read_record(card, rec, buf, sizeof(buf), SC_RECORD_BY_REC_NR);
	if (r<0)   {
		printf("Cannot read record %i; return %i\n", rec, r);
		goto err;;
	}

	buflen = sizeof(buf) - offs;
	i = parse_string_or_hexdata(argv[3], buf + offs, &buflen);
	if (!i) {
		printf("unable to parse data\n");
		goto err;
	}

	r = sc_update_record(card, rec, buf, r, SC_RECORD_BY_REC_NR);
	if (r<0)   {
		printf("Cannot update record %i; return %i\n", rec, r);
		goto err;
	}

	printf("Total of %d bytes written to record %i at %i offset.\n", 
	       i, rec, offs);

	err = 0;
err:
	sc_file_free(file);
	select_current_path_or_die();
	return -err;
}
コード例 #14
0
ファイル: pkcs15-rtecp.c プロジェクト: DDvO/OpenSC
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;
}
コード例 #15
0
ファイル: pkcs15-miocos.c プロジェクト: pawmas/opensc
/*
 * Create private key file
 */
static int
miocos_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
		struct sc_pkcs15_object *object)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
	struct sc_file *file;
	int r;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
        	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys.");

	if (key_info->modulus_length != 1024)
        	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys.");

        sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create private key ID:%s\n",  sc_pkcs15_print_id(&key_info->id));
	r = miocos_new_file(profile, p15card->card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file);
        SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot create key: failed to allocate new key object");

        memcpy(&file->path, &key_info->path, sizeof(file->path));
        file->id = file->path.value[file->path.len - 2] * 0x100
			+ file->path.value[file->path.len - 1];

        sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Path of private key file to create %s\n", sc_print_path(&file->path));

	r = sc_pkcs15init_create_file(profile, p15card, file);
	sc_file_free(file);

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
コード例 #16
0
ファイル: pkcs15-myeid.c プロジェクト: BradPID/OpenSC
/*
 * Store a private key
 */
static int
myeid_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
		struct sc_pkcs15_object *object) {
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_card *card = p15card->card;
	struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *) object->data;
	struct sc_file *file = NULL;
	int keybits = key_info->modulus_length, r;

	LOG_FUNC_CALLED(card->ctx);

	/* Check that the card supports the requested modulus length */
	switch (object->type) {
		case SC_PKCS15_TYPE_PRKEY_RSA:
			if (sc_card_find_rsa_alg(p15card->card, keybits) == NULL)
				LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS,
					"Unsupported RSA key size");
			break;
		case SC_PKCS15_TYPE_PRKEY_EC:
			/* Here the information about curve is not available, that's why algorithm is checked
			   without curve OID. */
			if (sc_card_find_ec_alg(p15card->card, keybits, NULL) == NULL)
				LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported EC key size");
			break;
		default:
			LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS,
					"Unsupported key type");
			break;
	}

	sc_log(ctx, "create MyEID private key ID:%s", sc_pkcs15_print_id(&key_info->id));

	/* Get the private key file */
	r = myeid_new_file(profile, card, object->type, key_info->key_reference, &file);
	LOG_TEST_RET(ctx, r, "Cannot get new MyEID private key file");

	if (!file || !file->path.len)
		LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Cannot determine private key file");

	sc_log(ctx, "Key file size %d", keybits);
	file->size = keybits;

	if (object->type == SC_PKCS15_TYPE_PRKEY_RSA)
		file->ef_structure = SC_CARDCTL_MYEID_KEY_RSA;
	else if (object->type == SC_PKCS15_TYPE_PRKEY_EC)
		file->ef_structure = SC_CARDCTL_MYEID_KEY_EC;

	memcpy(&key_info->path.value, &file->path.value, file->path.len);
	key_info->key_reference = file->path.value[file->path.len - 1] & 0xFF;

	sc_log(ctx, "Path of MyEID private key file to create %s",
			sc_print_path(&file->path));

	/* Now create the key file */
	r = sc_pkcs15init_create_file(profile, p15card, file);
	sc_file_free(file);
	LOG_TEST_RET(ctx, r, "Cannot create MyEID private key file");

	LOG_FUNC_RETURN(ctx, r);
}
コード例 #17
0
ファイル: pkcs15-cflex.c プロジェクト: CendioOssman/OpenSC
/*
 * Get private and public key file
 */
static int cflex_get_keyfiles(sc_profile_t *profile, sc_card_t *card,
			const sc_path_t *df_path,
			sc_file_t **prkf, sc_file_t **pukf)
{
	sc_path_t	path = *df_path;
	int		r;

	/* Get the private key file */
	r = sc_profile_get_file_by_path(profile, &path, prkf);
	if (r < 0) {
		char pbuf[SC_MAX_PATH_STRING_SIZE];

		r = sc_path_print(pbuf, sizeof(pbuf), &path);
		if (r != SC_SUCCESS)
			pbuf[0] = '\0';

		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Cannot find private key file info "
				"in profile (path=%s).", pbuf);
		return r;
	}

	/* Get the public key file */
	path.len -= 2;
	sc_append_file_id(&path, 0x1012);
	r = sc_profile_get_file_by_path(profile, &path, pukf);
	if (r < 0) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Cannot find public key file info in profile.");
		sc_file_free(*prkf);
		return r;
	}

	return 0;
}
コード例 #18
0
ファイル: pkcs15-jcop.c プロジェクト: CendioOssman/OpenSC
/*
 * Store a private key
 * Private key file formats: (transparent file)
 * Non-CRT:
 * byte 0     0x05
 * byte 1     Modulus length (in byte/4)
 * byte 2     Modulus (n)
 * byte 2+x   private exponent (d)
 *
 * CRT:
 * byte 0     0x06
 * byte 1     component length (in byte/2; component length is half
 *            of modulus length
 * byte 2     Prime (p)
 * byte 2+x   Prime (q)
 * byte 2+2*x Exponent 1 (d mod (p-1))
 * byte 2+3*x Exponent 2 (d mod (q-1))
 * byte 2+4*x Coefficient ((p ^ -1) mod q
 *
 * We use the CRT format, since that's what key generation does.
 *
 * Numbers are stored big endian.
 */
static int
jcop_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
                sc_pkcs15_object_t *obj,
                sc_pkcs15_prkey_t *key)
{
        sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
        sc_file_t       *keyfile;
        unsigned char   keybuf[1024];
        size_t          size,base;
        int             r;

        if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
                sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "JCOP supports only RSA keys.");
                return SC_ERROR_NOT_SUPPORTED;
        }
        r = sc_profile_get_file_by_path(profile, &key_info->path, &keyfile);
        if (r < 0)
                return r;
	base=key_info->modulus_length / 16;
	size=2+5*base;
	keybuf[0]=6;
	keybuf[1]=base/4;
	jcop_bn2bin(&keybuf[2 + 0 * base], &key->u.rsa.p, base);
	jcop_bn2bin(&keybuf[2 + 1 * base], &key->u.rsa.q, base);
	jcop_bn2bin(&keybuf[2 + 2 * base], &key->u.rsa.dmp1, base);
	jcop_bn2bin(&keybuf[2 + 3 * base], &key->u.rsa.dmq1, base);
	jcop_bn2bin(&keybuf[2 + 4 * base], &key->u.rsa.iqmp, base);
        r = sc_pkcs15init_update_file(profile, p15card, keyfile, keybuf, size);

	sc_file_free(keyfile);
	return r;
}
コード例 #19
0
ファイル: pkcs15-gpk.c プロジェクト: Hubitronic/OpenSC
/*
 * Lock the pin file
 */
static int
gpk_lock_pinfile(struct sc_profile *profile, sc_pkcs15_card_t *p15card,
		sc_file_t *pinfile)
{
	struct sc_path	path;
	struct sc_file	*parent = NULL;
	int		r;

	SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
	/* Select the parent DF */
	path = pinfile->path;
	if (path.len >= 2)
		path.len -= 2;
	if (path.len == 0)
		sc_format_path("3F00", &path);
	if ((r = sc_select_file(p15card->card, &path, &parent)) < 0)
		return r;

	/* Present PINs etc as necessary */
	r = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_LOCK);
	if (r >= 0)
		r = gpk_lock(p15card->card, pinfile, SC_AC_OP_WRITE);

	sc_file_free(parent);
	SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r);
}
コード例 #20
0
ファイル: opensc-explorer.c プロジェクト: jpki/OpenSC
static int do_put(int argc, char **argv)
{
	u8 buf[256];
	int r, err = 1;
	size_t count = 0;
	unsigned int idx = 0;
	sc_path_t path;
	sc_file_t *file = NULL;
	const char *filename;
	FILE *outf = NULL;

	if (argc < 1 || argc > 2)
		return usage(do_put);
	if (arg_to_path(argv[0], &path, 0) != 0)
		return usage(do_put);

	filename = (argc == 2) ? argv[1] : path_to_filename(&path, '_');
	outf = fopen(filename, "rb");
	if (outf == NULL) {
		perror(filename);
		goto err;
	}
	r = sc_select_file(card, &path, &file);
	if (r) {
		check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file);
		goto err;
	}
	count = file->size;
	while (count) {
		int c = count > sizeof(buf) ? sizeof(buf) : count;

		r = fread(buf, 1, c, outf);
		if (r < 0) {
			perror("fread");
			goto err;
		}
		if (r != c)
			count = c = r;
		r = sc_update_binary(card, idx, buf, c, 0);
		if (r < 0) {
			check_ret(r, SC_AC_OP_READ, "update failed", file);
			goto err;
		}
		if (r != c) {
			printf("expecting %d, wrote only %d bytes.\n", c, r);
			goto err;
		}
		idx += c;
		count -= c;
	}
	printf("Total of %d bytes written.\n", idx);

	err = 0;
err:
	sc_file_free(file);
	if (outf)
		fclose(outf);
	select_current_path_or_die();
	return -err;
}
コード例 #21
0
ファイル: pkcs15-cflex.c プロジェクト: CendioOssman/OpenSC
/*
 * Card initialization.
 * For the cryptoflex, read the card's serial number from 3F00 0002
 */
static int
cryptoflex_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card)
{
	sc_path_t	path;
	sc_file_t	*file;
	u8		buf[32];
	char		serial[128];
	size_t		len;
	int		r;

	sc_format_path("3F000002", &path);
	if ((r = sc_select_file(p15card->card, &path, &file)) < 0) {
		if (r == SC_ERROR_FILE_NOT_FOUND)
			return 0;
		return r;
	}

	if ((len = file->size) > sizeof(buf))
		len = sizeof(buf);
	sc_file_free(file);
	if ((r = sc_read_binary(p15card->card, 0, buf, len, 0)) < 0)
		return r;
	len = r;
	if (len == 0)
		return 0;

	if ((r = sc_bin_to_hex(buf, len, serial, sizeof(serial), '\0')) < 0)
		return r;
	sc_pkcs15init_set_serial(profile, serial);
	return 0;
}
コード例 #22
0
ファイル: pkcs15-jcop.c プロジェクト: Hubitronic/OpenSC
/*
 * Create a new key file
 */
static int
jcop_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj)
{
        sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
        sc_file_t  *keyfile = NULL;
        size_t          bytes, mod_len, prv_len;
        int             r;

        if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
                sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "JCOP supports only RSA keys.");
                return SC_ERROR_NOT_SUPPORTED;
        }
        /* The caller is supposed to have chosen a key file path for us */
        if (key_info->path.len == 0 || key_info->modulus_length == 0)
                return SC_ERROR_INVALID_ARGUMENTS;

        /* Get the file we're supposed to create */
        r = sc_profile_get_file_by_path(profile, &key_info->path, &keyfile);
        if (r < 0)
                return r;

        mod_len = key_info->modulus_length / 8;
        bytes   = mod_len / 2;
        prv_len = 2 + 5 * bytes;
        keyfile->size = prv_len;

        /* Fix up PIN references in file ACL */
        r = sc_pkcs15init_fixup_file(profile, p15card, keyfile);

        if (r >= 0)
                r = sc_pkcs15init_create_file(profile, p15card, keyfile);

        sc_file_free(keyfile);
        return r;
}
コード例 #23
0
ファイル: pkcs15-syn.c プロジェクト: RaedChaabouni/OpenSC
static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card,
	unsigned int type)
{
	sc_pkcs15_df_t	*df;
	sc_file_t	*file;
	int		created = 0;

	while (1) {
		for (df = p15card->df_list; df; df = df->next) {
			if (df->type == type) {
				if (created)
					df->enumerated = 1;
				return df;
			}
		}

		assert(created == 0);

		file = sc_file_new();
		if (!file)
			return NULL;
		sc_format_path("11001101", &file->path);
		sc_pkcs15_add_df(p15card, type, &file->path);
		sc_file_free(file);
		created++;
	}
}
コード例 #24
0
ファイル: pkcs15-cardos.c プロジェクト: jpki/OpenSC
/*
 * Object deletion.
 */
static int
cardos_delete_object(sc_profile_t *profile, struct sc_pkcs15_card *p15card,
		struct sc_pkcs15_object *obj, const struct sc_path *path)
{
	int r = SC_SUCCESS, stored_in_ef = 0, algorithm = 0;
	size_t keybits;
	sc_file_t *file = NULL;
	struct sc_pkcs15_prkey_info *key_info;
	struct sc_pkcs15_prkey_rsa key_obj;
	struct sc_context *ctx = p15card->card->ctx;
	uint8_t abignum[256];

	LOG_FUNC_CALLED(ctx);
	/*
	 * If we are deleting a private key, overwrite it so it can't be used.
	 */
	if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY) {
		key_info = obj->data;
		keybits = key_info->modulus_length & ~7UL;
		init_key_object(&key_obj, abignum, keybits >> 3);
		r = cardos_key_algorithm(key_info->usage, keybits, &algorithm);
		LOG_TEST_RET(ctx, r, "cardos_key_algorithm failed");

		r = sc_select_file(p15card->card, &key_info->path, &file);
		LOG_TEST_RET(ctx, r, "Failed to store key: cannot select parent DF");

		r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
		sc_file_free(file);
		LOG_TEST_RET(ctx, r, "Failed to store key: UPDATE authentication failed");

		r = cardos_put_key(profile, p15card, algorithm, key_info, &key_obj);
		LOG_TEST_RET(ctx, r, "cardos_put_key failed");
	}
コード例 #25
0
static int do_create(int argc, char **argv)
{
	sc_path_t path;
	sc_file_t *file;
	unsigned int size;
	int r, op;

	if (argc != 2)
		return usage(do_create);
	if (arg_to_path(argv[0], &path, 1) != 0)
		return usage(do_create);
	/* %z isn't supported everywhere */
	if (sscanf(argv[1], "%u", &size) != 1)
		return usage(do_create);
	file = sc_file_new();
	file->id = (path.value[0] << 8) | path.value[1];
	file->type = SC_FILE_TYPE_WORKING_EF;
	file->ef_structure = SC_FILE_EF_TRANSPARENT;
	file->size = (size_t) size;
	file->status = SC_FILE_STATUS_ACTIVATED;
	for (op = 0; op < SC_MAX_AC_OPS; op++)
		sc_file_add_acl_entry(file, op, SC_AC_NONE, 0);

	r = create_file(file);
	sc_file_free(file);
	return r;
}
コード例 #26
0
/*
 * Lock the pin file
 */
static int
gpk_lock_pinfile(struct sc_profile *profile, sc_card_t *card,
                 sc_file_t *pinfile)
{
    struct sc_path	path;
    struct sc_file	*parent = NULL;
    int		r;

    /* Select the parent DF */
    path = pinfile->path;
    if (path.len >= 2)
        path.len -= 2;
    if (path.len == 0)
        sc_format_path("3F00", &path);
    if ((r = sc_select_file(card, &path, &parent)) < 0)
        return r;

    /* Present PINs etc as necessary */
    r = sc_pkcs15init_authenticate(profile, card, parent, SC_AC_OP_LOCK);
    if (r >= 0)
        r = gpk_lock(card, pinfile, SC_AC_OP_WRITE);

    sc_file_free(parent);
    return r;
}
コード例 #27
0
static int do_mkdir(int argc, char **argv)
{
	sc_path_t path;
	sc_file_t *file;
	unsigned int size;
	int r, op;

	if (argc != 2)
		return usage(do_mkdir);
	if (arg_to_path(argv[0], &path, 1) != 0)
		return usage(do_mkdir);
	if (sscanf(argv[1], "%u", &size) != 1)
		return usage(do_mkdir);
	file = sc_file_new();
	file->id = (path.value[0] << 8) | path.value[1];
	file->type = SC_FILE_TYPE_DF;
	file->size = size;
	file->status = SC_FILE_STATUS_ACTIVATED;
	for (op = 0; op < SC_MAX_AC_OPS; op++)
		sc_file_add_acl_entry(file, op, SC_AC_NONE, 0);

	r = create_file(file);
	sc_file_free(file);
	return r;
}
コード例 #28
0
ファイル: pkcs15-cflex.c プロジェクト: CendioOssman/OpenSC
static int
cflex_delete_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df)
{
        sc_path_t  path;
        sc_file_t  *parent;
        int             r = 0;
        /* Select the parent DF */
        path = df->path;
        path.len -= 2;
        r = sc_select_file(p15card->card, &path, &parent);
        if (r < 0)
                return r;

        r = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_DELETE);
        sc_file_free(parent);
        if (r < 0)
                return r;

	/* cryptoflex has no ERASE AC */
        memset(&path, 0, sizeof(path));
        path.type = SC_PATH_TYPE_FILE_ID;
        path.value[0] = df->id >> 8;
        path.value[1] = df->id & 0xFF;
        path.len = 2;

	r = sc_delete_file(p15card->card, &path);
	return r;
}
コード例 #29
0
ファイル: pkcs15-entersafe.c プロジェクト: securez/opendnie
static int entersafe_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
							   sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key)
{
	sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data;
	sc_card_t *card = p15card->card;
	sc_entersafe_wkey_data data;
	sc_file_t              *tfile;
	const sc_acl_entry_t   *acl_entry;
	int r;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	if (key->algorithm != SC_ALGORITHM_RSA)
		 /* ignore DSA keys */
		 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS);

	r = sc_profile_get_file(profile, "PKCS15-AODF", &tfile);
	if (r < 0)
		 return r;
	acl_entry = sc_file_get_acl_entry(tfile, SC_AC_OP_UPDATE);
	if (acl_entry->method  != SC_AC_NONE) {
		 r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_UPDATE);
		 if(r<0)
			  r = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
	}
	sc_file_free(tfile);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "cant verify pin");

	data.key_id = (u8) kinfo->key_reference;
	data.usage=0x22;
	data.key_data.rsa=&key->u.rsa;
	return sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
}
コード例 #30
0
/*
 * Create the PK file
 * XXX: Handle the UPDATE ACL = NEVER case just like for EFsc files
 */
static int
gpk_pkfile_create(sc_profile_t *profile, sc_card_t *card, sc_file_t *file)
{
    struct sc_file	*found = NULL;
    int		r;

    sc_ctx_suppress_errors_on(card->ctx);
    r = sc_select_file(card, &file->path, &found);
    sc_ctx_suppress_errors_off(card->ctx);
    if (r == SC_ERROR_FILE_NOT_FOUND) {
        r = sc_pkcs15init_create_file(profile, card, file);
        if (r >= 0)
            r = sc_select_file(card, &file->path, &found);
    } else {
        /* XXX: make sure the file has correct type and size? */
    }

    if (r >= 0)
        r = sc_pkcs15init_authenticate(profile, card,
                                       file, SC_AC_OP_UPDATE);
    if (found)
        sc_file_free(found);

    return r;
}