Commit message: fixed out of bounds writes

Thanks to Eric Sesterhenn from X41 D-SEC GmbH
for reporting the problems.
CVE: CVE-2018-16420
CWE: CWE-415
Vulnerability description: Several buffer overflows when handling responses from an ePass 2003 Card in decrypt_response in libopensc/card-epass2003.c in OpenSC before 0.19.0-rc1 could be used by attackers able to supply crafted smartcards to cause a denial of service (application crash) or possibly have unspecified other impact.

Project: OpenSC
File: card-cac.c

static int cac_select_file(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out)
{
	return cac_select_file_by_type(card, in_path, file_out, card->type);
}

Project: OpenSC
File: card-cac.c

static int cac_rsa_op(sc_card_t *card,
					const u8 * data, size_t datalen,
					u8 * out, size_t outlen)
{
	int r;
	u8 *outp, *rbuf;
	size_t rbuflen, outplen;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
		 "datalen=%"SC_FORMAT_LEN_SIZE_T"u outlen=%"SC_FORMAT_LEN_SIZE_T"u\n",
		 datalen, outlen);

	outp = out;
	outplen = outlen;

	/* Not strictly necessary. This code requires the caller to have selected the correct PKI container
	 * and authenticated to that container with the verifyPin command... All of this under the reader lock.
	 * The PKCS #15 higher level driver code does all this correctly (it's the same for all cards, just
	 * different sets of APDU's that need to be called), so this call is really a little bit of paranoia */
	r = sc_lock(card);
	if (r != SC_SUCCESS)
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);


	rbuf = NULL;
	rbuflen = 0;
	for (; datalen > CAC_MAX_CHUNK_SIZE; data += CAC_MAX_CHUNK_SIZE, datalen -= CAC_MAX_CHUNK_SIZE) {
		r = cac_apdu_io(card, CAC_INS_SIGN_DECRYPT, CAC_P1_STEP,  0,
			data, CAC_MAX_CHUNK_SIZE, &rbuf, &rbuflen);
		if (r < 0) {
			break;
		}
		if (rbuflen != 0) {
			int n = MIN(rbuflen, outplen);
			memcpy(outp,rbuf, n);
			outp += n;
			outplen -= n;
		}
		free(rbuf);
		rbuf = NULL;
		rbuflen = 0;
	}
	if (r < 0) {
		goto err;
	}
	rbuf = NULL;
	rbuflen = 0;
	r = cac_apdu_io(card, CAC_INS_SIGN_DECRYPT, CAC_P1_FINAL, 0, data, datalen, &rbuf, &rbuflen);
	if (r < 0) {
		goto err;
	}
	if (rbuflen != 0) {
		int n = MIN(rbuflen, outplen);
		memcpy(outp,rbuf, n);
		/*outp += n;     unused */
		outplen -= n;
	}
	free(rbuf);
	rbuf = NULL;
	r = outlen-outplen;

err:
	sc_unlock(card);
	if (r < 0) {
		sc_mem_clear(out, outlen);
	}
	if (rbuf) {
		free(rbuf);
	}

	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
}

Project: OpenSC
File: card-tcos.c

static int tcos_create_file(sc_card_t *card, sc_file_t *file)
{
	int r;
	size_t len;
	u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
	sc_apdu_t apdu;

	len = SC_MAX_APDU_BUFFER_SIZE;
	r = tcos_construct_fci(file, sbuf, &len);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "tcos_construct_fci() failed");
	
	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00);
        apdu.cla |= 0x80;  /* this is an proprietary extension */
	apdu.lc = len;
	apdu.datalen = len;
	apdu.data = sbuf;

	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
	return sc_check_sw(card, apdu.sw1, apdu.sw2);
}

Project: OpenSC
File: card-muscle.c

static int muscle_set_security_env(sc_card_t *card,
				 const sc_security_env_t *env,
				 int se_num)
{
	muscle_private_t* priv = MUSCLE_DATA(card);

	if (env->operation != SC_SEC_OPERATION_SIGN &&
	    env->operation != SC_SEC_OPERATION_DECIPHER) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid crypto operation supplied.\n");
		return SC_ERROR_NOT_SUPPORTED;
	}
	if (env->algorithm != SC_ALGORITHM_RSA) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid crypto algorithm supplied.\n");
		return SC_ERROR_NOT_SUPPORTED;
	}
	/* ADJUST FOR PKCS1 padding support for decryption only */
	if ((env->algorithm_flags & SC_ALGORITHM_RSA_PADS) ||
	    (env->algorithm_flags & SC_ALGORITHM_RSA_HASHES)) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Card supports only raw RSA.\n");
		return SC_ERROR_NOT_SUPPORTED;
	}
	if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) {
		if (env->key_ref_len != 1 ||
		    (env->key_ref[0] > 0x0F)) {
			sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid key reference supplied.\n");
			return SC_ERROR_NOT_SUPPORTED;
		}
		priv->rsa_key_ref = env->key_ref[0];
	}
	if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Algorithm reference not supported.\n");
		return SC_ERROR_NOT_SUPPORTED;
	}
	/* if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT)
		if (memcmp(env->file_ref.value, "\x00\x12", 2) != 0) {
			sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File reference is not 0012.\n");
			return SC_ERROR_NOT_SUPPORTED;
		} */
	priv->env = *env;
	return 0;
}

Project: OpenSC
File: sc.c

int sc_mutex_lock(const sc_context_t *ctx, void *mutex)
{
	if (ctx == NULL)
		return SC_ERROR_INVALID_ARGUMENTS;
	if (ctx->thread_ctx != NULL && ctx->thread_ctx->lock_mutex != NULL)
		return ctx->thread_ctx->lock_mutex(mutex);
	else
		return SC_SUCCESS;
}

Project: OpenSC
File: card-epass2003.c

epass2003_sm_free_wrapped_apdu(struct sc_card *card,
		struct sc_apdu *plain, struct sc_apdu **sm_apdu)
{
	struct sc_context *ctx = card->ctx;
	int rv = SC_SUCCESS;

	LOG_FUNC_CALLED(ctx);
	if (!sm_apdu)
		LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
	if (!(*sm_apdu))
		LOG_FUNC_RETURN(ctx, SC_SUCCESS);


	if (plain)
		rv = epass2003_sm_unwrap_apdu(card, *sm_apdu, plain);

	if ((*sm_apdu)->data) {
		unsigned char * p = (unsigned char *)((*sm_apdu)->data);
		free(p);
	}
	if ((*sm_apdu)->resp) {
		free((*sm_apdu)->resp);
	}

	free(*sm_apdu);
	*sm_apdu = NULL;

	LOG_FUNC_RETURN(ctx, rv);
}

Project: OpenSC
File: card-muscle.c

static int _listFile(mscfs_file_t *file, int reset, void *udata)
{
	int next = reset ? 0x00 : 0x01;
	return msc_list_objects( (sc_card_t*)udata, next, file);
}

Project: OpenSC
File: card-muscle.c

static unsigned short muscle_parse_singleAcl(const sc_acl_entry_t* acl)
{
	unsigned short acl_entry = 0;
	while(acl) {
		int key = acl->key_ref;
		int method = acl->method;
		switch(method) {
		case SC_AC_NEVER:
			return 0xFFFF;
		/* Ignore... other items overwrite these */
		case SC_AC_NONE:
		case SC_AC_UNKNOWN:
			break;
		case SC_AC_CHV:
			acl_entry |= (1 << key); /* Assuming key 0 == SO */
			break;
		case SC_AC_AUT:
		case SC_AC_TERM:
		case SC_AC_PRO:
		default:
			/* Ignored */
			break;
		}
		acl = acl->next;
	}
	return acl_entry;
}

Project: OpenSC
File: card-muscle.c

static int muscle_card_reader_lock_obtained(sc_card_t *card, int was_reset)
{
	int r = SC_SUCCESS;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	if (was_reset > 0) {
		if (msc_select_applet(card, muscleAppletId, sizeof muscleAppletId) != 1) {
			r = SC_ERROR_INVALID_CARD;
		}
	}

	LOG_FUNC_RETURN(card->ctx, r);
}

Project: OpenSC
File: sc.c

int sc_append_path(sc_path_t *dest, const sc_path_t *src)
{
	return sc_concatenate_path(dest, dest, src);
}

Project: OpenSC
File: cryptoflex-tool.c

static int generate_key(void)
{
	sc_apdu_t apdu;
	u8 sbuf[4];
	u8 p2;
	int r;

	switch (opt_mod_length) {
	case 512:
		p2 = 0x40;
		break;
	case 768:
		p2 = 0x60;
		break;
	case 1024:
		p2 = 0x80;
		break;
	case 2048:
		p2 = 0x00;
		break;
	default:
		fprintf(stderr, "Invalid modulus length.\n");
		return 2;
	}
	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, (u8) opt_key_num-1, p2);
	apdu.cla = 0xF0;
	apdu.lc = 4;
	apdu.datalen = 4;
	apdu.data = sbuf;
	sbuf[0] = opt_exponent & 0xFF;
	sbuf[1] = (opt_exponent >> 8) & 0xFF;
	sbuf[2] = (opt_exponent >> 16) & 0xFF;
	sbuf[3] = (opt_exponent >> 24) & 0xFF;
	r = select_app_df();
	if (r)
		return 1;
	if (verbose)
		printf("Generating key...\n");
	r = sc_transmit_apdu(card, &apdu);
	if (r) {
		fprintf(stderr, "APDU transmit failed: %s\n", sc_strerror(r));
		if (r == SC_ERROR_TRANSMIT_FAILED)
			fprintf(stderr, "Reader has timed out. It is still possible that the key generation has\n"
					"succeeded.\n");
		return 1;
	}
	if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
		printf("Key generation successful.\n");
		return 0;
	}
	if (apdu.sw1 == 0x69 && apdu.sw2 == 0x82)
		fprintf(stderr, "CHV1 not verified or invalid exponent value.\n");
	else
		fprintf(stderr, "Card returned SW1=%02X, SW2=%02X.\n", apdu.sw1, apdu.sw2);
	return 1;
}

Project: OpenSC
File: sc.c

void sc_remote_data_init(struct sc_remote_data *rdata)
{
	if (!rdata)
		return;
	memset(rdata, 0, sizeof(struct sc_remote_data));

	rdata->alloc = sc_remote_apdu_allocate;
	rdata->free = sc_remote_apdu_free;
}

Project: OpenSC
File: card-epass2003.c

encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm,
		unsigned char *apdu_buf, size_t * apdu_buf_len)
{
	size_t block_size = 0;
	unsigned char dataTLV[4096] = { 0 };
	size_t data_tlv_len = 0;
	unsigned char le_tlv[256] = { 0 };
	size_t le_tlv_len = 0;
	size_t mac_tlv_len = 10;
	size_t tmp_lc = 0;
	size_t tmp_le = 0;
	unsigned char mac_tlv[256] = { 0 };
	epass2003_exdata *exdata = NULL;

	mac_tlv[0] = 0x8E;
	mac_tlv[1] = 8;
	/* size_t plain_le = 0; */
	if (!card->drv_data) 
		return SC_ERROR_INVALID_ARGUMENTS;
	exdata = (epass2003_exdata*)card->drv_data;
	block_size = (KEY_TYPE_DES == exdata->smtype ? 16 : 8);

	sm->cse = SC_APDU_CASE_4_SHORT;
	apdu_buf[0] = (unsigned char)plain->cla;
	apdu_buf[1] = (unsigned char)plain->ins;
	apdu_buf[2] = (unsigned char)plain->p1;
	apdu_buf[3] = (unsigned char)plain->p2;
	/* plain_le = plain->le; */
	/* padding */
	apdu_buf[4] = 0x80;
	memset(&apdu_buf[5], 0x00, block_size - 5);

	/* Data -> Data' */
	if (plain->lc != 0)
		if (0 != construct_data_tlv(card, plain, apdu_buf, dataTLV, &data_tlv_len, exdata->smtype))
			return -1;

	if (plain->le != 0 || (plain->le == 0 && plain->resplen != 0))
		if (0 != construct_le_tlv(plain, apdu_buf, data_tlv_len, le_tlv,
				     &le_tlv_len, exdata->smtype))
			return -1;

	if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype))
		return -1;

	memset(apdu_buf + 4, 0, *apdu_buf_len - 4);
	sm->lc = sm->datalen = data_tlv_len + le_tlv_len + mac_tlv_len;
	if (sm->lc > 0xFF) {
		sm->cse = SC_APDU_CASE_4_EXT;
		apdu_buf[4] = (unsigned char)((sm->lc) / 0x10000);
		apdu_buf[5] = (unsigned char)(((sm->lc) / 0x100) % 0x100);
		apdu_buf[6] = (unsigned char)((sm->lc) % 0x100);
		tmp_lc = 3;
	}
	else {
		apdu_buf[4] = (unsigned char)sm->lc;
		tmp_lc = 1;
	}

	memcpy(apdu_buf + 4 + tmp_lc, dataTLV, data_tlv_len);
	memcpy(apdu_buf + 4 + tmp_lc + data_tlv_len, le_tlv, le_tlv_len);
	memcpy(apdu_buf + 4 + tmp_lc + data_tlv_len + le_tlv_len, mac_tlv, mac_tlv_len);
	memcpy((unsigned char *)sm->data, apdu_buf + 4 + tmp_lc, sm->datalen);
	*apdu_buf_len = 0;

	if (4 == le_tlv_len) {
		sm->cse = SC_APDU_CASE_4_EXT;
		*(apdu_buf + 4 + tmp_lc + sm->lc) = (unsigned char)(plain->le / 0x100);
		*(apdu_buf + 4 + tmp_lc + sm->lc + 1) = (unsigned char)(plain->le % 0x100);
		tmp_le = 2;
	}
	else if (3 == le_tlv_len) {
		*(apdu_buf + 4 + tmp_lc + sm->lc) = (unsigned char)plain->le;
		tmp_le = 1;
	}

	*apdu_buf_len += 4 + tmp_lc + data_tlv_len + le_tlv_len + mac_tlv_len + tmp_le;
	/* sm->le = calc_le(plain_le); */
	return 0;
}

Project: OpenSC
File: card-cac.c

static int cac_is_cert(cac_private_data_t * priv, const sc_path_t *in_path)
{
	cac_object_t test_obj;
	test_obj.path = *in_path;
	test_obj.path.index = 0;
	test_obj.path.count = 0;

	return (list_contains(&priv->pki_list, &test_obj) != 0);
}

Project: OpenSC
File: card-cac.c

static int cac_decipher(sc_card_t *card,
					 const u8 * data, size_t datalen,
					 u8 * out, size_t outlen)
{
	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, cac_rsa_op(card, data, datalen, out, outlen));
}

Project: OpenSC
File: card-muscle.c

static int muscle_create_file(sc_card_t *card, sc_file_t *file)
{
	mscfs_t *fs = MUSCLE_FS(card);
	int objectSize = file->size;
	unsigned short read_perm = 0, write_perm = 0, delete_perm = 0;
	msc_id objectId;
	int r;
	if(file->type == SC_FILE_TYPE_DF)
		return muscle_create_directory(card, file);
	if(file->type != SC_FILE_TYPE_WORKING_EF)
		return SC_ERROR_NOT_SUPPORTED;
	if(file->id == 0) /* No null name files */
		return SC_ERROR_INVALID_ARGUMENTS;

	muscle_parse_acls(file, &read_perm, &write_perm, &delete_perm);

	mscfs_lookup_local(fs, file->id, &objectId);
	r = msc_create_object(card, objectId, objectSize, read_perm, write_perm, delete_perm);
	mscfs_clear_cache(fs);
	if(r >= 0) return 0;
	return r;
}

Project: OpenSC
File: card-epass2003.c

epass2003_select_path(struct sc_card *card, const u8 pathbuf[16], const size_t len,
		sc_file_t ** file_out)
{
	u8 n_pathbuf[SC_MAX_PATH_SIZE];
	const u8 *path = pathbuf;
	size_t pathlen = len;
	int bMatch = -1;
	unsigned int i;
	int r;

	if (pathlen % 2 != 0 || pathlen > 6 || pathlen <= 0)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);

	/* if pathlen == 6 then the first FID must be MF (== 3F00) */
	if (pathlen == 6 && (path[0] != 0x3f || path[1] != 0x00))
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);

	/* unify path (the first FID should be MF) */
	if (path[0] != 0x3f || path[1] != 0x00) {
		n_pathbuf[0] = 0x3f;
		n_pathbuf[1] = 0x00;

		for (i = 0; i < pathlen; i++)
			n_pathbuf[i + 2] = pathbuf[i];
		path = n_pathbuf;
		pathlen += 2;
	}

	/* check current working directory */
	if (card->cache.valid
			&& card->cache.current_path.type == SC_PATH_TYPE_PATH
			&& card->cache.current_path.len >= 2
			&& card->cache.current_path.len <= pathlen) {
		bMatch = 0;
		for (i = 0; i < card->cache.current_path.len; i += 2)
			if (card->cache.current_path.value[i] == path[i]
					&& card->cache.current_path.value[i + 1] == path[i + 1])
				bMatch += 2;
	}

	if (card->cache.valid && bMatch > 2) {
		if (pathlen - bMatch == 2) {
			/* we are in the right directory */
			return epass2003_select_fid(card, path[bMatch], path[bMatch + 1], file_out);
		}
		else if (pathlen - bMatch > 2) {
			/* two more steps to go */
			sc_path_t new_path;

			/* first step: change directory */
			r = epass2003_select_fid(card, path[bMatch], path[bMatch + 1], NULL);
			LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed");

			new_path.type = SC_PATH_TYPE_PATH;
			new_path.len = pathlen - bMatch - 2;
			memcpy(new_path.value, &(path[bMatch + 2]), new_path.len);

			/* final step: select file */
			return epass2003_select_file(card, &new_path, file_out);
		}
		else {	/* if (bMatch - pathlen == 0) */

			/* done: we are already in the
			 * requested directory */
			sc_log(card->ctx, "cache hit\n");
			/* copy file info (if necessary) */
			if (file_out) {
				sc_file_t *file = sc_file_new();
				if (!file)
					LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
				file->id = (path[pathlen - 2] << 8) + path[pathlen - 1];
				file->path = card->cache.current_path;
				file->type = SC_FILE_TYPE_DF;
				file->ef_structure = SC_FILE_EF_UNKNOWN;
				file->size = 0;
				file->namelen = 0;
				file->magic = SC_FILE_MAGIC;
				*file_out = file;
			}
			/* nothing left to do */
			return SC_SUCCESS;
		}
	}
	else {
		/* no usable cache */
		for (i = 0; i < pathlen - 2; i += 2) {
			r = epass2003_select_fid(card, path[i], path[i + 1], NULL);
			LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed");
		}

		return epass2003_select_fid(card, path[pathlen - 2], path[pathlen - 1], file_out);
	}
}

Project: OpenSC
File: util.c

is_string_valid_atr(const char *atr_str)
{
	unsigned char atr[SC_MAX_ATR_SIZE];
	size_t atr_len = sizeof(atr);

	if (sc_hex_to_bin(atr_str, atr, &atr_len))
		return 0;
	if (atr_len < 2)
		return 0;
	if (atr[0] != 0x3B && atr[0] != 0x3F)
		return 0;
	return 1;
}

Project: OpenSC
File: card-epass2003.c

epass2003_select_fid_(struct sc_card *card, sc_path_t * in_path, sc_file_t ** file_out)
{
	struct sc_apdu apdu;
	u8 buf[SC_MAX_APDU_BUFFER_SIZE] = { 0 };
	u8 pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf;
	int r, pathlen;
	sc_file_t *file = NULL;

	epass2003_hook_path(in_path, 1);
	memcpy(path, in_path->value, in_path->len);
	pathlen = in_path->len;

	sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x00, 0x00);

	switch (in_path->type) {
	case SC_PATH_TYPE_FILE_ID:
		apdu.p1 = 0;
		if (pathlen != 2)
			return SC_ERROR_INVALID_ARGUMENTS;
		break;
	default:
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
	}
	apdu.p2 = 0;		/* first record, return FCI */
	apdu.lc = pathlen;
	apdu.data = path;
	apdu.datalen = pathlen;

	if (file_out != NULL) {
		apdu.resp = buf;
		apdu.resplen = sizeof(buf);
		apdu.le = 0;
	}
	else   {
		apdu.cse = (apdu.lc == 0) ? SC_APDU_CASE_1 : SC_APDU_CASE_3_SHORT;
	}

	if (path[0] == 0x29) {	/* TODO:0x29 accords with FID prefix in profile  */
		/* Not allowed to select private key file, so fake fci. */
		/* 62 16 82 02 11 00 83 02 29 00 85 02 08 00 86 08 FF 90 90 90 FF FF FF FF */
		apdu.resplen = 0x18;
		memcpy(apdu.resp,
		       "\x6f\x16\x82\x02\x11\x00\x83\x02\x29\x00\x85\x02\x08\x00\x86\x08\xff\x90\x90\x90\xff\xff\xff\xff",
		       apdu.resplen);
		apdu.resp[9] = path[1];
		apdu.sw1 = 0x90;
		apdu.sw2 = 0x00;
	}
	else {
		r = sc_transmit_apdu_t(card, &apdu);
		LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
	}

	if (file_out == NULL) {
		if (apdu.sw1 == 0x61)
			LOG_FUNC_RETURN(card->ctx, 0);
		LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
	}

	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	if (r)
		LOG_FUNC_RETURN(card->ctx, r);
	if (apdu.resplen < 2)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);

	switch (apdu.resp[0]) {
	case 0x6F:
		file = sc_file_new();
		if (file == NULL)
			LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
		file->path = *in_path;
		if (card->ops->process_fci == NULL) {
			sc_file_free(file);
			LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
		}

		if ((size_t) apdu.resp[1] + 2 <= apdu.resplen)
			card->ops->process_fci(card, file, apdu.resp + 2, apdu.resp[1]);
		epass2003_hook_file(file, 0);
		*file_out = file;
		break;
	case 0x00:		/* proprietary coding */
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
		break;
	default:
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
	}
	return 0;
}

Project: OpenSC
File: card-epass2003.c

des3_encrypt_ecb(const unsigned char *key, int keysize,
		const unsigned char *input, int length, unsigned char *output)
{
	unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 };
	unsigned char bKey[24] = { 0 };

	if (keysize == 16) {
		memcpy(&bKey[0], key, 16);
		memcpy(&bKey[16], key, 8);
	}
	else {
		memcpy(&bKey[0], key, 24);
	}

	return openssl_enc(EVP_des_ede3(), bKey, iv, input, length, output);
}

Project: OpenSC
File: pkcs15-sc-hsm.c

void sc_pkcs15emu_sc_hsm_free_cvc(sc_cvc_t *cvc)
{
	if (cvc->signature) {
		free(cvc->signature);
		cvc->signature = NULL;
	}
	if (cvc->primeOrModulus) {
		free(cvc->primeOrModulus);
		cvc->primeOrModulus = NULL;
	}
	if (cvc->coefficientAorExponent) {
		free(cvc->coefficientAorExponent);
		cvc->coefficientAorExponent = NULL;
	}
	if (cvc->coefficientB) {
		free(cvc->coefficientB);
		cvc->coefficientB = NULL;
	}
	if (cvc->basePointG) {
		free(cvc->basePointG);
		cvc->basePointG = NULL;
	}
	if (cvc->order) {
		free(cvc->order);
		cvc->order = NULL;
	}
	if (cvc->publicPoint) {
		free(cvc->publicPoint);
		cvc->publicPoint = NULL;
	}
	if (cvc->cofactor) {
		free(cvc->cofactor);
		cvc->cofactor = NULL;
	}
}

Project: OpenSC
File: card-cac.c

static int cac_final_iterator(list_t *list)
{
	list_iterator_stop(list);
	return SC_SUCCESS;
}

Project: OpenSC
File: card-epass2003.c

static int epass2003_match_card(struct sc_card *card)
{
	int r;

	LOG_FUNC_CALLED(card->ctx);
	r = _sc_match_atr(card, epass2003_atrs, &card->type);
	if (r < 0)
		return 0;

	return 1;
}

Project: OpenSC
File: pkcs15-sc-hsm.c

static int sc_pkcs15emu_sc_hsm_add_pubkey(sc_pkcs15_card_t *p15card, u8 *efbin, size_t len, sc_pkcs15_prkey_info_t *key_info, char *label)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_card_t *card = p15card->card;
	sc_pkcs15_pubkey_info_t pubkey_info;
	sc_pkcs15_object_t pubkey_obj;
	struct sc_pkcs15_pubkey pubkey;
	sc_cvc_t cvc;
	u8 *cvcpo;
	int r;

	cvcpo = efbin;

	memset(&cvc, 0, sizeof(cvc));
	r = sc_pkcs15emu_sc_hsm_decode_cvc(p15card, (const u8 **)&cvcpo, &len, &cvc);
	LOG_TEST_RET(ctx, r, "Could decode certificate signing request");

	memset(&pubkey, 0, sizeof(pubkey));
	r = sc_pkcs15emu_sc_hsm_get_public_key(ctx, &cvc, &pubkey);
	LOG_TEST_RET(card->ctx, r, "Could not extract public key");

	memset(&pubkey_info, 0, sizeof(pubkey_info));
	memset(&pubkey_obj, 0, sizeof(pubkey_obj));

	r = sc_pkcs15_encode_pubkey(ctx, &pubkey, &pubkey_obj.content.value, &pubkey_obj.content.len);
	LOG_TEST_RET(ctx, r, "Could not encode public key");
	r = sc_pkcs15_encode_pubkey(ctx, &pubkey, &pubkey_info.direct.raw.value, &pubkey_info.direct.raw.len);
	LOG_TEST_RET(ctx, r, "Could not encode public key");
	r = sc_pkcs15_encode_pubkey_as_spki(ctx, &pubkey, &pubkey_info.direct.spki.value, &pubkey_info.direct.spki.len);
	LOG_TEST_RET(ctx, r, "Could not encode public key");

	pubkey_info.id = key_info->id;
	strlcpy(pubkey_obj.label, label, sizeof(pubkey_obj.label));

	if (pubkey.algorithm == SC_ALGORITHM_RSA) {
		pubkey_info.modulus_length = pubkey.u.rsa.modulus.len << 3;
		pubkey_info.usage = SC_PKCS15_PRKEY_USAGE_ENCRYPT|SC_PKCS15_PRKEY_USAGE_VERIFY|SC_PKCS15_PRKEY_USAGE_WRAP;
		r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
	} else {
		/* TODO fix if support of non multiple of 8 curves are added */
		pubkey_info.field_length = cvc.primeOrModuluslen << 3;
		pubkey_info.usage = SC_PKCS15_PRKEY_USAGE_VERIFY;
		r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info);
	}
	LOG_TEST_RET(ctx, r, "Could not add public key");

	sc_pkcs15emu_sc_hsm_free_cvc(&cvc);
	sc_pkcs15_erase_pubkey(&pubkey);

	return SC_SUCCESS;
}

Project: OpenSC
File: card-muscle.c

static int muscle_restore_security_env(sc_card_t *card, int se_num)
{
	muscle_private_t* priv = MUSCLE_DATA(card);
	memset(&priv->env, 0, sizeof(priv->env));
	return 0;
}

Project: OpenSC
File: card-tcos.c

static int tcos_select_file(sc_card_t *card,
			    const sc_path_t *in_path,
			    sc_file_t **file_out)
{
	sc_context_t *ctx;
	sc_apdu_t apdu;
	sc_file_t *file=NULL;
	u8 buf[SC_MAX_APDU_BUFFER_SIZE], pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf;
	unsigned int i;
	int r, pathlen;

	assert(card != NULL && in_path != NULL);
	ctx=card->ctx;
	memcpy(path, in_path->value, in_path->len);
	pathlen = in_path->len;

	sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0, 0x04);
	
	switch (in_path->type) {
	case SC_PATH_TYPE_FILE_ID:
		if (pathlen != 2) return SC_ERROR_INVALID_ARGUMENTS;
		/* fall through */
	case SC_PATH_TYPE_FROM_CURRENT:
		apdu.p1 = 9;
		break;
	case SC_PATH_TYPE_DF_NAME:
		apdu.p1 = 4;
		break;
	case SC_PATH_TYPE_PATH:
		apdu.p1 = 8;
		if (pathlen >= 2 && memcmp(path, "\x3F\x00", 2) == 0) path += 2, pathlen -= 2;
		if (pathlen == 0) apdu.p1 = 0;
		break;
	case SC_PATH_TYPE_PARENT:
		apdu.p1 = 3;
		pathlen = 0;
		break;
	default:
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
	}
	if( pathlen == 0 ) apdu.cse = SC_APDU_CASE_2_SHORT;

	apdu.lc = pathlen;
	apdu.data = path;
	apdu.datalen = pathlen;

	if (file_out != NULL) {
		apdu.resp = buf;
		apdu.resplen = sizeof(buf);
		apdu.le = 256;
	} else {
		apdu.resplen = 0;
		apdu.le = 0; 
		apdu.p2 = 0x0C; 
		apdu.cse = (pathlen == 0) ? SC_APDU_CASE_1 : SC_APDU_CASE_3_SHORT;
	}

	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	if (r || file_out == NULL) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r);

	if (apdu.resplen < 1 || apdu.resp[0] != 0x62){
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "received invalid template %02X\n", apdu.resp[0]);
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_UNKNOWN_DATA_RECEIVED);
	}

	file = sc_file_new();
	if (file == NULL) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
	*file_out = file;
	file->path = *in_path;

	for(i=2; i+1<apdu.resplen && i+1+apdu.resp[i+1]<apdu.resplen; i+=2+apdu.resp[i+1]){
		size_t j, len=apdu.resp[i+1];
		unsigned char type=apdu.resp[i], *d=apdu.resp+i+2;

		switch (type) {
		case 0x80:
		case 0x81:
			file->size=0;
			for(j=0; j<len; ++j) file->size = (file->size<<8) | d[j];
			break;
		case 0x82:
			file->shareable = (d[0] & 0x40) ? 1 : 0;
			file->ef_structure = d[0] & 7;
			switch ((d[0]>>3) & 7) {
			case 0: file->type = SC_FILE_TYPE_WORKING_EF; break;
			case 7: file->type = SC_FILE_TYPE_DF; break;
			default:
				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "invalid file type %02X in file descriptor\n", d[0]);
				SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_UNKNOWN_DATA_RECEIVED);
			}
			break;
		case 0x83:
			file->id = (d[0]<<8) | d[1];
			break;
		case 0x84:
			file->namelen = MIN(sizeof file->name, len);
			memcpy(file->name, d, file->namelen);
			break;
		case 0x86:
			sc_file_set_sec_attr(file, d, len); 
			break;
		default:
			if (len>0) sc_file_set_prop_attr(file, d, len); 
		}
	}
	file->magic = SC_FILE_MAGIC;

	parse_sec_attr(card, file, file->sec_attr, file->sec_attr_len);

	return 0;
}

Project: OpenSC
File: pkcs15-gemsafeV1.c

int sc_pkcs15emu_gemsafeV1_init_ex( sc_pkcs15_card_t *p15card,
			struct sc_aid *aid,
			sc_pkcs15emu_opt_t *opts)
{
	if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)
		return sc_pkcs15emu_gemsafeV1_init(p15card);
	else {
		int r = gemsafe_detect_card(p15card);
		if (r)
			return SC_ERROR_WRONG_CARD;
		return sc_pkcs15emu_gemsafeV1_init(p15card);
	}
}

Project: OpenSC
File: pkcs15-sc-hsm.c

int sc_pkcs15emu_sc_hsm_decode_cvc(sc_pkcs15_card_t * p15card,
											const u8 ** buf, size_t *buflen,
											sc_cvc_t *cvc)
{
	sc_card_t *card = p15card->card;
	struct sc_asn1_entry asn1_req[C_ASN1_REQ_SIZE];
	struct sc_asn1_entry asn1_authreq[C_ASN1_AUTHREQ_SIZE];
	struct sc_asn1_entry asn1_cvc[C_ASN1_CVC_SIZE];
	struct sc_asn1_entry asn1_cvcert[C_ASN1_CVCERT_SIZE];
	struct sc_asn1_entry asn1_cvc_body[C_ASN1_CVC_BODY_SIZE];
	struct sc_asn1_entry asn1_cvc_pubkey[C_ASN1_CVC_PUBKEY_SIZE];
	unsigned int cla,tag;
	size_t taglen;
	size_t lenchr = sizeof(cvc->chr);
	size_t lencar = sizeof(cvc->car);
	size_t lenoutercar = sizeof(cvc->outer_car);
	const u8 *tbuf;
	int r;

	memset(cvc, 0, sizeof(*cvc));
	sc_copy_asn1_entry(c_asn1_req, asn1_req);
	sc_copy_asn1_entry(c_asn1_authreq, asn1_authreq);
	sc_copy_asn1_entry(c_asn1_cvc, asn1_cvc);
	sc_copy_asn1_entry(c_asn1_cvcert, asn1_cvcert);
	sc_copy_asn1_entry(c_asn1_cvc_body, asn1_cvc_body);
	sc_copy_asn1_entry(c_asn1_cvc_pubkey, asn1_cvc_pubkey);

	sc_format_asn1_entry(asn1_cvc_pubkey    , &cvc->pukoid, NULL, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 1, &cvc->primeOrModulus, &cvc->primeOrModuluslen, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 2, &cvc->coefficientAorExponent, &cvc->coefficientAorExponentlen, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 3, &cvc->coefficientB, &cvc->coefficientBlen, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 4, &cvc->basePointG, &cvc->basePointGlen, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 5, &cvc->order, &cvc->orderlen, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 6, &cvc->publicPoint, &cvc->publicPointlen, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 7, &cvc->cofactor, &cvc->cofactorlen, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 8, &cvc->modulusSize, NULL, 0);

	sc_format_asn1_entry(asn1_cvc_body    , &cvc->cpi, NULL, 0);
	sc_format_asn1_entry(asn1_cvc_body + 1, &cvc->car, &lencar, 0);
	sc_format_asn1_entry(asn1_cvc_body + 2, &asn1_cvc_pubkey, NULL, 0);
	sc_format_asn1_entry(asn1_cvc_body + 3, &cvc->chr, &lenchr, 0);

	sc_format_asn1_entry(asn1_cvcert    , &asn1_cvc_body, NULL, 0);
	sc_format_asn1_entry(asn1_cvcert + 1, &cvc->signature, &cvc->signatureLen, 0);

	sc_format_asn1_entry(asn1_cvc , &asn1_cvcert, NULL, 0);

	sc_format_asn1_entry(asn1_authreq    , &asn1_cvcert, NULL, 0);
	sc_format_asn1_entry(asn1_authreq + 1, &cvc->outer_car, &lenoutercar, 0);
	sc_format_asn1_entry(asn1_authreq + 2, &cvc->outerSignature, &cvc->outerSignatureLen, 0);

	sc_format_asn1_entry(asn1_req , &asn1_authreq, NULL, 0);

/*	sc_asn1_print_tags(*buf, *buflen); */

	tbuf = *buf;
	r = sc_asn1_read_tag(&tbuf, *buflen, &cla, &tag, &taglen);
	LOG_TEST_RET(card->ctx, r, "Could not decode card verifiable certificate");

	/*  Determine if we deal with an authenticated request, plain request or certificate */
	if ((cla == (SC_ASN1_TAG_APPLICATION|SC_ASN1_TAG_CONSTRUCTED)) && (tag == 7)) {
		r = sc_asn1_decode(card->ctx, asn1_req, *buf, *buflen, buf, buflen);
	} else {
		r = sc_asn1_decode(card->ctx, asn1_cvc, *buf, *buflen, buf, buflen);
	}

	LOG_TEST_RET(card->ctx, r, "Could not decode card verifiable certificate");

	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}

Project: OpenSC
File: sc.c

const sc_acl_entry_t * sc_file_get_acl_entry(const sc_file_t *file,
						  unsigned int operation)
{
	sc_acl_entry_t *p;
	static const sc_acl_entry_t e_never = {
		SC_AC_NEVER, SC_AC_KEY_REF_NONE, {{0, 0, 0, {0}}}, NULL
	};
	static const sc_acl_entry_t e_none = {
		SC_AC_NONE, SC_AC_KEY_REF_NONE, {{0, 0, 0, {0}}}, NULL
	};
	static const sc_acl_entry_t e_unknown = {
		SC_AC_UNKNOWN, SC_AC_KEY_REF_NONE, {{0, 0, 0, {0}}}, NULL
	};

	if (file == NULL || operation >= SC_MAX_AC_OPS) {
		return NULL;
	}

	p = file->acl[operation];
	if (p == (sc_acl_entry_t *) 1)
		return &e_never;
	if (p == (sc_acl_entry_t *) 2)
		return &e_none;
	if (p == (sc_acl_entry_t *) 3)
		return &e_unknown;

	return file->acl[operation];
}

Project: OpenSC
File: sc.c

int sc_format_oid(struct sc_object_id *oid, const char *in)
{
	int        ii, ret = SC_ERROR_INVALID_ARGUMENTS;
	const char *p;
	char       *q;

	if (oid == NULL || in == NULL)
		return SC_ERROR_INVALID_ARGUMENTS;

	sc_init_oid(oid);

	p = in;
	for (ii=0; ii < SC_MAX_OBJECT_ID_OCTETS; ii++)   {
		oid->value[ii] = strtol(p, &q, 10);
		if (!*q)
			break;

		if (!(q[0] == '.' && isdigit(q[1])))
			goto out;

		p = q + 1;
	}

	if (!sc_valid_oid(oid))
		goto out;

	ret = SC_SUCCESS;
out:
	if (ret)
		sc_init_oid(oid);

	return ret;
}

Project: OpenSC
File: card-epass2003.c

hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType)
{

	if ((NULL == data) || (NULL == hash))
		return SC_ERROR_INVALID_ARGUMENTS;

	if(mechanismType & SC_ALGORITHM_ECDSA_HASH_SHA1)
	{
		unsigned char data_hash[24] = { 0 };
		size_t len = 0;

		sha1_digest(data, datalen, data_hash);
		len = REVERSE_ORDER4(datalen);
		memcpy(&data_hash[20], &len, 4);
		memcpy(hash, data_hash, 24);
	}
	else if(mechanismType & SC_ALGORITHM_ECDSA_HASH_SHA256)
	{
		unsigned char data_hash[36] = { 0 };
		size_t len = 0;

		sha256_digest(data, datalen, data_hash);
		len = REVERSE_ORDER4(datalen);
		memcpy(&data_hash[32], &len, 4);
		memcpy(hash, data_hash, 36);
	}
	else
	{
		return SC_ERROR_NOT_SUPPORTED;
	}

	return SC_SUCCESS;
}

Project: OpenSC
File: card-epass2003.c

mutual_auth(struct sc_card *card, unsigned char *key_enc,
			unsigned char *key_mac)
{
	struct sc_context *ctx = card->ctx;
	int r;
	unsigned char result[256] = { 0 };
	unsigned char ran_key[8] = { 0 };
	epass2003_exdata *exdata = NULL;

	if (!card->drv_data) 
		return SC_ERROR_INVALID_ARGUMENTS;
	exdata = (epass2003_exdata *)card->drv_data;

	LOG_FUNC_CALLED(ctx);

	r = gen_init_key(card, key_enc, key_mac, result, exdata->smtype);
	LOG_TEST_RET(ctx, r, "gen_init_key failed");
	memcpy(ran_key, &result[12], 8);

	r = verify_init_key(card, ran_key, exdata->smtype);
	LOG_TEST_RET(ctx, r, "verify_init_key failed");

	LOG_FUNC_RETURN(ctx, r);
}

Project: OpenSC
File: sc.c

unsigned long sc_thread_id(const sc_context_t *ctx)
{
	if (ctx == NULL || ctx->thread_ctx == NULL ||
	    ctx->thread_ctx->thread_id == NULL)
		return 0UL;
	else
		return ctx->thread_ctx->thread_id();
}

Project: OpenSC
File: card-epass2003.c

epass2003_select_fid(struct sc_card *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(path));
	path.type = SC_PATH_TYPE_FILE_ID;
	path.value[0] = id_hi;
	path.value[1] = id_lo;
	path.len = 2;

	r = epass2003_select_fid_(card, &path, &file);
	LOG_TEST_RET(card->ctx, r, "APDU transmit failed");

	/* update cache */
	if (file && 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;

	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}

Project: OpenSC
File: sc.c

const char *sc_print_path(const sc_path_t *path)
{
	static char buffer[SC_MAX_PATH_STRING_SIZE + SC_MAX_AID_STRING_SIZE];

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

	return buffer;
}

Project: OpenSC
File: pkcs15-sc-hsm.c

static int sc_pkcs15emu_sc_hsm_get_rsa_public_key(struct sc_context *ctx, sc_cvc_t *cvc, struct sc_pkcs15_pubkey *pubkey)
{
	pubkey->algorithm = SC_ALGORITHM_RSA;

	pubkey->alg_id = (struct sc_algorithm_id *)calloc(1, sizeof(struct sc_algorithm_id));
	if (!pubkey->alg_id)
		return SC_ERROR_OUT_OF_MEMORY;

	pubkey->alg_id->algorithm = SC_ALGORITHM_RSA;

	pubkey->u.rsa.modulus.len	= cvc->primeOrModuluslen;
	pubkey->u.rsa.modulus.data	= malloc(pubkey->u.rsa.modulus.len);
	pubkey->u.rsa.exponent.len	= cvc->coefficientAorExponentlen;
	pubkey->u.rsa.exponent.data	= malloc(pubkey->u.rsa.exponent.len);
	if (!pubkey->u.rsa.modulus.data || !pubkey->u.rsa.exponent.data)
		return SC_ERROR_OUT_OF_MEMORY;

	memcpy(pubkey->u.rsa.exponent.data, cvc->coefficientAorExponent, pubkey->u.rsa.exponent.len);
	memcpy(pubkey->u.rsa.modulus.data, cvc->primeOrModulus, pubkey->u.rsa.modulus.len);

	return SC_SUCCESS;
}

Project: OpenSC
File: card-tcos.c

struct sc_card_driver * sc_get_tcos_driver(void)
{
	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();

	if (iso_ops == NULL) iso_ops = iso_drv->ops;
	tcos_ops = *iso_drv->ops;

	tcos_ops.match_card           = tcos_match_card;
	tcos_ops.init                 = tcos_init;
	tcos_ops.finish               = tcos_finish;
	tcos_ops.create_file          = tcos_create_file;
	tcos_ops.set_security_env     = tcos_set_security_env;
	tcos_ops.select_file          = tcos_select_file;
	tcos_ops.list_files           = tcos_list_files;
	tcos_ops.delete_file          = tcos_delete_file;
	tcos_ops.set_security_env     = tcos_set_security_env;
	tcos_ops.compute_signature    = tcos_compute_signature;
	tcos_ops.decipher             = tcos_decipher;
	tcos_ops.restore_security_env = tcos_restore_security_env;
	tcos_ops.card_ctl             = tcos_card_ctl;
	
	return &tcos_drv;
}

Project: OpenSC
File: card-cac.c

static int cac_read_file(sc_card_t *card, int file_type, u8 **out_buf, size_t *out_len)
{
	u8 params[2];
	u8 count[2];
	u8 *out = NULL;
	u8 *out_ptr;
	size_t offset = 0;
	size_t size = 0;
	size_t left = 0;
	size_t len;
	int r;

	params[0] = file_type;
	params[1] = 2;

	/* get the size */
	len = sizeof(count);
	out_ptr = count;
	r = cac_apdu_io(card, CAC_INS_READ_FILE, 0, 0, &params[0], sizeof(params), &out_ptr, &len);
	if (len == 0) {
		r = SC_ERROR_FILE_NOT_FOUND;
	}
	if (r < 0)
		goto fail;

	left = size = lebytes2ushort(count);
	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
		 "got %"SC_FORMAT_LEN_SIZE_T"u bytes out_ptr=%p count&=%p count[0]=0x%02x count[1]=0x%02x, len=0x%04"SC_FORMAT_LEN_SIZE_T"x (%"SC_FORMAT_LEN_SIZE_T"u)",
		 len, out_ptr, &count, count[0], count[1], size, size);
	out = out_ptr = malloc(size);
	if (out == NULL) {
		r = SC_ERROR_OUT_OF_MEMORY;
		goto fail;
	}
	for (offset += 2; left > 0; offset += len, left -= len, out_ptr += len) {
		len = MIN(left, CAC_MAX_CHUNK_SIZE);
		params[1] = len;
		r = cac_apdu_io(card, CAC_INS_READ_FILE, HIGH_BYTE_OF_SHORT(offset), LOW_BYTE_OF_SHORT(offset),
						&params[0], sizeof(params), &out_ptr, &len);
		/* if there is no data, assume there is no file */
		if (len == 0) {
			r = SC_ERROR_FILE_NOT_FOUND;
		}
		if (r < 0) {
			goto fail;
		}
	}
	*out_len = size;
	*out_buf = out;
	return SC_SUCCESS;
fail:
	if (out)
		free(out);
	*out_len = 0;
	return r;
}

Project: OpenSC
File: card-epass2003.c

epass2003_sm_unwrap_apdu(struct sc_card *card, struct sc_apdu *sm, struct sc_apdu *plain)
{
	int r;
	size_t len = 0;
	epass2003_exdata *exdata = NULL;

	if (!card->drv_data) 
		return SC_ERROR_INVALID_ARGUMENTS;

	exdata = (epass2003_exdata *)card->drv_data;

	LOG_FUNC_CALLED(card->ctx);

	r = sc_check_sw(card, sm->sw1, sm->sw2);
	if (r == SC_SUCCESS) {
		if (exdata->sm) {
			len = plain->resplen;
			if (0 != decrypt_response(card, sm->resp, sm->resplen, plain->resp, &len))
				return SC_ERROR_CARD_CMD_FAILED;
		}
		else {
			memcpy(plain->resp, sm->resp, sm->resplen);
			len = sm->resplen;
		}
	}

	plain->resplen = len;
	plain->sw1 = sm->sw1;
	plain->sw2 = sm->sw2;

	sc_log(card->ctx,
	       "unwrapped APDU: resplen %"SC_FORMAT_LEN_SIZE_T"u, SW %02X%02X",
	       plain->resplen, plain->sw1, plain->sw2);
	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}

Project: OpenSC
File: sc.c

int sc_file_set_type_attr(sc_file_t *file, const u8 *type_attr,
			 size_t type_attr_len)
{
	u8 *tmp;
	if (!sc_file_valid(file)) {
		return SC_ERROR_INVALID_ARGUMENTS;
	}

	if (type_attr == NULL) {
		if (file->type_attr != NULL)
			free(file->type_attr);
		file->type_attr = NULL;
		file->type_attr_len = 0;
		return SC_SUCCESS;
	 }
	tmp = (u8 *) realloc(file->type_attr, type_attr_len);
	if (!tmp) {
		if (file->type_attr)
			free(file->type_attr);
		file->type_attr = NULL;
		file->type_attr_len = 0;
		return SC_ERROR_OUT_OF_MEMORY;
	}
	file->type_attr = tmp;
	memcpy(file->type_attr, type_attr, type_attr_len);
	file->type_attr_len = type_attr_len;

	return SC_SUCCESS;
}

Project: OpenSC
File: card-cac.c

static int cac_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
{
	cac_private_data_t * priv = CAC_DATA(card);

	LOG_FUNC_CALLED(card->ctx);
	sc_log(card->ctx, "cmd=%ld ptr=%p", cmd, ptr);

	if (priv == NULL) {
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
	}
	switch(cmd) {
		case SC_CARDCTL_CAC_GET_ACA_PATH:
			return cac_get_ACA_path(card, (sc_path_t *) ptr);
		case SC_CARDCTL_GET_SERIALNR:
			return cac_get_serial_nr_from_CUID(card, (sc_serial_number_t *) ptr);
		case SC_CARDCTL_CAC_INIT_GET_GENERIC_OBJECTS:
			return cac_get_init_and_get_count(&priv->general_list, &priv->general_current, (int *)ptr);
		case SC_CARDCTL_CAC_INIT_GET_CERT_OBJECTS:
			return cac_get_init_and_get_count(&priv->pki_list, &priv->pki_current, (int *)ptr);
		case SC_CARDCTL_CAC_GET_NEXT_GENERIC_OBJECT:
			return cac_fill_object_info(&priv->general_list, &priv->general_current, (sc_pkcs15_data_info_t *)ptr);
		case SC_CARDCTL_CAC_GET_NEXT_CERT_OBJECT:
			return cac_fill_object_info(&priv->pki_list, &priv->pki_current, (sc_pkcs15_data_info_t *)ptr);
		case SC_CARDCTL_CAC_FINAL_GET_GENERIC_OBJECTS:
			return cac_final_iterator(&priv->general_list);
		case SC_CARDCTL_CAC_FINAL_GET_CERT_OBJECTS:
			return cac_final_iterator(&priv->pki_list);
	}

	LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
}

Project: OpenSC
File: card-epass2003.c

des_decrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH],
		const unsigned char *input, size_t length, unsigned char *output)
{
	return openssl_dec(EVP_des_cbc(), key, iv, input, length, output);
}

Project: OpenSC
File: card-tcos.c

static int tcos_delete_file(sc_card_t *card, const sc_path_t *path)
{
	int r;
	u8 sbuf[2];
	sc_apdu_t apdu;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
	if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "File type has to be SC_PATH_TYPE_FILE_ID\n");
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS);
	}
	sbuf[0] = path->value[0];
	sbuf[1] = path->value[1];
	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x00, 0x00);
        apdu.cla |= 0x80;
	apdu.lc = 2;
	apdu.datalen = 2;
	apdu.data = sbuf;
	
	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
	return sc_check_sw(card, apdu.sw1, apdu.sw2);
}

Project: OpenSC
File: sc.c

const u8 *sc_compacttlv_find_tag(const u8 *buf, size_t len, u8 tag, size_t *outlen)
{
	if (buf != NULL) {
		size_t idx;
		u8 plain_tag = tag & 0xF0;
		size_t expected_len = tag & 0x0F;

	        for (idx = 0; idx < len; idx++) {
			if ((buf[idx] & 0xF0) == plain_tag && idx + expected_len < len &&
			    (expected_len == 0 || expected_len == (buf[idx] & 0x0F))) {
				if (outlen != NULL)
					*outlen = buf[idx] & 0x0F;
				return buf + (idx + 1);
			}
			idx += (buf[idx] & 0x0F);
                }
        }
	return NULL;
}

Project: OpenSC
File: card-muscle.c

static int muscle_list_files(sc_card_t *card, u8 *buf, size_t bufLen)
{
	muscle_private_t* priv = MUSCLE_DATA(card);
	mscfs_t *fs = priv->fs;
	int x;
	int count = 0;

	mscfs_check_cache(priv->fs);

	for(x = 0; x < fs->cache.size; x++) {
		u8* oid = fs->cache.array[x].objectId.id;
		if (bufLen < 2)
			break;
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
			"FILE: %02X%02X%02X%02X\n",
			oid[0],oid[1],oid[2],oid[3]);
		if(0 == memcmp(fs->currentPath, oid, 2)) {
			buf[0] = oid[2];
			buf[1] = oid[3];
			if(buf[0] == 0x00 && buf[1] == 0x00) continue; /* No directories/null names outside of root */
			buf += 2;
			count += 2;
			bufLen -= 2;
		}
	}
	return count;
}

Project: OpenSC
File: card-cac.c

static int cac_restore_security_env(sc_card_t *card, int se_num)
{
	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS);
}

Project: OpenSC
File: card-cac.c

static int cac_compute_signature(sc_card_t *card,
					const u8 * data, size_t datalen,
					u8 * out, size_t outlen)
{
	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, cac_rsa_op(card, data, datalen, out, outlen));
}

Project: OpenSC
File: card-tcos.c

static unsigned int map_operations (int commandbyte )
{
	unsigned int op = (unsigned int)-1;

	switch ( (commandbyte & 0xfe) ) {
		case 0xe2: /* append record */   op = SC_AC_OP_UPDATE; break;
		case 0x24: /* change password */ op = SC_AC_OP_UPDATE; break;
		case 0xe0: /* create */          op = SC_AC_OP_CREATE; break;
		case 0xe4: /* delete */          op = SC_AC_OP_DELETE; break;
		case 0xe8: /* exclude sfi */     op = SC_AC_OP_WRITE; break;
		case 0x82: /* external auth */   op = SC_AC_OP_READ; break;
		case 0xe6: /* include sfi */     op = SC_AC_OP_WRITE; break;
		case 0x88: /* internal auth */   op = SC_AC_OP_READ; break;
		case 0x04: /* invalidate */      op = SC_AC_OP_INVALIDATE; break;
		case 0x2a: /* perform sec. op */ op = SC_AC_OP_SELECT; break;
		case 0xb0: /* read binary */     op = SC_AC_OP_READ; break;
		case 0xb2: /* read record */     op = SC_AC_OP_READ; break;
		case 0x44: /* rehabilitate */    op = SC_AC_OP_REHABILITATE; break;
		case 0xa4: /* select */          op = SC_AC_OP_SELECT; break;
		case 0xee: /* set permanent */   op = SC_AC_OP_CREATE; break;
		case 0x2c: /* unblock password */op = SC_AC_OP_WRITE; break;
		case 0xd6: /* update binary */   op = SC_AC_OP_WRITE; break;
		case 0xdc: /* update record */   op = SC_AC_OP_WRITE; break;
		case 0x20: /* verify password */ op = SC_AC_OP_SELECT; break;
		case 0x60: /* admin group */     op = SC_AC_OP_CREATE; break;
	}
	return op;
}

Project: OpenSC
File: pkcs15-sc-hsm.c

static int sc_pkcs15emu_sc_hsm_add_cd(sc_pkcs15_card_t * p15card, u8 id) {

	sc_card_t *card = p15card->card;
	sc_pkcs15_cert_info_t *cert_info;
	sc_pkcs15_object_t obj;
	u8 fid[2];
	u8 efbin[512];
	const u8 *ptr;
	size_t len;
	int r;

	fid[0] = CD_PREFIX;
	fid[1] = id;

	/* Try to select a related EF containing the PKCS#15 description of the data */
	len = sizeof efbin;
	r = read_file(p15card, fid, efbin, &len, 1);
	LOG_TEST_RET(card->ctx, r, "Skipping optional EF.DCOD");

	ptr = efbin;

	memset(&obj, 0, sizeof(obj));
	r = sc_pkcs15_decode_cdf_entry(p15card, &obj, &ptr, &len);
	LOG_TEST_RET(card->ctx, r, "Skipping optional EF.CDOD");

	cert_info = (sc_pkcs15_cert_info_t *)obj.data;

	r = sc_pkcs15emu_add_x509_cert(p15card, &obj, cert_info);

	LOG_TEST_RET(card->ctx, r, "Could not add data object to framework");

	return SC_SUCCESS;
}

Project: OpenSC
File: sc.c

void sc_format_path(const char *str, sc_path_t *path)
{
	int type = SC_PATH_TYPE_PATH;

	if (path) {
		memset(path, 0, sizeof(*path));
		if (*str == 'i' || *str == 'I') {
			type = SC_PATH_TYPE_FILE_ID;
			str++;
		}
		path->len = sizeof(path->value);
		if (sc_hex_to_bin(str, path->value, &path->len) >= 0) {
			path->type = type;
		}
		path->count = -1;
	}
}

Project: OpenSC
File: cryptoflex-tool.c

static int parse_private_key(const u8 *key, size_t keysize, RSA *rsa)
{
	const u8 *p = key;
	BIGNUM *bn_p, *q, *dmp1, *dmq1, *iqmp;
	int base;

	base = (keysize - 3) / 5;
	if (base != 32 && base != 48 && base != 64 && base != 128) {
		fprintf(stderr, "Invalid private key.\n");
		return -1;
	}
	p += 3;
	bn_p = BN_new();
	if (bn_p == NULL)
		return -1;
	cf2bn(p, base, bn_p);
	p += base;

	q = BN_new();
	if (q == NULL)
		return -1;
	cf2bn(p, base, q);
	p += base;

	iqmp = BN_new();
	if (iqmp == NULL)
		return -1;
	cf2bn(p, base, iqmp);
	p += base;

	dmp1 = BN_new();
	if (dmp1 == NULL)
		return -1;
	cf2bn(p, base, dmp1);
	p += base;

	dmq1 = BN_new();
	if (dmq1 == NULL)
		return -1;
	cf2bn(p, base, dmq1);
	p += base;

	
	if (RSA_set0_factors(rsa, bn_p, q) != 1)
		return -1;
	if (RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) != 1)
		return -1;
	if (gen_d(rsa))
		return -1;

	return 0;
}

Project: OpenSC
File: card-muscle.c

static int muscle_card_import_key(sc_card_t *card, sc_cardctl_muscle_key_info_t *info)
{
	/* CURRENTLY DONT SUPPORT EXTRACTING PRIVATE KEYS... */
	switch(info->keyType) {
	case 0x02: /* RSA_PRIVATE */
	case 0x03: /* RSA_PRIVATE_CRT */
		return msc_import_key(card,
			info->keyLocation,
			info);
	default:
		return SC_ERROR_NOT_SUPPORTED;
	}
}

Project: OpenSC
File: pkcs15-esteid.c

set_string (char **strp, const char *value)
{
	if (*strp)
		free (*strp);
	*strp = value ? strdup (value) : NULL;
}

Project: OpenSC
File: pkcs15-sc-hsm.c

int sc_pkcs15emu_sc_hsm_init_ex(sc_pkcs15_card_t *p15card,
				struct sc_aid *aid,
				sc_pkcs15emu_opt_t *opts)
{
	if (opts && (opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) {
		return sc_pkcs15emu_sc_hsm_init(p15card);
	} else {
		if (p15card->card->type != SC_CARD_TYPE_SC_HSM
				&& p15card->card->type != SC_CARD_TYPE_SC_HSM_SOC
				&& p15card->card->type != SC_CARD_TYPE_SC_HSM_GOID) {
			return SC_ERROR_WRONG_CARD;
		}
		return sc_pkcs15emu_sc_hsm_init(p15card);
	}
}

Project: OpenSC
File: util.c

void util_hex_dump_asc(FILE *f, const u8 *in, size_t count, int addr)
{
	int lines = 0;

 	while (count) {
		char ascbuf[17];
		size_t i;

		if (addr >= 0) {
			fprintf(f, "%08X: ", addr);
			addr += 16;
		}
		for (i = 0; i < count && i < 16; i++) {
			fprintf(f, "%02X ", *in);
			if (isprint(*in))
				ascbuf[i] = *in;
			else
				ascbuf[i] = '.';
			in++;
		}
		count -= i;
		ascbuf[i] = 0;
		for (; i < 16 && lines; i++)
			fprintf(f, "   ");
		fprintf(f, "%s\n", ascbuf);
		lines++;
	}
}

Project: OpenSC
File: card-tcos.c

static int tcos_compute_signature(sc_card_t *card, const u8 * data, size_t datalen, u8 * out, size_t outlen)
{
	size_t i, dlen=datalen;
	sc_apdu_t apdu;
	u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
	u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
	int tcos3, r;

	assert(card != NULL && data != NULL && out != NULL);
	tcos3=(card->type==SC_CARD_TYPE_TCOS_V3);

	if (datalen > 255) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);

	if(((tcos_data *)card->drv_data)->next_sign){
		if(datalen>48){
			sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Data to be signed is too long (TCOS supports max. 48 bytes)\n");
			SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
		}
		sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A);
		memcpy(sbuf, data, datalen);
		dlen=datalen;
	} else {
		int keylen= tcos3 ? 256 : 128;
		sc_format_apdu(card, &apdu, keylen>255 ? SC_APDU_CASE_4_EXT : SC_APDU_CASE_4_SHORT, 0x2A,0x80,0x86);
		for(i=0; i<sizeof(sbuf);++i) sbuf[i]=0xff;
		sbuf[0]=0x02; sbuf[1]=0x00; sbuf[2]=0x01; sbuf[keylen-datalen]=0x00;
		memcpy(sbuf+keylen-datalen+1, data, datalen);
		dlen=keylen+1;
	}
	apdu.resp = rbuf;
	apdu.resplen = sizeof(rbuf);
	apdu.le = tcos3 ? 256 : 128;
	apdu.data = sbuf;
	apdu.lc = apdu.datalen = dlen;

	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
	if (tcos3 && apdu.p1==0x80 && apdu.sw1==0x6A && apdu.sw2==0x87) {
		int keylen=128;
		sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A,0x80,0x86);
		for(i=0; i<sizeof(sbuf);++i) sbuf[i]=0xff;
		sbuf[0]=0x02; sbuf[1]=0x00; sbuf[2]=0x01; sbuf[keylen-datalen]=0x00;
		memcpy(sbuf+keylen-datalen+1, data, datalen);
		dlen=keylen+1;

		apdu.resp = rbuf;
		apdu.resplen = sizeof(rbuf);
		apdu.le = 128;
		apdu.data = sbuf;
		apdu.lc = apdu.datalen = dlen;
		r = sc_transmit_apdu(card, &apdu);
		SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
	}
	if (apdu.sw1==0x90 && apdu.sw2==0x00) {
		size_t len = apdu.resplen>outlen ? outlen : apdu.resplen;
		memcpy(out, apdu.resp, len);
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, len);
	}
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
}

Project: OpenSC
File: sc.c

int sc_append_path_id(sc_path_t *dest, const u8 *id, size_t idlen)
{
	if (dest->len + idlen > SC_MAX_PATH_SIZE)
		return SC_ERROR_INVALID_ARGUMENTS;
	memcpy(dest->value + dest->len, id, idlen);
	dest->len += idlen;
	return SC_SUCCESS;
}

Project: OpenSC
File: sc.c

void sc_file_free(sc_file_t *file)
{
	unsigned int i;
	if (file == NULL || !sc_file_valid(file))
		return;
	file->magic = 0;
	for (i = 0; i < SC_MAX_AC_OPS; i++)
		sc_file_clear_acl_entries(file, i);
	if (file->sec_attr)
		free(file->sec_attr);
	if (file->prop_attr)
		free(file->prop_attr);
	if (file->type_attr)
		free(file->type_attr);
	if (file->encoded_content)
		free(file->encoded_content);
	free(file);
}

Project: OpenSC
File: util.c

util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp,
		 const char *reader_id, int do_wait, int do_lock, int verbose)
{
	struct sc_reader *reader = NULL, *found = NULL;
	struct sc_card *card = NULL;
	int r;

	sc_notify_init();

	if (do_wait) {
		unsigned int event;

		if (sc_ctx_get_reader_count(ctx) == 0) {
			fprintf(stderr, "Waiting for a reader to be attached...\n");
			r = sc_wait_for_event(ctx, SC_EVENT_READER_ATTACHED, &found, &event, -1, NULL);
			if (r < 0) {
				fprintf(stderr, "Error while waiting for a reader: %s\n", sc_strerror(r));
				return 3;
			}
			r = sc_ctx_detect_readers(ctx);
			if (r < 0) {
				fprintf(stderr, "Error while refreshing readers: %s\n", sc_strerror(r));
				return 3;
			}
		}
		fprintf(stderr, "Waiting for a card to be inserted...\n");
		r = sc_wait_for_event(ctx, SC_EVENT_CARD_INSERTED, &found, &event, -1, NULL);
		if (r < 0) {
			fprintf(stderr, "Error while waiting for a card: %s\n", sc_strerror(r));
			return 3;
		}
		reader = found;
	}
	else if (sc_ctx_get_reader_count(ctx) == 0) {
		fprintf(stderr, "No smart card readers found.\n");
		return 1;
	}
	else   {
		if (!reader_id) {
			unsigned int i;
			/* Automatically try to skip to a reader with a card if reader not specified */
			for (i = 0; i < sc_ctx_get_reader_count(ctx); i++) {
				reader = sc_ctx_get_reader(ctx, i);
				if (sc_detect_card_presence(reader) & SC_READER_CARD_PRESENT) {
					fprintf(stderr, "Using reader with a card: %s\n", reader->name);
					goto autofound;
				}
			}
			/* If no reader had a card, default to the first reader */
			reader = sc_ctx_get_reader(ctx, 0);
		}
		else {
			/* If the reader identifier looks like an ATR, try to find the reader with that card */
			if (is_string_valid_atr(reader_id))   {
				unsigned char atr_buf[SC_MAX_ATR_SIZE];
				size_t atr_buf_len = sizeof(atr_buf);
				unsigned int i;

				sc_hex_to_bin(reader_id, atr_buf, &atr_buf_len);
				/* Loop readers, looking for a card with ATR */
				for (i = 0; i < sc_ctx_get_reader_count(ctx); i++) {
					struct sc_reader *rdr = sc_ctx_get_reader(ctx, i);

					if (!(sc_detect_card_presence(rdr) & SC_READER_CARD_PRESENT))
						continue;
					else if (rdr->atr.len != atr_buf_len)
						continue;
					else if (memcmp(rdr->atr.value, atr_buf, rdr->atr.len))
						continue;

					fprintf(stderr, "Matched ATR in reader: %s\n", rdr->name);
					reader = rdr;
					goto autofound;
				}
			}
			else   {
				char *endptr = NULL;
				unsigned int num;

				errno = 0;
				num = strtol(reader_id, &endptr, 0);
				if (!errno && endptr && *endptr == '\0')
					reader = sc_ctx_get_reader(ctx, num);
				else
					reader = sc_ctx_get_reader_by_name(ctx, reader_id);
			}
		}
autofound:
		if (!reader) {
			fprintf(stderr, "Reader \"%s\" not found (%d reader(s) detected)\n",
					reader_id, sc_ctx_get_reader_count(ctx));
			return 1;
		}

		if (sc_detect_card_presence(reader) <= 0) {
			fprintf(stderr, "Card not present.\n");
			return 3;
		}
	}

	if (verbose)
		printf("Connecting to card in reader %s...\n", reader->name);
	r = sc_connect_card(reader, &card);
	if (r < 0) {
		fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(r));
		return 1;
	}

	if (verbose)
		printf("Using card driver %s.\n", card->driver->name);

	if (do_lock) {
		r = sc_lock(card);
		if (r < 0) {
			fprintf(stderr, "Failed to lock card: %s\n", sc_strerror(r));
			sc_disconnect_card(card);
			return 1;
		}
	}

	*cardp = card;
	return 0;
}

Project: OpenSC
File: pkcs15-gemsafeV1.c

sc_pkcs15emu_add_cert(sc_pkcs15_card_t *p15card,
		int type, int authority,
		const sc_path_t *path,
		const sc_pkcs15_id_t *id,
                const char *label, int obj_flags)
{
	sc_pkcs15_cert_info_t *info;
	info = calloc(1, sizeof(*info));
	if (!info)
	{
		LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
	}
	info->id		= *id;
	info->authority		= authority;
	if (path)
		info->path = *path;

	return sc_pkcs15emu_add_object(p15card, type, label, info, NULL, obj_flags);
}

Project: OpenSC
File: cryptoflex-tool.c

static int parse_public_key(const u8 *key, size_t keysize, RSA *rsa)
{
	const u8 *p = key;
	BIGNUM *n, *e;
	int base;

	base = (keysize - 7) / 5;
	if (base != 32 && base != 48 && base != 64 && base != 128) {
		fprintf(stderr, "Invalid public key.\n");
		return -1;
	}
	p += 3;
	n = BN_new();
	if (n == NULL)
		return -1;
	cf2bn(p, 2 * base, n);
	p += 2 * base;
	p += base;
	p += 2 * base;
	e = BN_new();
	if (e == NULL)
		return -1;
	cf2bn(p, 4, e);
	if (RSA_set0_key(rsa, n, e, NULL) != 1)
	    return -1;
	return 0;
}

Project: OpenSC
File: card-epass2003.c

sha1_digest(const unsigned char *input, size_t length, unsigned char *output)
{
	return openssl_dig(EVP_sha1(), input, length, output);
}

Project: OpenSC
File: card-muscle.c

static int muscle_compute_signature(sc_card_t *card, const u8 *data,
		size_t data_len, u8 * out, size_t outlen)
{
	muscle_private_t* priv = MUSCLE_DATA(card);
	u8 key_id;
	int r;

	key_id = priv->rsa_key_ref * 2; /* Private key */

	if (outlen < data_len) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Output buffer too small");
		return SC_ERROR_BUFFER_TOO_SMALL;
	}

	r = msc_compute_crypt(card,
		key_id,
		0x00, /* RSA NO PADDING */
		0x04, /* -- decrypt raw... will do what we need since signing isn't yet supported */
		data,
		out,
		data_len,
		outlen);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card signature failed");
	return r;
}

Project: OpenSC
File: sc.c

int sc_compare_path(const sc_path_t *path1, const sc_path_t *path2)
{
	return path1->len == path2->len
		&& !memcmp(path1->value, path2->value, path1->len);
}

Project: OpenSC
File: card-tcos.c

static int tcos_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num)
{
	sc_context_t *ctx;
	sc_apdu_t apdu;
	u8 sbuf[SC_MAX_APDU_BUFFER_SIZE], *p;
	int r, default_key, tcos3;
	tcos_data *data;

	assert(card != NULL && env != NULL);
	ctx = card->ctx;
	tcos3=(card->type==SC_CARD_TYPE_TCOS_V3);
	data=(tcos_data *)card->drv_data;

        if (se_num || (env->operation!=SC_SEC_OPERATION_DECIPHER && env->operation!=SC_SEC_OPERATION_SIGN)){
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS);
	}
	if(!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT))
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
			"No Key-Reference in SecEnvironment\n");
	else
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
			 "Key-Reference %02X (len=%"SC_FORMAT_LEN_SIZE_T"u)\n",
			 env->key_ref[0], env->key_ref_len);
	/* Key-Reference 0x80 ?? */
	default_key= !(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || (env->key_ref_len==1 && env->key_ref[0]==0x80);
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
		"TCOS3:%d PKCS1:%d\n", tcos3,
		!!(env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1));

	data->pad_flags = env->algorithm_flags;
	data->next_sign = default_key;

	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, tcos3 ? 0x41 : 0xC1, 0xB8);
	p = sbuf;
	*p++=0x80; *p++=0x01; *p++=tcos3 ? 0x0A : 0x10;
	if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) {
		*p++ = (env->flags & SC_SEC_ENV_KEY_REF_SYMMETRIC) ? 0x83 : 0x84;
		*p++ = env->key_ref_len;
		memcpy(p, env->key_ref, env->key_ref_len);
		p += env->key_ref_len;
	}
	apdu.data = sbuf;
	apdu.lc = apdu.datalen = (p - sbuf);

	r=sc_transmit_apdu(card, &apdu);
	if (r) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
			"%s: APDU transmit failed", sc_strerror(r));
		return r;
	}
	if (apdu.sw1==0x6A && (apdu.sw2==0x81 || apdu.sw2==0x88)) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
			"Detected Signature-Only key\n");
		if (env->operation==SC_SEC_OPERATION_SIGN && default_key) return SC_SUCCESS;
	}
	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
}

Project: OpenSC
File: card-epass2003.c

install_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid,
		unsigned char useac, unsigned char modifyac, unsigned char EC,
		unsigned char *data, unsigned long dataLen)
{
	int r;
	struct sc_apdu apdu;
	unsigned char isapp = 0x00;	/* appendable */
	unsigned char tmp_data[256] = { 0 };

	tmp_data[0] = ktype;
	tmp_data[1] = kid;
	tmp_data[2] = useac;
	tmp_data[3] = modifyac;
	tmp_data[8] = 0xFF;

	if (0x04 == ktype || 0x06 == ktype) {
		tmp_data[4] = EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_SO;
		tmp_data[5] = EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_SO;
		tmp_data[7] = (kid == PIN_ID[0] ? EPASS2003_AC_USER : EPASS2003_AC_SO);
		tmp_data[9] = (EC << 4) | EC;
	}

	memcpy(&tmp_data[10], data, dataLen);
	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xe3, isapp, 0x00);
	apdu.cla = 0x80;
	apdu.lc = apdu.datalen = 10 + dataLen;
	apdu.data = tmp_data;

	r = sc_transmit_apdu_t(card, &apdu);
	LOG_TEST_RET(card->ctx, r, "APDU install_secret_key failed");
	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	LOG_TEST_RET(card->ctx, r, "install_secret_key failed");

	return r;
}

Project: OpenSC
File: sc.c

unsigned short lebytes2ushort(const u8 *buf)
{
	if (buf == NULL)
		return 0U;
	return (unsigned short)buf[1] << 8 | (unsigned short)buf[0];
}

Project: OpenSC
File: card-cac.c

static int cac_select_ACA(sc_card_t *card)
{
	return cac_select_file_by_type(card, &cac_ACA_Path, NULL, SC_CARD_TYPE_CAC_II);
}

Project: OpenSC
File: card-cac.c

static int cac_populate_cac_alt(sc_card_t *card, int index, cac_private_data_t *priv)
{
	int r, i;
	cac_object_t pki_obj = cac_cac_pki_obj;
	u8 buf[100];
	u8 *val;
	size_t val_len;

	/* populate PKI objects */
	for (i = index; i < MAX_CAC_SLOTS; i++) {
		r = cac_select_pki_applet(card, i);
		if (r == SC_SUCCESS) {
			pki_obj.name = cac_labels[i];
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
			    "CAC: pki_object found, cert_next=%d (%s),", i, pki_obj.name);
			pki_obj.path.aid.value[pki_obj.path.aid.len-1] = i;
			pki_obj.fd = i+1; /* don't use id of zero */
			cac_add_object_to_list(&priv->pki_list, &pki_obj);
		}
	}

	/* populate non-PKI objects */
	for (i=0; i < cac_object_count; i++) {
		r = cac_select_file_by_type(card, &cac_objects[i].path, NULL,
		    SC_CARD_TYPE_CAC_II);
		if (r == SC_SUCCESS) {
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
			    "CAC: obj_object found, cert_next=%d (%s),",
			    i, cac_objects[i].name);
			cac_add_object_to_list(&priv->general_list, &cac_objects[i]);
		}
	}

	/*
	 * create a cuid to simulate the cac 2 cuid.
	 */
	priv->cuid = cac_cac_cuid;
	/* create a serial number by hashing the first 100 bytes of the
	 * first certificate on the card */
	r = cac_select_pki_applet(card, index);
	if (r < 0) {
		return r; /* shouldn't happen unless the card has been removed or is malfunctioning */
	}
	val = buf;
	val_len = cac_read_binary(card, 0, val, sizeof(buf), 0);
	if (val_len > 0) {
		priv->cac_id = malloc(20);
		if (priv->cac_id == NULL) {
			return SC_ERROR_OUT_OF_MEMORY;
		}
#ifdef ENABLE_OPENSSL
		SHA1(val, val_len, priv->cac_id);
		priv->cac_id_len = 20;
		sc_debug_hex(card->ctx, SC_LOG_DEBUG_VERBOSE,
		    "cuid", priv->cac_id, priv->cac_id_len);
#else
		sc_log(card->ctx, "OpenSSL Required");
		return SC_ERROR_NOT_SUPPORTED;
#endif /* ENABLE_OPENSSL */
	}
	return SC_SUCCESS;
}

Project: OpenSC
File: pkcs15-sc-hsm.c

static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card)
{
	sc_card_t *card = p15card->card;
	sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
	sc_file_t *file = NULL;
	sc_path_t path;
	u8 filelist[MAX_EXT_APDU_LENGTH];
	int filelistlength;
	int r, i;
	sc_cvc_t devcert;
	struct sc_app_info *appinfo;
	struct sc_pkcs15_auth_info pin_info;
	struct sc_pkcs15_object pin_obj;
	struct sc_pin_cmd_data pindata;
	u8 efbin[1024];
	u8 *ptr;
	size_t len;

	LOG_FUNC_CALLED(card->ctx);

	appinfo = calloc(1, sizeof(struct sc_app_info));

	if (appinfo == NULL) {
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
	}

	appinfo->aid = sc_hsm_aid;

	appinfo->ddo.aid = sc_hsm_aid;
	p15card->app = appinfo;

	sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
	r = sc_select_file(card, &path, &file);
	LOG_TEST_RET(card->ctx, r, "Could not select SmartCard-HSM application");

	p15card->card->version.hw_major = 24;	/* JCOP 2.4.1r3 */
	p15card->card->version.hw_minor = 13;
	if (file && file->prop_attr && file->prop_attr_len >= 2) {
		p15card->card->version.fw_major = file->prop_attr[file->prop_attr_len - 2];
		p15card->card->version.fw_minor = file->prop_attr[file->prop_attr_len - 1];
	}

	sc_file_free(file);

	/* Read device certificate to determine serial number */
	if (priv->EF_C_DevAut && priv->EF_C_DevAut_len) {
		ptr = priv->EF_C_DevAut;
		len = priv->EF_C_DevAut_len;
	} else {
		len = sizeof efbin;
		r = read_file(p15card, (u8 *) "\x2F\x02", efbin, &len, 1);
		LOG_TEST_RET(card->ctx, r, "Skipping optional EF.C_DevAut");

		if (len > 0) {
			/* save EF_C_DevAut for further use */
			ptr = realloc(priv->EF_C_DevAut, len);
			if (ptr) {
				memcpy(ptr, efbin, len);
				priv->EF_C_DevAut = ptr;
				priv->EF_C_DevAut_len = len;
			}
		}

		ptr = efbin;
	}

	memset(&devcert, 0 ,sizeof(devcert));
	r = sc_pkcs15emu_sc_hsm_decode_cvc(p15card, (const u8 **)&ptr, &len, &devcert);
	LOG_TEST_RET(card->ctx, r, "Could not decode EF.C_DevAut");

	sc_pkcs15emu_sc_hsm_read_tokeninfo(p15card);

	if (p15card->tokeninfo->label == NULL) {
		if (p15card->card->type == SC_CARD_TYPE_SC_HSM_GOID
				|| p15card->card->type == SC_CARD_TYPE_SC_HSM_SOC) {
			p15card->tokeninfo->label = strdup("GoID");
		} else {
			p15card->tokeninfo->label = strdup("SmartCard-HSM");
		}
		if (p15card->tokeninfo->label == NULL)
			LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
	}

	if ((p15card->tokeninfo->manufacturer_id != NULL) && !strcmp("(unknown)", p15card->tokeninfo->manufacturer_id)) {
		free(p15card->tokeninfo->manufacturer_id);
		p15card->tokeninfo->manufacturer_id = NULL;
	}

	if (p15card->tokeninfo->manufacturer_id == NULL) {
		if (p15card->card->type == SC_CARD_TYPE_SC_HSM_GOID
				|| p15card->card->type == SC_CARD_TYPE_SC_HSM_SOC) {
			p15card->tokeninfo->manufacturer_id = strdup("Bundesdruckerei GmbH");
		} else {
			p15card->tokeninfo->manufacturer_id = strdup("www.CardContact.de");
		}
		if (p15card->tokeninfo->manufacturer_id == NULL)
			LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
	}

	appinfo->label = strdup(p15card->tokeninfo->label);
	if (appinfo->label == NULL)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);

	len = strnlen(devcert.chr, sizeof devcert.chr);		/* Strip last 5 digit sequence number from CHR */
	assert(len >= 8);
	len -= 5;

	p15card->tokeninfo->serial_number = calloc(len + 1, 1);
	if (p15card->tokeninfo->serial_number == NULL)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);

	memcpy(p15card->tokeninfo->serial_number, devcert.chr, len);
	*(p15card->tokeninfo->serial_number + len) = 0;

	sc_hsm_set_serialnr(card, p15card->tokeninfo->serial_number);

	sc_pkcs15emu_sc_hsm_free_cvc(&devcert);

	memset(&pin_info, 0, sizeof(pin_info));
	memset(&pin_obj, 0, sizeof(pin_obj));

	pin_info.auth_id.len = 1;
	pin_info.auth_id.value[0] = 1;
	pin_info.path.aid = sc_hsm_aid;
	pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
	pin_info.attrs.pin.reference = 0x81;
	pin_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_LOCAL|SC_PKCS15_PIN_FLAG_INITIALIZED|SC_PKCS15_PIN_FLAG_EXCHANGE_REF_DATA;
	pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC;
	pin_info.attrs.pin.min_length = 6;
	pin_info.attrs.pin.stored_length = 0;
	pin_info.attrs.pin.max_length = 15;
	pin_info.attrs.pin.pad_char = '\0';
	pin_info.tries_left = 3;
	pin_info.max_tries = 3;

	pin_obj.auth_id.len = 1;
	pin_obj.auth_id.value[0] = 2;
	strlcpy(pin_obj.label, "UserPIN", sizeof(pin_obj.label));
	pin_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE|SC_PKCS15_CO_FLAG_MODIFIABLE;

	r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
	if (r < 0)
		LOG_FUNC_RETURN(card->ctx, r);

	memset(&pin_info, 0, sizeof(pin_info));
	memset(&pin_obj, 0, sizeof(pin_obj));

	pin_info.auth_id.len = 1;
	pin_info.auth_id.value[0] = 2;
	pin_info.path.aid = sc_hsm_aid;
	pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
	pin_info.attrs.pin.reference = 0x88;
	pin_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_LOCAL|SC_PKCS15_PIN_FLAG_INITIALIZED|SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED|SC_PKCS15_PIN_FLAG_SO_PIN;
	pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_BCD;
	pin_info.attrs.pin.min_length = 16;
	pin_info.attrs.pin.stored_length = 0;
	pin_info.attrs.pin.max_length = 16;
	pin_info.attrs.pin.pad_char = '\0';
	pin_info.tries_left = 15;
	pin_info.max_tries = 15;

	strlcpy(pin_obj.label, "SOPIN", sizeof(pin_obj.label));
	pin_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE;

	r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
	if (r < 0)
		LOG_FUNC_RETURN(card->ctx, r);


	if (card->type == SC_CARD_TYPE_SC_HSM_SOC
			|| card->type == SC_CARD_TYPE_SC_HSM_GOID) {
		/* SC-HSM of this type always has a PIN-Pad */
		r = SC_SUCCESS;
	} else {
		memset(&pindata, 0, sizeof(pindata));
		pindata.cmd = SC_PIN_CMD_GET_INFO;
		pindata.pin_type = SC_AC_CHV;
		pindata.pin_reference = 0x85;

		r = sc_pin_cmd(card, &pindata, NULL);
	}
	if (r == SC_ERROR_DATA_OBJECT_NOT_FOUND) {
		memset(&pindata, 0, sizeof(pindata));
		pindata.cmd = SC_PIN_CMD_GET_INFO;
		pindata.pin_type = SC_AC_CHV;
		pindata.pin_reference = 0x86;

		r = sc_pin_cmd(card, &pindata, NULL);
	}

	if ((r != SC_ERROR_DATA_OBJECT_NOT_FOUND) && (r != SC_ERROR_INCORRECT_PARAMETERS))
		card->caps |= SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH;


	filelistlength = sc_list_files(card, filelist, sizeof(filelist));
	LOG_TEST_RET(card->ctx, filelistlength, "Could not enumerate file and key identifier");

	for (i = 0; i < filelistlength; i += 2) {
		switch(filelist[i]) {
		case KEY_PREFIX:
			r = sc_pkcs15emu_sc_hsm_add_prkd(p15card, filelist[i + 1]);
			break;
		case DCOD_PREFIX:
			r = sc_pkcs15emu_sc_hsm_add_dcod(p15card, filelist[i + 1]);
			break;
		case CD_PREFIX:
			r = sc_pkcs15emu_sc_hsm_add_cd(p15card, filelist[i + 1]);
			break;
		}
		if (r != SC_SUCCESS) {
			sc_log(card->ctx, "Error %d adding elements to framework", r);
		}
	}

	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}

Project: OpenSC
File: cryptoflex-tool.c

static int gen_d(RSA *rsa)
{
	BN_CTX *bnctx;
	BIGNUM *r0, *r1, *r2;
	const BIGNUM *rsa_p, *rsa_q, *rsa_n, *rsa_e, *rsa_d;
	BIGNUM *rsa_n_new, *rsa_e_new, *rsa_d_new;

	bnctx = BN_CTX_new();
	if (bnctx == NULL)
		return -1;
	BN_CTX_start(bnctx);
	r0 = BN_CTX_get(bnctx);
	r1 = BN_CTX_get(bnctx);
	r2 = BN_CTX_get(bnctx);
	RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
	RSA_get0_factors(rsa, &rsa_p, &rsa_q);

	BN_sub(r1, rsa_p, BN_value_one());
	BN_sub(r2, rsa_q, BN_value_one());
	BN_mul(r0, r1, r2, bnctx);
	if ((rsa_d_new = BN_mod_inverse(NULL, rsa_e, r0, bnctx)) == NULL) {
		fprintf(stderr, "BN_mod_inverse() failed.\n");
		return -1;
	}

	/* RSA_set0_key will free previous value, and replace with new value
	 * Thus the need to copy the contents of rsa_n and rsa_e
	 */
	rsa_n_new = BN_dup(rsa_n);
	rsa_e_new = BN_dup(rsa_e);
	if (RSA_set0_key(rsa, rsa_n_new, rsa_e_new, rsa_d_new) != 1)
		return -1;

	BN_CTX_end(bnctx);
	BN_CTX_free(bnctx);
	return 0;
}

Project: OpenSC
File: cryptoflex-tool.c

static int read_key(void)
{
	RSA *rsa = RSA_new();
	u8 buf[1024], *p = buf;
	u8 b64buf[2048];
	int r;

	if (rsa == NULL)
		return -1;
	r = read_public_key(rsa);
	if (r)
		return r;
	r = i2d_RSA_PUBKEY(rsa, &p);
	if (r <= 0) {
		fprintf(stderr, "Error encoding public key.\n");
		return -1;
	}
	r = sc_base64_encode(buf, r, b64buf, sizeof(b64buf), 64);
	if (r < 0) {
		fprintf(stderr, "Error in Base64 encoding: %s\n", sc_strerror(r));
		return -1;
	}
	printf("-----BEGIN PUBLIC KEY-----\n%s-----END PUBLIC KEY-----\n", b64buf);

	r = read_private_key(rsa);
	if (r == 10)
		return 0;
	else if (r)
		return r;
	p = buf;
	r = i2d_RSAPrivateKey(rsa, &p);
	if (r <= 0) {
		fprintf(stderr, "Error encoding private key.\n");
		return -1;
	}
	r = sc_base64_encode(buf, r, b64buf, sizeof(b64buf), 64);
	if (r < 0) {
		fprintf(stderr, "Error in Base64 encoding: %s\n", sc_strerror(r));
		return -1;
	}
	printf("-----BEGIN RSA PRIVATE KEY-----\n%s-----END RSA PRIVATE KEY-----\n", b64buf);

	return 0;
}

Project: OpenSC
File: egk-tool.c

int read_file(struct sc_card *card, char *str_path, unsigned char **data, size_t *data_len)
{
	struct sc_path path;
	struct sc_file *file;
	unsigned char *p;
	int ok = 0;
	int r;
	size_t len;

	sc_format_path(str_path, &path);
	if (SC_SUCCESS != sc_select_file(card, &path, &file)) {
		goto err;
	}

	len = file && file->size > 0 ? file->size : 4096;
	p = realloc(*data, len);
	if (!p) {
		goto err;
	}
	*data = p;
	*data_len = len;

	r = sc_read_binary(card, 0, p, len, 0);
	if (r < 0)
		goto err;

	*data_len = r;
	ok = 1;

err:
	sc_file_free(file);

	return ok;
}

Project: OpenSC
File: card-cac.c

static int cac_path_from_cardurl(sc_card_t *card, sc_path_t *path, cac_card_url_t *val, int len)
{
	if (len < 10) {
		return SC_ERROR_INVALID_DATA;
	}
	sc_mem_clear(path, sizeof(sc_path_t));
	memcpy(path->aid.value, &val->rid, sizeof(val->rid));
	memcpy(&path->aid.value[5], &val->applicationID, sizeof(val->applicationID));
	path->aid.len = sizeof(val->rid) + sizeof(val->applicationID);
	memcpy(path->value, &val->objectID, sizeof(val->objectID));
	path->len = sizeof(val->objectID);
	path->type = SC_PATH_TYPE_FILE_ID;
	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
		 "path->aid=%x %x %x %x %x %x %x  len=%"SC_FORMAT_LEN_SIZE_T"u, path->value = %x %x len=%"SC_FORMAT_LEN_SIZE_T"u path->type=%d (%x)",
		 path->aid.value[0], path->aid.value[1], path->aid.value[2],
		 path->aid.value[3], path->aid.value[4], path->aid.value[5],
		 path->aid.value[6], path->aid.len, path->value[0],
		 path->value[1], path->len, path->type, path->type);
	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
		 "rid=%x %x %x %x %x  len=%"SC_FORMAT_LEN_SIZE_T"u appid= %x %x len=%"SC_FORMAT_LEN_SIZE_T"u objid= %x %x len=%"SC_FORMAT_LEN_SIZE_T"u",
		 val->rid[0], val->rid[1], val->rid[2], val->rid[3],
		 val->rid[4], sizeof(val->rid), val->applicationID[0],
		 val->applicationID[1], sizeof(val->applicationID),
		 val->objectID[0], val->objectID[1], sizeof(val->objectID));

	return SC_SUCCESS;
}

Project: OpenSC
File: card-epass2003.c

epass2003_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
{
	u8 rbuf[16];
	size_t out_len;
	int r;

	LOG_FUNC_CALLED(card->ctx);

	r = iso_ops->get_challenge(card, rbuf, sizeof rbuf);
	LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed");

	if (len < (size_t) r) {
		out_len = len;
	} else {
		out_len = (size_t) r;
	}
	memcpy(rnd, rbuf, out_len);

	LOG_FUNC_RETURN(card->ctx, (int) out_len);
}

Project: OpenSC
File: card-epass2003.c

decrypt_response(struct sc_card *card, unsigned char *in, size_t inlen, unsigned char *out, size_t * out_len)
{
	size_t cipher_len;
	size_t i;
	unsigned char iv[16] = { 0 };
	unsigned char plaintext[4096] = { 0 };
	epass2003_exdata *exdata = NULL;

	if (!card->drv_data) 
		return SC_ERROR_INVALID_ARGUMENTS;

	exdata = (epass2003_exdata *)card->drv_data;

	/* no cipher */
	if (in[0] == 0x99)
		return 0;

	/* parse cipher length */
	if (0x01 == in[2] && 0x82 != in[1]) {
		cipher_len = in[1];
		i = 3;
	}
	else if (0x01 == in[3] && 0x81 == in[1]) {
		cipher_len = in[2];
		i = 4;
	}
	else if (0x01 == in[4] && 0x82 == in[1]) {
		cipher_len = in[2] * 0x100;
		cipher_len += in[3];
		i = 5;
	}
	else {
		return -1;
	}

	if (cipher_len < 2 || i+cipher_len > inlen || cipher_len > sizeof plaintext)
		return -1;

	/* decrypt */
	if (KEY_TYPE_AES == exdata->smtype)
		aes128_decrypt_cbc(exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext);
	else
		des3_decrypt_cbc(exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext);

	/* unpadding */
	while (0x80 != plaintext[cipher_len - 2] && (cipher_len - 2 > 0))
		cipher_len--;

	if (2 == cipher_len || *out_len < cipher_len - 2)
		return -1;

	memcpy(out, plaintext, cipher_len - 2);
	*out_len = cipher_len - 2;
	return 0;
}

Project: OpenSC
File: pkcs15-gemsafeV1.c

sc_pkcs15emu_add_prkey(sc_pkcs15_card_t *p15card,
                const sc_pkcs15_id_t *id,
                const char *label,
                int type, unsigned int modulus_length, int usage,
                const sc_path_t *path, int ref,
                const sc_pkcs15_id_t *auth_id, int obj_flags)
{
	sc_pkcs15_prkey_info_t *info;

	info = calloc(1, sizeof(*info));
	if (!info)
	{
		LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
	}
	info->id                = *id;
	info->modulus_length    = modulus_length;
	info->usage             = usage;
	info->native            = 1;
	info->access_flags      = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
                                | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
                                | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
                                | SC_PKCS15_PRKEY_ACCESS_LOCAL;
	info->key_reference     = ref;

	if (path)
		info->path = *path;

	return sc_pkcs15emu_add_object(p15card, type, label,
			info, auth_id, obj_flags);
}

Project: OpenSC
File: cryptoflex-tool.c

static int update_private_key(const u8 *key, size_t keysize)
{
	int r, idx = 0;
	sc_path_t path;

	r = select_app_df();
	if (r)
		return 1;
	sc_format_path("I0012", &path);
	r = sc_select_file(card, &path, NULL);
	if (r) {
		fprintf(stderr, "Unable to select private key file: %s\n", sc_strerror(r));
		return 2;
	}
	idx = keysize * (opt_key_num-1);
	r = sc_update_binary(card, idx, key, keysize, 0);
	if (r < 0) {
		fprintf(stderr, "Unable to write private key: %s\n", sc_strerror(r));
		return 2;
	}
	return 0;
}

Project: OpenSC
File: card-cac.c

static cac_private_data_t *cac_new_private_data(void)
{
	cac_private_data_t *priv;
	priv = calloc(1, sizeof(cac_private_data_t));
	if (!priv)
		return NULL;
	list_init(&priv->pki_list);
	list_attributes_comparator(&priv->pki_list, cac_list_compare_path);
	list_attributes_copy(&priv->pki_list, cac_list_meter, 1);
	list_init(&priv->general_list);
	list_attributes_comparator(&priv->general_list, cac_list_compare_path);
	list_attributes_copy(&priv->general_list, cac_list_meter, 1);
	/* set other fields as appropriate */

	return priv;
}

Project: OpenSC
File: card-tcos.c

static void parse_sec_attr(sc_card_t *card,
                           sc_file_t *file, const u8 *buf, size_t len)
{
        unsigned int op;
        
        /* list directory is not covered by ACLs - so always add an entry */
        sc_file_add_acl_entry (file, SC_AC_OP_LIST_FILES,
                               SC_AC_NONE, SC_AC_KEY_REF_NONE);
        /* FIXME: check for what LOCK is used */
        sc_file_add_acl_entry (file, SC_AC_OP_LOCK,
                               SC_AC_NONE, SC_AC_KEY_REF_NONE);
        for (; len >= 6; len -= 6, buf += 6) {
                /* FIXME: temporary hacks */
                if (!memcmp(buf, "\xa4\x00\x00\x00\xff\xff", 6)) /* select */
                        sc_file_add_acl_entry (file, SC_AC_OP_SELECT,
                                               SC_AC_NONE, SC_AC_KEY_REF_NONE);
                else if (!memcmp(buf, "\xb0\x00\x00\x00\xff\xff", 6)) /*read*/
                        sc_file_add_acl_entry (file, SC_AC_OP_READ,
                                               SC_AC_NONE, SC_AC_KEY_REF_NONE);
                else if (!memcmp(buf, "\xd6\x00\x00\x00\xff\xff", 6)) /*upd*/
                        sc_file_add_acl_entry (file, SC_AC_OP_UPDATE,
                                               SC_AC_NONE, SC_AC_KEY_REF_NONE);
                else if (!memcmp(buf, "\x60\x00\x00\x00\xff\xff", 6)) {/*adm */
                        sc_file_add_acl_entry (file, SC_AC_OP_WRITE,
                                               SC_AC_NONE, SC_AC_KEY_REF_NONE);
                        sc_file_add_acl_entry (file, SC_AC_OP_CREATE,
                                               SC_AC_NONE, SC_AC_KEY_REF_NONE);
                        sc_file_add_acl_entry (file, SC_AC_OP_INVALIDATE,
                                               SC_AC_NONE, SC_AC_KEY_REF_NONE);
                        sc_file_add_acl_entry (file, SC_AC_OP_REHABILITATE,
                                               SC_AC_NONE, SC_AC_KEY_REF_NONE);
                }
                else {
                        /* the first byte tells use the command or the
                           command group.  We have to mask bit 0
                           because this one distinguish between AND/OR
                           combination of PINs*/
                        op = map_operations (buf[0]);
                        if (op == (unsigned int)-1)
                        {
                                sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
                                       "Unknown security command byte %02x\n",
                                       buf[0]);
                                continue;
                        }
                        if (!buf[1])
                                sc_file_add_acl_entry (file, op,
                                                       SC_AC_NONE,
                                                       SC_AC_KEY_REF_NONE);
                        else
                                sc_file_add_acl_entry (file, op,
                                                       SC_AC_CHV, buf[1]);

                        if (!buf[2] && !buf[3])
                                sc_file_add_acl_entry (file, op,
                                                       SC_AC_NONE,
                                                       SC_AC_KEY_REF_NONE);
                        else
                                sc_file_add_acl_entry (file, op,
                                                       SC_AC_TERM,
                                                       (buf[2]<<8)|buf[3]);
                }
        }
}

Project: OpenSC
File: card-epass2003.c

update_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid,
		const unsigned char *data, unsigned long datalen)
{
	int r;
	struct sc_apdu apdu;
	unsigned char hash[HASH_LEN] = { 0 };
	unsigned char tmp_data[256] = { 0 };
	unsigned char maxtries = 0;

	r = hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1);
	LOG_TEST_RET(card->ctx, r, "hash data failed");

	r = get_external_key_maxtries(card, &maxtries);
	LOG_TEST_RET(card->ctx, r, "get max counter failed");

	tmp_data[0] = (maxtries << 4) | maxtries;
	memcpy(&tmp_data[1], hash, HASH_LEN);
	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xe5, ktype, kid);
	apdu.cla = 0x80;
	apdu.lc = apdu.datalen = 1 + HASH_LEN;
	apdu.data = tmp_data;

	r = sc_transmit_apdu_t(card, &apdu);
	LOG_TEST_RET(card->ctx, r, "APDU update_secret_key failed");
	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	LOG_TEST_RET(card->ctx, r, "update_secret_key failed");

	return r;
}

Project: OpenSC
File: card-muscle.c

static int muscle_init(sc_card_t *card)
{
	muscle_private_t *priv;

	card->name = "MuscleApplet";
	card->drv_data = malloc(sizeof(muscle_private_t));
	if(!card->drv_data) {
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
	}
	memset(card->drv_data, 0, sizeof(muscle_private_t));
	priv = MUSCLE_DATA(card);
	priv->verifiedPins = 0;
	priv->fs = mscfs_new();
	if(!priv->fs) {
		free(card->drv_data);
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
	}
	priv->fs->udata = card;
	priv->fs->listFile = _listFile;

	card->cla = 0xB0;

	card->flags |= SC_CARD_FLAG_RNG;
	card->caps |= SC_CARD_CAP_RNG;

	/* Card type detection */
	_sc_match_atr(card, muscle_atrs, &card->type);
	if(card->type == SC_CARD_TYPE_MUSCLE_ETOKEN_72K) {
		card->caps |= SC_CARD_CAP_APDU_EXT;
	}
	if(card->type == SC_CARD_TYPE_MUSCLE_JCOP241) {
		card->caps |= SC_CARD_CAP_APDU_EXT;
	}
	if (!(card->caps & SC_CARD_CAP_APDU_EXT)) {
		card->max_recv_size = 255;
		card->max_send_size = 255;
	}
	if(card->type == SC_CARD_TYPE_MUSCLE_JCOP242R2_NO_EXT_APDU) {
	        /* Tyfone JCOP v242R2 card that doesn't support extended APDUs */
	}


	/* FIXME: Card type detection */
	if (1) {
		unsigned long flags;

		flags = SC_ALGORITHM_RSA_RAW;
		flags |= SC_ALGORITHM_RSA_HASH_NONE;
		flags |= SC_ALGORITHM_ONBOARD_KEY_GEN;

		_sc_card_add_rsa_alg(card, 1024, flags, 0);
		_sc_card_add_rsa_alg(card, 2048, flags, 0);
	}
	return SC_SUCCESS;
}

Project: OpenSC
File: sc.c

size_t sc_right_trim(u8 *buf, size_t len) {

	size_t i;

	if (!buf)
		return 0;

	if (len > 0) {
		for(i = len-1; i > 0; i--) {
			if(!isprint(buf[i])) {
				buf[i] = '\0';
				len--;
				continue;
			}
			break;
		}
	}
	return len;
}

Project: OpenSC
File: sc.c

int sc_bin_to_hex(const u8 *in, size_t in_len, char *out, size_t out_len,
		  int in_sep)
{
	unsigned int	n, sep_len;
	char		*pos, *end, sep;

	sep = (char)in_sep;
	sep_len = sep > 0 ? 1 : 0;
	pos = out;
	end = out + out_len;
	for (n = 0; n < in_len; n++) {
		if (pos + 3 + sep_len >= end)
			return SC_ERROR_BUFFER_TOO_SMALL;
		if (n && sep_len)
			*pos++ = sep;
		sprintf(pos, "%02x", in[n]);
		pos += 2;
	}
	*pos = '\0';
	return SC_SUCCESS;
}

Project: OpenSC
File: util.c

util_get_pin(const char *input, const char **pin)
{
	size_t inputlen = strlen(input);
	size_t pinlen = 0;

	if(inputlen > 4 && strncasecmp(input, "env:", 4) == 0) {
		// Get a PIN from a environment variable
		*pin = getenv(input + 4);
		pinlen = *pin ? strlen(*pin) : 0;
	} else {
		//Just use the input
		*pin = input;
		pinlen = inputlen;
	}
	return pinlen;
}

Project: OpenSC
File: card-cac.c

static int cac_apdu_io(sc_card_t *card, int ins, int p1, int p2,
	const u8 * sendbuf, size_t sendbuflen, u8 ** recvbuf,
	size_t * recvbuflen)
{
	int r;
	sc_apdu_t apdu;
	u8 rbufinitbuf[CAC_MAX_SIZE];
	u8 *rbuf;
	size_t rbuflen;
	unsigned int apdu_case = SC_APDU_CASE_1;


	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
		 "%02x %02x %02x %"SC_FORMAT_LEN_SIZE_T"u : %"SC_FORMAT_LEN_SIZE_T"u %"SC_FORMAT_LEN_SIZE_T"u\n",
		 ins, p1, p2, sendbuflen, card->max_send_size,
		 card->max_recv_size);

	rbuf = rbufinitbuf;
	rbuflen = sizeof(rbufinitbuf);

	/* if caller provided a buffer and length */
	if (recvbuf && *recvbuf && recvbuflen && *recvbuflen) {
		rbuf = *recvbuf;
		rbuflen = *recvbuflen;
	}

	if (recvbuf) {
		if (sendbuf)
			apdu_case = SC_APDU_CASE_4_SHORT;
		else
			apdu_case = SC_APDU_CASE_2_SHORT;
	} else if (sendbuf)
		apdu_case = SC_APDU_CASE_3_SHORT;


	sc_format_apdu(card, &apdu, apdu_case, ins, p1, p2);

	apdu.lc = sendbuflen;
	apdu.datalen = sendbuflen;
	apdu.data = sendbuf;

	if (recvbuf) {
		apdu.resp = rbuf;
		apdu.le = (rbuflen > 255) ? 255 : rbuflen;
		apdu.resplen = rbuflen;
	} else {
		 apdu.resp =  rbuf;
		 apdu.le = 0;
		 apdu.resplen = 0;
	}

	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
		 "calling sc_transmit_apdu flags=%lx le=%"SC_FORMAT_LEN_SIZE_T"u, resplen=%"SC_FORMAT_LEN_SIZE_T"u, resp=%p",
		 apdu.flags, apdu.le, apdu.resplen, apdu.resp);

	/* with new adpu.c and chaining, this actually reads the whole object */
	r = sc_transmit_apdu(card, &apdu);

	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
		 "result r=%d apdu.resplen=%"SC_FORMAT_LEN_SIZE_T"u sw1=%02x sw2=%02x",
		 r, apdu.resplen, apdu.sw1, apdu.sw2);
	if (r < 0) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"Transmit failed");
		goto err;
	}

	r = sc_check_sw(card, apdu.sw1, apdu.sw2);

	if (r < 0) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Card returned error ");
		goto err;
	}

	if (recvbuflen) {
		if (recvbuf && *recvbuf == NULL) {
			*recvbuf =  malloc(apdu.resplen);
			if (*recvbuf == NULL) {
				r = SC_ERROR_OUT_OF_MEMORY;
				goto err;
			}
			memcpy(*recvbuf, rbuf, apdu.resplen);
		}
		*recvbuflen =  apdu.resplen;
		r = *recvbuflen;
	}

err:
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
}

Project: OpenSC
File: card-cac.c

static int cac_parse_aid(sc_card_t *card, cac_private_data_t *priv, u8 *aid, int aid_len)
{
	cac_object_t new_object;
	cac_properties_t prop;
	size_t i;
	int r;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	/* Search for PKI applets (7 B). Ignore generic objects for now */
	if (aid_len != 7 || (memcmp(aid, CAC_1_RID "\x01", 6) != 0
	    && memcmp(aid, CAC_1_RID "\x00", 6) != 0))
		return SC_SUCCESS;

	sc_mem_clear(&new_object.path, sizeof(sc_path_t));
	memcpy(new_object.path.aid.value, aid, aid_len);
	new_object.path.aid.len = aid_len;

	/* Call without OID set will just select the AID without subseqent
	 * OID selection, which we need to figure out just now
	 */
	cac_select_file_by_type(card, &new_object.path, NULL, SC_CARD_TYPE_CAC_II);
	r = cac_get_properties(card, &prop);
	if (r < 0)
		return SC_ERROR_INTERNAL;

	for (i = 0; i < prop.num_objects; i++) {
		/* don't fail just because we have more certs than we can support */
		if (priv->cert_next >= MAX_CAC_SLOTS)
			return SC_SUCCESS;

		sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
		    "ACA: pki_object found, cert_next=%d (%s), privkey=%d",
		    priv->cert_next, cac_labels[priv->cert_next],
		    prop.objects[i].privatekey);

		/* If the private key is not initialized, we can safely
		 * ignore this object here, but increase the pointer to follow
		 * the certificate labels
		 */
		if (!prop.objects[i].privatekey) {
			priv->cert_next++;
			continue;
		}

		/* OID here has always 2B */
		memcpy(new_object.path.value, &prop.objects[i].oid, 2);
		new_object.path.len = 2;
		new_object.path.type = SC_PATH_TYPE_FILE_ID;
		new_object.name = cac_labels[priv->cert_next];
		new_object.fd = priv->cert_next+1;
		cac_add_object_to_list(&priv->pki_list, &new_object);
		priv->cert_next++;
	}

	return SC_SUCCESS;
}

Project: OpenSC
File: pkcs15-gemsafeV1.c

static int gemsafe_get_cert_len(sc_card_t *card)
{
	int r;
	u8  ibuf[GEMSAFE_MAX_OBJLEN];
	u8 *iptr;
	struct sc_path path;
	struct sc_file *file;
	size_t objlen, certlen;
	unsigned int ind, i=0;

	sc_format_path(GEMSAFE_PATH, &path);
	r = sc_select_file(card, &path, &file);
	if (r != SC_SUCCESS || !file)
		return SC_ERROR_INTERNAL;

	/* Initial read */
	r = sc_read_binary(card, 0, ibuf, GEMSAFE_READ_QUANTUM, 0);
	if (r < 0)
		return SC_ERROR_INTERNAL;

	/* Actual stored object size is encoded in first 2 bytes
	 * (allocated EF space is much greater!)
	 */
	objlen = (((size_t) ibuf[0]) << 8) | ibuf[1];
	sc_log(card->ctx, "Stored object is of size: %"SC_FORMAT_LEN_SIZE_T"u",
	       objlen);
	if (objlen < 1 || objlen > GEMSAFE_MAX_OBJLEN) {
	    sc_log(card->ctx, "Invalid object size: %"SC_FORMAT_LEN_SIZE_T"u",
		   objlen);
	    return SC_ERROR_INTERNAL;
	}

	/* It looks like the first thing in the block is a table of
	 * which keys are allocated. The table is small and is in the
	 * first 248 bytes. Example for a card with 10 key containers:
	 * 01 f0 00 03 03 b0 00 03     <=  1st key unallocated
	 * 01 f0 00 04 03 b0 00 04     <=  2nd key unallocated
	 * 01 fe 14 00 05 03 b0 00 05  <=  3rd key allocated
	 * 01 fe 14 01 06 03 b0 00 06  <=  4th key allocated
	 * 01 f0 00 07 03 b0 00 07     <=  5th key unallocated
	 * ...
	 * 01 f0 00 0c 03 b0 00 0c     <= 10th key unallocated
	 * For allocated keys, the fourth byte seems to indicate the
	 * default key and the fifth byte indicates the key_ref of
	 * the private key.
	 */
	ind = 2; /* skip length */
	while (ibuf[ind] == 0x01 && i < gemsafe_cert_max) {
		if (ibuf[ind+1] == 0xFE) {
			gemsafe_prkeys[i].ref = ibuf[ind+4];
			sc_log(card->ctx, "Key container %d is allocated and uses key_ref %d",
					i+1, gemsafe_prkeys[i].ref);
			ind += 9;
		}
		else {
			gemsafe_prkeys[i].label = NULL;
			gemsafe_cert[i].label = NULL;
			sc_log(card->ctx, "Key container %d is unallocated", i+1);
			ind += 8;
		}
		i++;
	}

	/* Delete additional key containers from the data structures if
	 * this card can't accommodate them.
	 */
	for (; i < gemsafe_cert_max; i++) {
		gemsafe_prkeys[i].label = NULL;
		gemsafe_cert[i].label = NULL;
	}

	/* Read entire file, then dissect in memory.
	 * Gemalto ClassicClient seems to do it the same way.
	 */
	iptr = ibuf + GEMSAFE_READ_QUANTUM;
	while ((size_t)(iptr - ibuf) < objlen) {
		r = sc_read_binary(card, iptr - ibuf, iptr,
				   MIN(GEMSAFE_READ_QUANTUM, objlen - (iptr - ibuf)), 0);
		if (r < 0) {
			sc_log(card->ctx, "Could not read cert object");
			return SC_ERROR_INTERNAL;
		}
		iptr += GEMSAFE_READ_QUANTUM;
	}

	/* Search buffer for certificates, they start with 0x3082. */
	i = 0;
	while (ind < objlen - 1) {
		if (ibuf[ind] == 0x30 && ibuf[ind+1] == 0x82) {
			/* Find next allocated key container */
			while (i < gemsafe_cert_max && gemsafe_cert[i].label == NULL)
				i++;
			if (i == gemsafe_cert_max) {
				sc_log(card->ctx, "Warning: Found orphaned certificate at offset %d", ind);
				return SC_SUCCESS;
			}
			/* DER cert len is encoded this way */
			if (ind+3 >= sizeof ibuf)
				return SC_ERROR_INVALID_DATA;
			certlen = ((((size_t) ibuf[ind+2]) << 8) | ibuf[ind+3]) + 4;
			sc_log(card->ctx,
			       "Found certificate of key container %d at offset %d, len %"SC_FORMAT_LEN_SIZE_T"u",
			       i+1, ind, certlen);
			gemsafe_cert[i].index = ind;
			gemsafe_cert[i].count = certlen;
			ind += certlen;
			i++;
		} else
			ind++;
	}

	/* Delete additional key containers from the data structures if
	 * they're missing on the card.
	 */
	for (; i < gemsafe_cert_max; i++) {
		if (gemsafe_cert[i].label) {
			sc_log(card->ctx, "Warning: Certificate of key container %d is missing", i+1);
			gemsafe_prkeys[i].label = NULL;
			gemsafe_cert[i].label = NULL;
		}
	}

	return SC_SUCCESS;
}

Project: OpenSC
File: card-muscle.c

static int muscle_delete_file(sc_card_t *card, const sc_path_t *path_in)
{
	mscfs_t *fs = MUSCLE_FS(card);
	mscfs_file_t *file_data = NULL;
	int r = 0;

	r = mscfs_loadFileInfo(fs, path_in->value, path_in->len, &file_data, NULL);
	if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r);
	r = muscle_delete_mscfs_file(card, file_data);
	mscfs_clear_cache(fs);
	if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r);
	return 0;
}

Project: OpenSC
File: pkcs15-sc-hsm.c

static int sc_pkcs15emu_sc_hsm_add_dcod(sc_pkcs15_card_t * p15card, u8 id) {

	sc_card_t *card = p15card->card;
	sc_pkcs15_data_info_t *data_info;
	sc_pkcs15_object_t data_obj;
	u8 fid[2];
	u8 efbin[512];
	const u8 *ptr;
	size_t len;
	int r;

	fid[0] = DCOD_PREFIX;
	fid[1] = id;

	/* Try to select a related EF containing the PKCS#15 description of the data */
	len = sizeof efbin;
	r = read_file(p15card, fid, efbin, &len, 1);
	LOG_TEST_RET(card->ctx, r, "Skipping optional EF.DCOD");

	ptr = efbin;

	memset(&data_obj, 0, sizeof(data_obj));
	r = sc_pkcs15_decode_dodf_entry(p15card, &data_obj, &ptr, &len);
	LOG_TEST_RET(card->ctx, r, "Could not decode optional EF.DCOD");

	data_info = (sc_pkcs15_data_info_t *)data_obj.data;

	r = sc_pkcs15emu_add_data_object(p15card, &data_obj, data_info);

	LOG_TEST_RET(card->ctx, r, "Could not add data object to framework");

	return SC_SUCCESS;
}

Project: OpenSC
File: card-muscle.c

static struct sc_card_driver * sc_get_driver(void)
{
	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
	if (iso_ops == NULL)
		iso_ops = iso_drv->ops;

	muscle_ops = *iso_drv->ops;
	muscle_ops.check_sw = muscle_check_sw;
	muscle_ops.pin_cmd = muscle_pin_cmd;
	muscle_ops.match_card = muscle_match_card;
	muscle_ops.init = muscle_init;
	muscle_ops.finish = muscle_finish;

	muscle_ops.get_challenge = muscle_get_challenge;

	muscle_ops.set_security_env = muscle_set_security_env;
	muscle_ops.restore_security_env = muscle_restore_security_env;
	muscle_ops.compute_signature = muscle_compute_signature;
	muscle_ops.decipher = muscle_decipher;
	muscle_ops.card_ctl = muscle_card_ctl;
	muscle_ops.read_binary = muscle_read_binary;
	muscle_ops.update_binary = muscle_update_binary;
	muscle_ops.create_file = muscle_create_file;
	muscle_ops.select_file = muscle_select_file;
	muscle_ops.delete_file = muscle_delete_file;
	muscle_ops.list_files = muscle_list_files;
	muscle_ops.card_reader_lock_obtained = muscle_card_reader_lock_obtained;

	return &muscle_drv;
}

Project: OpenSC
File: sc.c

int sc_file_add_acl_entry(sc_file_t *file, unsigned int operation,
                          unsigned int method, unsigned long key_ref)
{
	sc_acl_entry_t *p, *_new;

	if (file == NULL || operation >= SC_MAX_AC_OPS) {
		return SC_ERROR_INVALID_ARGUMENTS;
	}

	switch (method) {
	case SC_AC_NEVER:
		sc_file_clear_acl_entries(file, operation);
		file->acl[operation] = (sc_acl_entry_t *) 1;
		return SC_SUCCESS;
	case SC_AC_NONE:
		sc_file_clear_acl_entries(file, operation);
		file->acl[operation] = (sc_acl_entry_t *) 2;
		return SC_SUCCESS;
	case SC_AC_UNKNOWN:
		sc_file_clear_acl_entries(file, operation);
		file->acl[operation] = (sc_acl_entry_t *) 3;
		return SC_SUCCESS;
	default:
		/* NONE and UNKNOWN get zapped when a new AC is added.
		 * If the ACL is NEVER, additional entries will be
		 * dropped silently. */
		if (file->acl[operation] == (sc_acl_entry_t *) 1)
			return SC_SUCCESS;
		if (file->acl[operation] == (sc_acl_entry_t *) 2
		 || file->acl[operation] == (sc_acl_entry_t *) 3)
			file->acl[operation] = NULL;
	}

	/* If the entry is already present (e.g. due to the mapping)
	 * of the card's AC with OpenSC's), don't add it again. */
	for (p = file->acl[operation]; p != NULL; p = p->next) {
		if ((p->method == method) && (p->key_ref == key_ref))
			return SC_SUCCESS;
	}

	_new = malloc(sizeof(sc_acl_entry_t));
	if (_new == NULL)
		return SC_ERROR_OUT_OF_MEMORY;
	_new->method = method;
	_new->key_ref = key_ref;
	_new->next = NULL;

	p = file->acl[operation];
	if (p == NULL) {
		file->acl[operation] = _new;
		return SC_SUCCESS;
	}
	while (p->next != NULL)
		p = p->next;
	p->next = _new;

	return SC_SUCCESS;
}

Project: OpenSC
File: cryptoflex-tool.c

static int create_pin(void)
{
	sc_path_t path;
	char buf[80];

	if (opt_pin_num != 1 && opt_pin_num != 2) {
		fprintf(stderr, "Invalid PIN number. Possible values: 1, 2.\n");
		return 2;
	}
	strcpy(buf, "3F00");
	if (opt_appdf != NULL)
		strlcat(buf, opt_appdf, sizeof buf);
	sc_format_path(buf, &path);

	return create_pin_file(&path, opt_pin_num, "");
}

Project: OpenSC
File: sc.c

void sc_init_oid(struct sc_object_id *oid)
{
	int ii;

	if (!oid)
		return;
	for (ii=0; ii<SC_MAX_OBJECT_ID_OCTETS; ii++)
		oid->value[ii] = -1;
}

Project: OpenSC
File: sc.c

sc_file_t * sc_file_new(void)
{
	sc_file_t *file = (sc_file_t *)calloc(1, sizeof(sc_file_t));
	if (file == NULL)
		return NULL;

	file->magic = SC_FILE_MAGIC;
	return file;
}

Project: OpenSC
File: card-cac.c

static int cac_add_object_to_list(list_t *list, const cac_object_t *object)
{
	if (list_append(list, object) < 0)
		return SC_ERROR_UNKNOWN;
	return SC_SUCCESS;
}

Project: OpenSC
File: card-epass2003.c

internal_write_rsa_key(struct sc_card *card, unsigned short fid, struct sc_pkcs15_prkey_rsa *rsa)
{
	int r;

	LOG_FUNC_CALLED(card->ctx);

	r = internal_write_rsa_key_factor(card, fid, 0x02, rsa->modulus);
	LOG_TEST_RET(card->ctx, r, "write n failed");
	r = internal_write_rsa_key_factor(card, fid, 0x03, rsa->d);
	LOG_TEST_RET(card->ctx, r, "write d failed");

	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}

Project: OpenSC
File: card-epass2003.c

internal_write_rsa_key_factor(struct sc_card *card, unsigned short fid, u8 factor,
		sc_pkcs15_bignum_t data)
{
	int r;
	struct sc_apdu apdu;
	u8 sbuff[SC_MAX_EXT_APDU_BUFFER_SIZE] = { 0 };

	LOG_FUNC_CALLED(card->ctx);

	sbuff[0] = ((fid & 0xff00) >> 8);
	sbuff[1] = (fid & 0x00ff);
	memcpy(&sbuff[2], data.data, data.len);
//	sc_mem_reverse(&sbuff[2], data.len);

	sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xe7, factor, 0x00);
	apdu.cla = 0x80;
	apdu.lc = apdu.datalen = 2 + data.len;
	apdu.data = sbuff;

	r = sc_transmit_apdu_t(card, &apdu);
	LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	LOG_TEST_RET(card->ctx, r, "Write rsa key factor failed");

	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}

Project: OpenSC
File: card-muscle.c

static int muscle_read_binary(sc_card_t *card, unsigned int idx, u8* buf, size_t count, unsigned long flags)
{
	mscfs_t *fs = MUSCLE_FS(card);
	int r;
	msc_id objectId;
	u8* oid = objectId.id;
	mscfs_file_t *file;

	r = mscfs_check_selection(fs, -1);
	if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
	file = &fs->cache.array[fs->currentFileIndex];
	objectId = file->objectId;
	/* memcpy(objectId.id, file->objectId.id, 4); */
	if(!file->ef) {
		oid[0] = oid[2];
		oid[1] = oid[3];
		oid[2] = oid[3] = 0;
	}
	r = msc_read_object(card, objectId, idx, buf, count);
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
}

Project: OpenSC
File: sc.c

void sc_mem_clear(void *ptr, size_t len)
{
	if (len > 0)   {
#ifdef ENABLE_OPENSSL
		OPENSSL_cleanse(ptr, len);
#else
		memset(ptr, 0, len);
#endif
	}
}

Project: OpenSC
File: util.c

util_connect_card(sc_context_t *ctx, sc_card_t **cardp,
		 const char *reader_id, int do_wait, int verbose)
{
	return util_connect_card_ex(ctx, cardp, reader_id, do_wait, 1, verbose);
}

Project: OpenSC
File: card-cac.c

static const cac_object_t *cac_find_obj_by_id(unsigned short object_id)
{
	int i;

	for (i = 0; i < cac_object_count; i++) {
		if (cac_objects[i].fd == object_id) {
			return &cac_objects[i];
		}
	}
	return NULL;
}

Project: OpenSC
File: card-epass2003.c

verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_type)
{
	int r;
	struct sc_apdu apdu;
	unsigned long blocksize = (key_type == KEY_TYPE_AES ? 16 : 8);
	unsigned char data[256] = { 0 };
	unsigned char cryptogram[256] = { 0 };	/* host cryptogram */
	unsigned char iv[16] = { 0 };
	unsigned char mac[256] = { 0 };
	unsigned long i;
	unsigned char tmp_sm;
	epass2003_exdata *exdata = NULL;

	if (!card->drv_data) 
		return SC_ERROR_INVALID_ARGUMENTS;
	exdata = (epass2003_exdata *)card->drv_data;

	LOG_FUNC_CALLED(card->ctx);

	memcpy(data, ran_key, 8);
	memcpy(&data[8], g_random, 8);
	data[16] = 0x80;
	memset(&data[17], 0x00, blocksize - 1);
	memset(iv, 0, 16);

	/* calculate host cryptogram */
	if (KEY_TYPE_AES == key_type) {
		aes128_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize,
				   cryptogram);
	} else {
		des3_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize,
				 cryptogram);
	}

	memset(data, 0, sizeof(data));
	memcpy(data, "\x84\x82\x03\x00\x10", 5);
	memcpy(&data[5], &cryptogram[16], 8);
	memcpy(&data[13], "\x80\x00\x00", 3);

	/* calculate mac icv */
	memset(iv, 0x00, 16);
	if (KEY_TYPE_AES == key_type) {
		aes128_encrypt_cbc(exdata->sk_mac, 16, iv, data, 16, mac);
		i = 0;
	} else {
		des3_encrypt_cbc(exdata->sk_mac, 16, iv, data, 16, mac);
		i = 8;
	}
	/* save mac icv */
	memset(exdata->icv_mac, 0x00, 16);
	memcpy(exdata->icv_mac, &mac[i], 8);

	/* verify host cryptogram */
	memcpy(data, &cryptogram[16], 8);
	memcpy(&data[8], &mac[i], 8);
	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x03, 0x00);
	apdu.cla = 0x84;
	apdu.lc = apdu.datalen = 16;
	apdu.data = data;
	tmp_sm = exdata->sm;
	exdata->sm = SM_PLAIN;
	r = epass2003_transmit_apdu(card, &apdu);
	exdata->sm = tmp_sm;
	LOG_TEST_RET(card->ctx, r,
		    "APDU verify_init_key failed");
	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	LOG_TEST_RET(card->ctx, r,
		    "verify_init_key failed");
	return r;
}

Project: OpenSC
File: card-epass2003.c

epass2003_list_files(struct sc_card *card, unsigned char *buf, size_t buflen)
{
	struct sc_apdu apdu;
	unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE] = { 0 };
	int r;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
	sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x34, 0x00, 0x00);
	apdu.cla = 0x80;
	apdu.le = 0;
	apdu.resplen = sizeof(rbuf);
	apdu.resp = rbuf;

	r = sc_transmit_apdu_t(card, &apdu);
	LOG_TEST_RET(card->ctx, r, "APDU transmit failed");

	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	LOG_TEST_RET(card->ctx, r, "Card returned error");

	if (apdu.resplen == 0x100 && rbuf[0] == 0 && rbuf[1] == 0)
		LOG_FUNC_RETURN(card->ctx, 0);

	buflen = buflen < apdu.resplen ? buflen : apdu.resplen;
	memcpy(buf, rbuf, buflen);

	LOG_FUNC_RETURN(card->ctx, buflen);
}

Project: OpenSC
File: card-tcos.c

static int tcos_init(sc_card_t *card)
{
        unsigned long flags;

	tcos_data *data = malloc(sizeof(tcos_data));
	if (!data) return SC_ERROR_OUT_OF_MEMORY;

	card->name = "TCOS";
	card->drv_data = (void *)data;
	card->cla = 0x00;

        flags = SC_ALGORITHM_RSA_RAW;
        flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
        flags |= SC_ALGORITHM_RSA_HASH_NONE;

        _sc_card_add_rsa_alg(card, 512, flags, 0);
        _sc_card_add_rsa_alg(card, 768, flags, 0);
        _sc_card_add_rsa_alg(card, 1024, flags, 0);

	if (card->type == SC_CARD_TYPE_TCOS_V3) {
		card->caps |= SC_CARD_CAP_APDU_EXT;
		_sc_card_add_rsa_alg(card, 1280, flags, 0);
		_sc_card_add_rsa_alg(card, 1536, flags, 0);
		_sc_card_add_rsa_alg(card, 1792, flags, 0);
        	_sc_card_add_rsa_alg(card, 2048, flags, 0);
	}

	return 0;
}

Project: OpenSC
File: cryptoflex-tool.c

static int read_private_key(RSA *rsa)
{
	int r;
	sc_path_t path;
	sc_file_t *file;
	const sc_acl_entry_t *e;

	u8 buf[2048], *p = buf;
	size_t bufsize, keysize;

	r = select_app_df();
	if (r)
		return 1;
	sc_format_path("I0012", &path);
	r = sc_select_file(card, &path, &file);
	if (r) {
		fprintf(stderr, "Unable to select private key file: %s\n", sc_strerror(r));
		return 2;
	}
	e = sc_file_get_acl_entry(file, SC_AC_OP_READ);
	if (e == NULL || e->method == SC_AC_NEVER)
		return 10;
	bufsize = MIN(file->size, sizeof buf);
	sc_file_free(file);
	r = sc_read_binary(card, 0, buf, bufsize, 0);
	if (r < 0) {
		fprintf(stderr, "Unable to read private key file: %s\n", sc_strerror(r));
		return 2;
	}
	bufsize = r;
	do {
		if (bufsize < 4)
			return 3;
		keysize = (p[0] << 8) | p[1];
		if (keysize == 0)
			break;
		if (keysize < 3)
			return 3;
		if (p[2] == opt_key_num)
			break;
		p += keysize;
		bufsize -= keysize;
	} while (1);
	if (keysize == 0) {
		printf("Key number %d not found.\n", opt_key_num);
		return 2;
	}
	return parse_private_key(p, keysize, rsa);
}

Project: OpenSC
File: util.c

util_fatal(const char *fmt, ...)
{
	va_list	ap;

	va_start(ap, fmt);
	fprintf(stderr, "error: ");
	vfprintf(stderr, fmt, ap);
	fprintf(stderr, "\nAborting.\n");
	va_end(ap);

	sc_notify_close();

	exit(1);
}

Project: OpenSC
File: sc.c

unsigned sc_crc32(const unsigned char *value, size_t len)
{
	size_t ii, jj;
	unsigned long crc;
	unsigned long index, long_c;

	if (!sc_CRC_tab32_initialized)   {
		for (ii=0; ii<256; ii++) {
			crc = (unsigned long) ii;
			for (jj=0; jj<8; jj++) {
				if ( crc & 0x00000001L )
					crc = ( crc >> 1 ) ^ 0xEDB88320l;
				else
					crc =   crc >> 1;
			}
			sc_CRC_tab32[ii] = crc;
		}
		sc_CRC_tab32_initialized = 1;
	}

	crc = 0xffffffffL;
	for (ii=0; ii<len; ii++)   {
		long_c = 0x000000ffL & (unsigned long) (*(value + ii));
		index = crc ^ long_c;
		crc = (crc >> 8) ^ sc_CRC_tab32[ index & 0xff ];
	}

	crc ^= 0xffffffff;
	return  crc%0xffff;
}

Project: OpenSC
File: card-epass2003.c

epass2003_select_file(struct sc_card *card, const sc_path_t * in_path,
		sc_file_t ** file_out)
{
	int r;
	char pbuf[SC_MAX_PATH_STRING_SIZE];

	LOG_FUNC_CALLED(card->ctx);

	r = sc_path_print(pbuf, sizeof(pbuf), &card->cache.current_path);
	if (r != SC_SUCCESS)
		pbuf[0] = '\0';

	sc_log(card->ctx,
	       "current path (%s, %s): %s (len: %"SC_FORMAT_LEN_SIZE_T"u)\n",
	       card->cache.current_path.type == SC_PATH_TYPE_DF_NAME ?
	       "aid" : "path",
	       card->cache.valid ? "valid" : "invalid", pbuf,
	       card->cache.current_path.len);

	switch (in_path->type) {
	case SC_PATH_TYPE_FILE_ID:
		if (in_path->len != 2)
			LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
		return epass2003_select_fid(card, in_path->value[0], in_path->value[1], file_out);
	case SC_PATH_TYPE_DF_NAME:
		return epass2003_select_aid(card, in_path, file_out);
	case SC_PATH_TYPE_PATH:
		return epass2003_select_path(card, in_path->value, in_path->len, file_out);
	default:
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
	}
}

Project: OpenSC
File: card-epass2003.c

epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
{
	int r;
	u8 kid;
	u8 retries = 0;
	u8 pin_low = 3;
	unsigned char maxtries = 0;

	LOG_FUNC_CALLED(card->ctx);

	internal_sanitize_pin_info(&data->pin1, 0);
	internal_sanitize_pin_info(&data->pin2, 1);
	data->flags |= SC_PIN_CMD_NEED_PADDING;
	kid = data->pin_reference;
	/* get pin retries */
	if (data->cmd == SC_PIN_CMD_GET_INFO) {

		r = get_external_key_retries(card, 0x80 | kid, &retries);
		if (r == SC_SUCCESS) {
			data->pin1.tries_left = retries;
			if (tries_left)
				*tries_left = retries;

			r = get_external_key_maxtries(card, &maxtries);
			LOG_TEST_RET(card->ctx, r, "get max counter failed");

			data->pin1.max_tries = maxtries;
		}
//remove below code, because the old implement only return PIN retries, now modify the code and return PIN status
//		return r;
	}
	else if (data->cmd == SC_PIN_CMD_UNBLOCK) { /* verify */
		r = external_key_auth(card, (kid + 1), (unsigned char *)data->pin1.data,
				data->pin1.len);
		LOG_TEST_RET(card->ctx, r, "verify pin failed");
	}
	else if (data->cmd == SC_PIN_CMD_CHANGE || data->cmd == SC_PIN_CMD_UNBLOCK) { /* change */
		r = update_secret_key(card, 0x04, kid, data->pin2.data,
				(unsigned long)data->pin2.len);
		LOG_TEST_RET(card->ctx, r, "verify pin failed");
	}
	else {
		r = external_key_auth(card, kid, (unsigned char *)data->pin1.data,
				data->pin1.len);
		get_external_key_retries(card, 0x80 | kid, &retries);
		if (retries < pin_low)
			sc_log(card->ctx, "Verification failed (remaining tries: %d)", retries);

	}
	LOG_TEST_RET(card->ctx, r, "verify pin failed");

	if (r == SC_SUCCESS)
	{
		data->pin1.logged_in = SC_PIN_STATE_LOGGED_IN;
	}

	return r;
}

Project: OpenSC
File: card-epass2003.c

epass2003_sm_wrap_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm)
{
	unsigned char buf[4096] = { 0 };	/* APDU buffer */
	size_t buf_len = sizeof(buf);
	epass2003_exdata *exdata = NULL;
	
	if (!card->drv_data) 
		return SC_ERROR_INVALID_ARGUMENTS;
	
	exdata = (epass2003_exdata *)card->drv_data;

	LOG_FUNC_CALLED(card->ctx);

	if (exdata->sm)
		plain->cla |= 0x0C;

	sm->cse = plain->cse;
	sm->cla = plain->cla;
	sm->ins = plain->ins;
	sm->p1 = plain->p1;
	sm->p2 = plain->p2;
	sm->lc = plain->lc;
	sm->le = plain->le;
	sm->control = plain->control;
	sm->flags = plain->flags;

	switch (sm->cla & 0x0C) {
	case 0x00:
	case 0x04:
		sm->datalen = plain->datalen;
		memcpy((void *)sm->data, plain->data, plain->datalen);
		sm->resplen = plain->resplen;
		memcpy(sm->resp, plain->resp, plain->resplen);
		break;
	case 0x0C:
		memset(buf, 0, sizeof(buf));
		if (0 != encode_apdu(card, plain, sm, buf, &buf_len))
			return SC_ERROR_CARD_CMD_FAILED;
		break;
	default:
		return SC_ERROR_INCORRECT_PARAMETERS;
	}

	return SC_SUCCESS;
}

Project: OpenSC
File: card-tcos.c

static int tcos_construct_fci(const sc_file_t *file,
                              u8 *out, size_t *outlen)
{
	u8 *p = out;
	u8 buf[64];
        size_t n;

        /* FIXME: possible buffer overflow */

        *p++ = 0x6F; /* FCI */
        p++;

	/* File size */
	buf[0] = (file->size >> 8) & 0xFF;
	buf[1] = file->size & 0xFF;
	sc_asn1_put_tag(0x81, buf, 2, p, 16, &p);

        /* File descriptor */
        n = 0;
	buf[n] = file->shareable ? 0x40 : 0;
	switch (file->type) {
	case SC_FILE_TYPE_WORKING_EF:
		break;
	case SC_FILE_TYPE_DF:
		buf[0] |= 0x38;
		break;
	default:
		return SC_ERROR_NOT_SUPPORTED;
	}
	buf[n++] |= file->ef_structure & 7;
        if ( (file->ef_structure & 7) > 1) {
                /* record structured file */
                buf[n++] = 0x41; /* indicate 3rd byte */
                buf[n++] = file->record_length;
        }
	sc_asn1_put_tag(0x82, buf, n, p, 8, &p);

        /* File identifier */
	buf[0] = (file->id >> 8) & 0xFF;
	buf[1] = file->id & 0xFF;
	sc_asn1_put_tag(0x83, buf, 2, p, 16, &p);

        /* Directory name */
        if (file->type == SC_FILE_TYPE_DF) {
                if (file->namelen) {
                        sc_asn1_put_tag(0x84, file->name, file->namelen,
                                        p, 16, &p);
                }
                else {
                        /* TCOS needs one, so we use a faked one */
                        snprintf ((char *) buf, sizeof(buf)-1, "foo-%lu",
                                  (unsigned long) time (NULL));
                        sc_asn1_put_tag(0x84, buf, strlen ((char *) buf), p, 16, &p);
                }
        }

        /* File descriptor extension */
        if (file->prop_attr_len && file->prop_attr) {
		n = file->prop_attr_len;
		memcpy(buf, file->prop_attr, n);
        }
        else {
                n = 0;
                buf[n++] = 0x01; /* not invalidated, permanent */
                if (file->type == SC_FILE_TYPE_WORKING_EF) 
                        buf[n++] = 0x00; /* generic data file */
        }
        sc_asn1_put_tag(0x85, buf, n, p, 16, &p);

        /* Security attributes */
	if (file->sec_attr_len && file->sec_attr) {
		memcpy(buf, file->sec_attr, file->sec_attr_len);
		n = file->sec_attr_len;
	}
        else {
                /* no attributes given - fall back to default one */
                memcpy (buf+ 0, "\xa4\x00\x00\x00\xff\xff", 6); /* select */
                memcpy (buf+ 6, "\xb0\x00\x00\x00\xff\xff", 6); /* read bin */
                memcpy (buf+12, "\xd6\x00\x00\x00\xff\xff", 6); /* upd bin */
                memcpy (buf+18, "\x60\x00\x00\x00\xff\xff", 6); /* admin grp*/
                n = 24;
        }
        sc_asn1_put_tag(0x86, buf, n, p, sizeof (buf), &p);

        
        /* fixup length of FCI */
        out[1] = p - out - 2;

	*outlen = p - out;
	return 0;
}

Project: OpenSC
File: egk-tool.c

int uncompress_gzip(void* uncompressed, size_t *uncompressed_len,
		const void* compressed, size_t compressed_len)
{
	z_stream stream;
	memset(&stream, 0, sizeof stream);
	stream.total_in = compressed_len;
	stream.avail_in = compressed_len;
	stream.total_out = *uncompressed_len;
	stream.avail_out = *uncompressed_len;
	stream.next_in = (Bytef *) compressed;
	stream.next_out = (Bytef *) uncompressed;

	/* 15 window bits, and the +32 tells zlib to to detect if using gzip or zlib */
	if (Z_OK == inflateInit2(&stream, (15 + 32))
			&& Z_STREAM_END == inflate(&stream, Z_FINISH)) {
		*uncompressed_len = stream.total_out;
	} else {
		return SC_ERROR_INVALID_DATA;
	}
	inflateEnd(&stream);

	return SC_SUCCESS;
}

Project: OpenSC
File: card-cac.c

static int cac_write_binary(sc_card_t *card, unsigned int idx,
		const u8 *buf, size_t count, unsigned long flags)
{

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED);
}

Project: OpenSC
File: cryptoflex-tool.c

static int update_public_key(const u8 *key, size_t keysize)
{
	int r, idx = 0;
	sc_path_t path;

	r = select_app_df();
	if (r)
		return 1;
	sc_format_path("I1012", &path);
	r = sc_select_file(card, &path, NULL);
	if (r) {
		fprintf(stderr, "Unable to select public key file: %s\n", sc_strerror(r));
		return 2;
	}
	idx = keysize * (opt_key_num-1);
	r = sc_update_binary(card, idx, key, keysize, 0);
	if (r < 0) {
		fprintf(stderr, "Unable to write public key: %s\n", sc_strerror(r));
		return 2;
	}
	return 0;
}

Project: OpenSC
File: sc.c

int sc_mutex_destroy(const sc_context_t *ctx, void *mutex)
{
	if (ctx == NULL)
		return SC_ERROR_INVALID_ARGUMENTS;
	if (ctx->thread_ctx != NULL && ctx->thread_ctx->destroy_mutex != NULL)
		return ctx->thread_ctx->destroy_mutex(mutex);
	else
		return SC_SUCCESS;
}

Project: OpenSC
File: util.c

void util_hex_dump(FILE *f, const u8 *in, int len, const char *sep)
{
	int i;

	for (i = 0; i < len; i++) {
		if (sep != NULL && i)
			fprintf(f, "%s", sep);
		fprintf(f, "%02X", in[i]);
	}
}

Project: OpenSC
File: card-epass2003.c

epass2003_sm_get_wrapped_apdu(struct sc_card *card,
		struct sc_apdu *plain, struct sc_apdu **sm_apdu)
{
	struct sc_context *ctx = card->ctx;
	struct sc_apdu *apdu = NULL;
	int rv;

	LOG_FUNC_CALLED(ctx);
	if (!plain || !sm_apdu)
		LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);

	*sm_apdu = NULL;
	//construct new SM apdu from original apdu
	apdu = calloc(1, sizeof(struct sc_apdu));
	if (!apdu) {
		rv = SC_ERROR_OUT_OF_MEMORY;
		goto err;
	}
	apdu->data = calloc (1, SC_MAX_EXT_APDU_BUFFER_SIZE);
	if (!apdu->data) {
		rv = SC_ERROR_OUT_OF_MEMORY;
		goto err;
	}
	apdu->resp = calloc (1, SC_MAX_EXT_APDU_BUFFER_SIZE);
	if (!apdu->resp) {
		rv = SC_ERROR_OUT_OF_MEMORY;
		goto err;
	}
	apdu->datalen = SC_MAX_EXT_APDU_BUFFER_SIZE;
	apdu->resplen = SC_MAX_EXT_APDU_BUFFER_SIZE;

	rv = epass2003_sm_wrap_apdu(card, plain, apdu);
	if (rv)   {
		rv = epass2003_sm_free_wrapped_apdu(card, NULL, &apdu);
		if (rv < 0)
			goto err;
	}

	*sm_apdu = apdu;
	apdu = NULL;
err:
	if (apdu) {
		free((unsigned char *) apdu->data);
		free(apdu->resp);
		free(apdu);
		apdu = NULL;
	}
	LOG_FUNC_RETURN(ctx, rv);
}

Project: OpenSC
File: card-cac.c

cac_get_acr(sc_card_t *card, int acr_type, u8 **out_buf, size_t *out_len)
{
	u8 *out = NULL;
	/* XXX assuming it will not be longer than 255 B */
	size_t len = 256;
	int r;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	/* for simplicity we support only ACR without arguments now */
	if (acr_type != 0x00 && acr_type != 0x10
	    && acr_type != 0x20 && acr_type != 0x21) {
		return SC_ERROR_INVALID_ARGUMENTS;
	}

	r = cac_apdu_io(card, CAC_INS_GET_ACR, acr_type, 0, NULL, 0, &out, &len);
	if (len == 0) {
		r = SC_ERROR_FILE_NOT_FOUND;
	}
	if (r < 0)
		goto fail;

	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
	    "got %"SC_FORMAT_LEN_SIZE_T"u bytes out=%p", len, out);

	*out_len = len;
	*out_buf = out;
	return SC_SUCCESS;

fail:
	if (out)
		free(out);
	*out_buf = NULL;
	*out_len = 0;
	return r;
}

Project: OpenSC
File: card-cac.c

static int cac_find_and_initialize(sc_card_t *card, int initialize)
{
	int r, index;
	cac_private_data_t *priv = NULL;

	/* already initialized? */
	if (card->drv_data) {
		return SC_SUCCESS;
	}

	/* is this a CAC-2 specified in NIST Interagency Report 6887 -
	 * "Government Smart Card Interoperability Specification v2.1 July 2003" */
	r = cac_select_CCC(card);
	if (r == SC_SUCCESS) {
		sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "CCC found, is CAC-2");
		if (!initialize) /* match card only */
			return r;

		priv = cac_new_private_data();
		if (!priv)
			return SC_ERROR_OUT_OF_MEMORY;
		r = cac_process_CCC(card, priv);
		if (r == SC_SUCCESS) {
			card->type = SC_CARD_TYPE_CAC_II;
			card->drv_data = priv;
			return r;
		}
	}

	/* Even some ALT tokens can be missing CCC so we should try with ACA */
	r = cac_select_ACA(card);
	if (r == SC_SUCCESS) {
		sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "ACA found, is CAC-2 without CCC");
		if (!initialize) /* match card only */
			return r;

		if (!priv) {
			priv = cac_new_private_data();
			if (!priv)
				return SC_ERROR_OUT_OF_MEMORY;
		}
		r = cac_process_ACA(card, priv);
		if (r == SC_SUCCESS) {
			card->type = SC_CARD_TYPE_CAC_II;
			card->drv_data = priv;
			return r;
		}
	}

	/* is this a CAC Alt token without any accompanying structures */
	r = cac_find_first_pki_applet(card, &index);
	if (r == SC_SUCCESS) {
		sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "PKI applet found, is bare CAC Alt");
		if (!initialize) /* match card only */
			return r;

		if (!priv) {
			priv = cac_new_private_data();
			if (!priv)
				return SC_ERROR_OUT_OF_MEMORY;
		}
		card->drv_data = priv; /* needed for the read_binary() */
		r = cac_populate_cac_alt(card, index, priv);
		if (r == SC_SUCCESS) {
			card->type = SC_CARD_TYPE_CAC_II;
			return r;
		}
		card->drv_data = NULL; /* reset on failure */
	}
	if (priv) {
		cac_free_private_data(priv);
	}
	return r;
}

Project: OpenSC
File: card-epass2003.c

epass2003_process_fci(struct sc_card *card, sc_file_t * file, const u8 * buf, size_t buflen)
{
	sc_context_t *ctx = card->ctx;
	size_t taglen, len = buflen;
	const u8 *tag = NULL, *p = buf;

	sc_log(ctx, "processing FCI bytes");
	tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen);
	if (tag != NULL && taglen == 2) {
		file->id = (tag[0] << 8) | tag[1];
		sc_log(ctx, "  file identifier: 0x%02X%02X", tag[0], tag[1]);
	}

	tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen);
	if (tag != NULL && taglen > 0 && taglen < 3) {
		file->size = tag[0];
		if (taglen == 2)
			file->size = (file->size << 8) + tag[1];
		sc_log(ctx, "  bytes in file: %"SC_FORMAT_LEN_SIZE_T"u",
		       file->size);
	}

	if (tag == NULL) {
		tag = sc_asn1_find_tag(ctx, p, len, 0x81, &taglen);
		if (tag != NULL && taglen >= 2) {
			int bytes = (tag[0] << 8) + tag[1];

			sc_log(ctx, "  bytes in file: %d", bytes);
			file->size = bytes;
		}
	}

	tag = sc_asn1_find_tag(ctx, p, len, 0x82, &taglen);
	if (tag != NULL) {
		if (taglen > 0) {
			unsigned char byte = tag[0];
			const char *type;

			if (byte == 0x38) {
				type = "DF";
				file->type = SC_FILE_TYPE_DF;
			}
			else if (0x01 <= byte && byte <= 0x07) {
				type = "working EF";
				file->type = SC_FILE_TYPE_WORKING_EF;
				switch (byte) {
				case 0x01:
					file->ef_structure = SC_FILE_EF_TRANSPARENT;
					break;
				case 0x02:
					file->ef_structure = SC_FILE_EF_LINEAR_FIXED;
					break;
				case 0x04:
					file->ef_structure = SC_FILE_EF_LINEAR_FIXED;
					break;
				case 0x03:
				case 0x05:
				case 0x06:
				case 0x07:
					break;
				default:
					break;
				}

			}
			else if (0x10 == byte) {
				type = "BSO";
				file->type = SC_FILE_TYPE_BSO;
			}
			else if (0x11 <= byte) {
				type = "internal EF";
				file->type = SC_FILE_TYPE_INTERNAL_EF;
				switch (byte) {
				case 0x11:
					break;
				case 0x12:
					break;
				default:
					break;
				}
			}
			else {
				type = "unknown";
				file->type = SC_FILE_TYPE_INTERNAL_EF;

			}
			sc_log(ctx, "type %s, EF structure %d", type, byte);
		}
	}

	tag = sc_asn1_find_tag(ctx, p, len, 0x84, &taglen);
	if (tag != NULL && taglen > 0 && taglen <= 16) {
		memcpy(file->name, tag, taglen);
		file->namelen = taglen;

		sc_log_hex(ctx, "File name", file->name, file->namelen);
		if (!file->type)
			file->type = SC_FILE_TYPE_DF;
	}

	tag = sc_asn1_find_tag(ctx, p, len, 0x85, &taglen);
	if (tag != NULL && taglen)
		sc_file_set_prop_attr(file, tag, taglen);
	else
		file->prop_attr_len = 0;

	tag = sc_asn1_find_tag(ctx, p, len, 0xA5, &taglen);
	if (tag != NULL && taglen)
		sc_file_set_prop_attr(file, tag, taglen);

	tag = sc_asn1_find_tag(ctx, p, len, 0x86, &taglen);
	if (tag != NULL && taglen)
		sc_file_set_sec_attr(file, tag, taglen);

	tag = sc_asn1_find_tag(ctx, p, len, 0x8A, &taglen);
	if (tag != NULL && taglen == 1) {
		if (tag[0] == 0x01)
			file->status = SC_FILE_STATUS_CREATION;
		else if (tag[0] == 0x07 || tag[0] == 0x05)
			file->status = SC_FILE_STATUS_ACTIVATED;
		else if (tag[0] == 0x06 || tag[0] == 0x04)
			file->status = SC_FILE_STATUS_INVALIDATED;
	}
	file->magic = SC_FILE_MAGIC;

	return 0;
}

Project: OpenSC
File: sc.c

u8 *ulong2bebytes(u8 *buf, unsigned long x)
{
	if (buf != NULL) {
		buf[3] = (u8) (x & 0xff);
		buf[2] = (u8) ((x >> 8) & 0xff);
		buf[1] = (u8) ((x >> 16) & 0xff);
		buf[0] = (u8) ((x >> 24) & 0xff);
	}
	return buf;
}

Project: OpenSC
File: card-epass2003.c

aes128_encrypt_ecb(const unsigned char *key, int keysize,
		const unsigned char *input, size_t length, unsigned char *output)
{
	unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 };
	return openssl_enc(EVP_aes_128_ecb(), key, iv, input, length, output);
}

Project: OpenSC
File: egk-tool.c

void dump_binary(void *buf, size_t buf_len)
{
#ifdef _WIN32
	_setmode(fileno(stdout), _O_BINARY);
#endif
	fwrite(buf, 1, buf_len, stdout);
#ifdef _WIN32
	_setmode(fileno(stdout), _O_TEXT);
#endif
}

Project: OpenSC
File: pkcs15-gemsafeV1.c

sc_pkcs15emu_add_pin(sc_pkcs15_card_t *p15card,
                const sc_pkcs15_id_t *id, const char *label,
                const sc_path_t *path, int ref, int type,
                unsigned int min_length,
                unsigned int max_length,
                int flags, int tries_left, const char pad_char, int obj_flags)
{
	sc_pkcs15_auth_info_t *info;

	info = calloc(1, sizeof(*info));
	if (!info)
		LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);

	info->auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
	info->auth_method = SC_AC_CHV;
	info->auth_id           = *id;
	info->attrs.pin.min_length        = min_length;
	info->attrs.pin.max_length        = max_length;
	info->attrs.pin.stored_length     = max_length;
	info->attrs.pin.type              = type;
	info->attrs.pin.reference         = ref;
	info->attrs.pin.flags             = flags;
	info->attrs.pin.pad_char          = pad_char;
	info->tries_left        = tries_left;
	info->logged_in = SC_PIN_STATE_UNKNOWN;

	if (path)
		info->path = *path;

	return sc_pkcs15emu_add_object(p15card, SC_PKCS15_TYPE_AUTH_PIN, label, info, NULL, obj_flags);
}

Project: OpenSC
File: card-epass2003.c

epass2003_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
{
	LOG_FUNC_CALLED(card->ctx);

	sc_log(card->ctx, "cmd is %0lx", cmd);
	switch (cmd) {
	case SC_CARDCTL_ENTERSAFE_WRITE_KEY:
		return epass2003_write_key(card, (sc_epass2003_wkey_data *) ptr);
	case SC_CARDCTL_ENTERSAFE_GENERATE_KEY:
		return epass2003_gen_key(card, (sc_epass2003_gen_key_data *) ptr);
	case SC_CARDCTL_ERASE_CARD:
		return epass2003_erase_card(card);
	case SC_CARDCTL_GET_SERIALNR:
		return epass2003_get_serialnr(card, (sc_serial_number_t *) ptr);
	default:
		return SC_ERROR_NOT_SUPPORTED;
	}
}

Project: OpenSC
File: card-cac.c

static int cac_fill_object_info(list_t *list, cac_object_t **entry, sc_pkcs15_data_info_t *obj_info)
{
	memset(obj_info, 0, sizeof(sc_pkcs15_data_info_t));
	if (*entry == NULL) {
		return SC_ERROR_FILE_END_REACHED;
	}

	obj_info->path = (*entry)->path;
	obj_info->path.count = CAC_MAX_SIZE-1; /* read something from the object */
	obj_info->id.value[0] = ((*entry)->fd >> 8) & 0xff;
	obj_info->id.value[1] = (*entry)->fd & 0xff;
	obj_info->id.len = 2;
	strncpy(obj_info->app_label, (*entry)->name, SC_PKCS15_MAX_LABEL_SIZE-1);
	*entry = list_iterator_next(list);
	return SC_SUCCESS;
}

Project: OpenSC
File: card-muscle.c

static int muscle_update_binary(sc_card_t *card, unsigned int idx, const u8* buf, size_t count, unsigned long flags)
{
	mscfs_t *fs = MUSCLE_FS(card);
	int r;
	mscfs_file_t *file;
	msc_id objectId;
	u8* oid = objectId.id;

	r = mscfs_check_selection(fs, -1);
	if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
	file = &fs->cache.array[fs->currentFileIndex];

	objectId = file->objectId;
	/* memcpy(objectId.id, file->objectId.id, 4); */
	if(!file->ef) {
		oid[0] = oid[2];
		oid[1] = oid[3];
		oid[2] = oid[3] = 0;
	}
	if(file->size < idx + count) {
		int newFileSize = idx + count;
		u8* buffer = malloc(newFileSize);
		if(buffer == NULL) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);

		r = msc_read_object(card, objectId, 0, buffer, file->size);
		/* TODO: RETRIEVE ACLS */
		if(r < 0) goto update_bin_free_buffer;
		r = msc_delete_object(card, objectId, 0);
		if(r < 0) goto update_bin_free_buffer;
		r = msc_create_object(card, objectId, newFileSize, 0,0,0);
		if(r < 0) goto update_bin_free_buffer;
		memcpy(buffer + idx, buf, count);
		r = msc_update_object(card, objectId, 0, buffer, newFileSize);
		if(r < 0) goto update_bin_free_buffer;
		file->size = newFileSize;
update_bin_free_buffer:
		free(buffer);
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
	} else {
		r = msc_update_object(card, objectId, idx, buf, count);
	}
	/* mscfs_clear_cache(fs); */
	return r;
}

Project: OpenSC
File: card-epass2003.c

sc_transmit_apdu_t(sc_card_t *card, sc_apdu_t *apdu)
{
	int r = sc_transmit_apdu(card, apdu);
	if ( ((0x69 == apdu->sw1) && (0x85 == apdu->sw2)) || ((0x69 == apdu->sw1) && (0x88 == apdu->sw2)))
	{
		epass2003_refresh(card);
		r = sc_transmit_apdu(card, apdu);
	}
	return r;
}

Project: OpenSC
File: card-epass2003.c

construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv_len, size_t le_tlv_len,
		unsigned char *mac_tlv, size_t * mac_tlv_len, const unsigned char key_type)
{
	size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8);
	unsigned char mac[4096] = { 0 };
	size_t mac_len;
	unsigned char icv[16] = { 0 };
	int i = (KEY_TYPE_AES == key_type ? 15 : 7);
	epass2003_exdata *exdata = NULL;

	if (!card->drv_data) 
		return SC_ERROR_INVALID_ARGUMENTS;

	exdata = (epass2003_exdata *)card->drv_data;

	if (0 == data_tlv_len && 0 == le_tlv_len) {
		mac_len = block_size;
	}
	else {
		/* padding */
		*(apdu_buf + block_size + data_tlv_len + le_tlv_len) = 0x80;
		if ((data_tlv_len + le_tlv_len + 1) % block_size)
			mac_len = (((data_tlv_len + le_tlv_len + 1) / block_size) +
					1) * block_size + block_size;

		else
			mac_len = data_tlv_len + le_tlv_len + 1 + block_size;

		memset((apdu_buf + block_size + data_tlv_len + le_tlv_len + 1),
		       0, (mac_len - (data_tlv_len + le_tlv_len + 1)));
	}

	/* increase icv */
	for (; i >= 0; i--) {
		if (exdata->icv_mac[i] == 0xff) {
			exdata->icv_mac[i] = 0;
		}
		else {
			exdata->icv_mac[i]++;
			break;
		}
	}

	/* calculate MAC */
	memset(icv, 0, sizeof(icv));
	memcpy(icv, exdata->icv_mac, 16);
	if (KEY_TYPE_AES == key_type) {
		aes128_encrypt_cbc(exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac);
		memcpy(mac_tlv + 2, &mac[mac_len - 16], 8);
	}
	else {
		unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 };
		unsigned char tmp[8] = { 0 };
		des_encrypt_cbc(exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac);
		des_decrypt_cbc(&exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp);
		memset(iv, 0x00, sizeof iv);
		des_encrypt_cbc(exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2);
	}

	*mac_tlv_len = 2 + 8;
	return 0;
}

Project: OpenSC
File: card-cac.c

static int cac_select_CCC(sc_card_t *card)
{
	return cac_select_file_by_type(card, &cac_CCC_Path, NULL, SC_CARD_TYPE_CAC_II);
}

Project: OpenSC
File: card-tcos.c

static int tcos_setperm(sc_card_t *card, int enable_nullpin)
{
	int r;
	sc_apdu_t apdu;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
	sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xEE, 0x00, 0x00);
        apdu.cla |= 0x80;
	apdu.lc = 0;
	apdu.datalen = 0;
	apdu.data = NULL;
	
	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
	return sc_check_sw(card, apdu.sw1, apdu.sw2);
}

Project: OpenSC
File: cryptoflex-tool.c

static int list_keys(void)
{
	int r, idx = 0;
	sc_path_t path;
	u8 buf[2048], *p = buf;
	size_t keysize, i;
	int mod_lens[] = { 512, 768, 1024, 2048 };
	size_t sizes[] = { 167, 247, 327, 647 };

	r = select_app_df();
	if (r)
		return 1;
	sc_format_path("I1012", &path);
	r = sc_select_file(card, &path, NULL);
	if (r) {
		fprintf(stderr, "Unable to select public key file: %s\n", sc_strerror(r));
		return 2;
	}
	do {
		int mod_len = -1;

		r = sc_read_binary(card, idx, buf, 3, 0);
		if (r < 0) {
			fprintf(stderr, "Unable to read public key file: %s\n", sc_strerror(r));
			return 2;
		}
		keysize = (p[0] << 8) | p[1];
		if (keysize == 0)
			break;
		idx += keysize;
		for (i = 0; i < sizeof(sizes)/sizeof(sizes[ 0]); i++)
			if (sizes[i] == keysize)
				mod_len = mod_lens[i];
		if (mod_len < 0)
			printf("Key %d -- unknown modulus length\n", p[2] & 0x0F);
		else
			printf("Key %d -- Modulus length %d\n", p[2] & 0x0F, mod_len);
	} while (1);
	return 0;
}

Project: OpenSC
File: sc.c

int sc_file_set_sec_attr(sc_file_t *file, const u8 *sec_attr,
			 size_t sec_attr_len)
{
	u8 *tmp;
	if (!sc_file_valid(file)) {
		return SC_ERROR_INVALID_ARGUMENTS;
	}

	if (sec_attr == NULL || sec_attr_len) {
		if (file->sec_attr != NULL)
			free(file->sec_attr);
		file->sec_attr = NULL;
		file->sec_attr_len = 0;
		return 0;
	 }
	tmp = (u8 *) realloc(file->sec_attr, sec_attr_len);
	if (!tmp) {
		if (file->sec_attr)
			free(file->sec_attr);
		file->sec_attr     = NULL;
		file->sec_attr_len = 0;
		return SC_ERROR_OUT_OF_MEMORY;
	}
	file->sec_attr = tmp;
	memcpy(file->sec_attr, sec_attr, sec_attr_len);
	file->sec_attr_len = sec_attr_len;

	return 0;
}

Project: OpenSC
File: card-epass2003.c

epass2003_gen_key(struct sc_card *card, sc_epass2003_gen_key_data * data)
{
	int r;
	size_t len = data->key_length;
	struct sc_apdu apdu;
	u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE] = { 0 };
	u8 sbuf[SC_MAX_EXT_APDU_BUFFER_SIZE] = { 0 };

	LOG_FUNC_CALLED(card->ctx);

	if(len == 256)
	{
		sbuf[0] = 0x02;
	}
	else
	{
		sbuf[0] = 0x01;
	}
	sbuf[1] = (u8) ((len >> 8) & 0xff);
	sbuf[2] = (u8) (len & 0xff);
	sbuf[3] = (u8) ((data->prkey_id >> 8) & 0xFF);
	sbuf[4] = (u8) ((data->prkey_id) & 0xFF);
	sbuf[5] = (u8) ((data->pukey_id >> 8) & 0xFF);
	sbuf[6] = (u8) ((data->pukey_id) & 0xFF);

	/* generate key */
	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, 0x00, 0x00);
	apdu.lc = apdu.datalen = 7;
	apdu.data = sbuf;

	r = sc_transmit_apdu_t(card, &apdu);
	LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	LOG_TEST_RET(card->ctx, r, "generate keypair failed");

	/* read public key */
	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xb4, 0x02, 0x00);
	if(len == 256)
	{
		apdu.p1 = 0x00;
	}
	apdu.cla = 0x80;
	apdu.lc = apdu.datalen = 2;
	apdu.data = &sbuf[5];
	apdu.resp = rbuf;
	apdu.resplen = sizeof(rbuf);
	apdu.le = 0x00;

	r = sc_transmit_apdu_t(card, &apdu);
	LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	LOG_TEST_RET(card->ctx, r, "get pukey failed");

	if (len < apdu.resplen)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);

	data->modulus = (u8 *) malloc(len);
	if (!data->modulus)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);

	memcpy(data->modulus, rbuf, len);

	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}

Project: OpenSC
File: card-epass2003.c

epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env, int se_num)
{
	struct sc_apdu apdu;
	u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = { 0 };
	u8 *p;
	unsigned short fid = 0;
	int r, locked = 0;
	epass2003_exdata *exdata = NULL;

	if (!card->drv_data)
		return SC_ERROR_INVALID_ARGUMENTS;

	exdata = (epass2003_exdata *)card->drv_data;

	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0);
    
	p = sbuf;
	*p++ = 0x80;		/* algorithm reference */
	*p++ = 0x01;
	*p++ = 0x84;

	*p++ = 0x81;
	*p++ = 0x02;

	fid = 0x2900;
	fid += (unsigned short)(0x20 * (env->key_ref[0] & 0xff));
	*p++ = fid >> 8;
	*p++ = fid & 0xff;
	r = p - sbuf;
	apdu.lc = r;
	apdu.datalen = r;
	apdu.data = sbuf;

	if (env->algorithm == SC_ALGORITHM_EC)
	{
		apdu.p2 = 0xB6;
		exdata->currAlg = SC_ALGORITHM_EC;
		if(env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA1)
		{
			sbuf[2] = 0x91;
			exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_SHA1;
		}
		else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA256)
		{
			sbuf[2] = 0x92;
			exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_SHA256;
		}
		else
		{
			sc_log(card->ctx, "%0x Alg Not Support! ", env->algorithm_flags);
			goto err;
		}
	}
	else if(env->algorithm == SC_ALGORITHM_RSA)
	{
		exdata->currAlg = SC_ALGORITHM_RSA; 
		apdu.p2 = 0xB8;
		sc_log(card->ctx, "setenv RSA Algorithm alg_flags = %0x\n",env->algorithm_flags);
	}
	else
	{
		sc_log(card->ctx, "%0x Alg Not Support! ", env->algorithm);
	}

	if (se_num > 0) {
		r = sc_lock(card);
		LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
		locked = 1;
	}
	if (apdu.datalen != 0) {
		r = sc_transmit_apdu_t(card, &apdu);
		if (r) {
			sc_log(card->ctx, "%s: APDU transmit failed", sc_strerror(r));
			goto err;
		}

		r = sc_check_sw(card, apdu.sw1, apdu.sw2);
		if (r) {
			sc_log(card->ctx, "%s: Card returned error", sc_strerror(r));
			goto err;
		}
	}
	if (se_num <= 0)
		return 0;

	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF2, se_num);
	r = sc_transmit_apdu_t(card, &apdu);
	sc_unlock(card);

	LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
	return sc_check_sw(card, apdu.sw1, apdu.sw2);

err:
	if (locked)
		sc_unlock(card);
	return r;
}

Project: OpenSC
File: pkcs15-esteid.c

select_esteid_df (sc_card_t * card)
{
	int r;
	sc_path_t tmppath;
	sc_format_path ("3F00EEEE", &tmppath);
	r = sc_select_file (card, &tmppath, NULL);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "esteid select DF failed");
	return r;
}

Project: OpenSC
File: pkcs15-sc-hsm.c

static int sc_pkcs15emu_sc_hsm_add_prkd(sc_pkcs15_card_t * p15card, u8 keyid) {

	sc_card_t *card = p15card->card;
	sc_pkcs15_cert_info_t cert_info;
	sc_pkcs15_object_t cert_obj;
	struct sc_pkcs15_object prkd;
	sc_pkcs15_prkey_info_t *key_info;
	u8 fid[2];
	/* enough to hold a complete certificate */
	u8 efbin[4096];
	u8 *ptr;
	size_t len;
	int r;

	fid[0] = PRKD_PREFIX;
	fid[1] = keyid;

	/* Try to select a related EF containing the PKCS#15 description of the key */
	len = sizeof efbin;
	r = read_file(p15card, fid, efbin, &len, 1);
	LOG_TEST_RET(card->ctx, r, "Skipping optional EF.PRKD");

	ptr = efbin;

	memset(&prkd, 0, sizeof(prkd));
	r = sc_pkcs15_decode_prkdf_entry(p15card, &prkd, (const u8 **)&ptr, &len);
	LOG_TEST_RET(card->ctx, r, "Skipping optional EF.PRKD");

	/* All keys require user PIN authentication */
	prkd.auth_id.len = 1;
	prkd.auth_id.value[0] = 1;

	/*
	 * Set private key flag as all keys are private anyway
	 */
	prkd.flags |= SC_PKCS15_CO_FLAG_PRIVATE;

	key_info = (sc_pkcs15_prkey_info_t *)prkd.data;
	key_info->key_reference = keyid;
	key_info->path.aid.len = 0;

	if (prkd.type == SC_PKCS15_TYPE_PRKEY_RSA) {
		r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkd, key_info);
	} else {
		r = sc_pkcs15emu_add_ec_prkey(p15card, &prkd, key_info);
	}

	LOG_TEST_RET(card->ctx, r, "Could not add private key to framework");

	/* Check if we also have a certificate for the private key */
	fid[0] = EE_CERTIFICATE_PREFIX;

	len = sizeof efbin;
	r = read_file(p15card, fid, efbin, &len, 0);
	LOG_TEST_RET(card->ctx, r, "Could not read EF");

	if (efbin[0] == 0x67) {		/* Decode CSR and create public key object */
		sc_pkcs15emu_sc_hsm_add_pubkey(p15card, efbin, len, key_info, prkd.label);
		free(key_info);
		return SC_SUCCESS;		/* Ignore any errors */
	}

	if (efbin[0] != 0x30) {
		free(key_info);
		return SC_SUCCESS;
	}

	memset(&cert_info, 0, sizeof(cert_info));
	memset(&cert_obj, 0, sizeof(cert_obj));

	cert_info.id = key_info->id;
	sc_path_set(&cert_info.path, SC_PATH_TYPE_FILE_ID, fid, 2, 0, 0);
	cert_info.path.count = -1;
	if (p15card->opts.use_file_cache) {
		/* look this up with our AID, which should already be cached from the
		 * call to `read_file`. This may have the side effect that OpenSC's
		 * caching layer re-selects our applet *if the cached file cannot be
		 * found/used* and we may loose the authentication status. We assume
		 * that caching works perfectly without this side effect. */
		cert_info.path.aid = sc_hsm_aid;
	}

	strlcpy(cert_obj.label, prkd.label, sizeof(cert_obj.label));
	r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);

	free(key_info);

	LOG_TEST_RET(card->ctx, r, "Could not add certificate");

	return SC_SUCCESS;
}

Project: OpenSC
File: sc.c

unsigned long bebytes2ulong(const u8 *buf)
{
	if (buf == NULL)
		return 0UL;
	return (unsigned long) (buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]);
}

Project: OpenSC
File: card-epass2003.c

aes128_encrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[16],
		const unsigned char *input, size_t length, unsigned char *output)
{
	return openssl_enc(EVP_aes_128_cbc(), key, iv, input, length, output);
}

Project: OpenSC
File: card-epass2003.c

sha256_digest(const unsigned char *input, size_t length, unsigned char *output)
{
	return openssl_dig(EVP_sha256(), input, length, output);
}

Project: OpenSC
File: sc.c

int sc_mem_reverse(unsigned char *buf, size_t len)
{
	unsigned char ch;
	size_t ii;

	if (!buf || !len)
		return SC_ERROR_INVALID_ARGUMENTS;

	for (ii = 0; ii < len / 2; ii++)   {
		ch = *(buf + ii);
		*(buf + ii) = *(buf + len - 1 - ii);
		*(buf + len - 1 - ii) = ch;
	}

	return SC_SUCCESS;
}

Project: OpenSC
File: pkcs15-esteid.c

static int esteid_detect_card(sc_pkcs15_card_t *p15card)
{
	if (is_esteid_card(p15card->card))
		return SC_SUCCESS;
	else
		return SC_ERROR_WRONG_CARD;
}

Project: OpenSC
File: cryptoflex-tool.c

static int select_app_df(void)
{
	sc_path_t path;
	sc_file_t *file;
	char str[80];
	int r;

	strcpy(str, "3F00");
	if (opt_appdf != NULL)
		strlcat(str, opt_appdf, sizeof str);
	sc_format_path(str, &path);
	r = sc_select_file(card, &path, &file);
	if (r) {
		fprintf(stderr, "Unable to select application DF: %s\n", sc_strerror(r));
		return -1;
	}
	if (file->type != SC_FILE_TYPE_DF) {
		fprintf(stderr, "Selected application DF is not a DF.\n");
		return -1;
	}
	sc_file_free(file);
	if (opt_pin_num >= 0)
		return verify_pin(opt_pin_num);
	else
		return 0;
}

Project: OpenSC
File: card-cac.c

static int cac_read_binary(sc_card_t *card, unsigned int idx,
		unsigned char *buf, size_t count, unsigned long flags)
{
	cac_private_data_t * priv = CAC_DATA(card);
	int r = 0;
	u8 *tl = NULL, *val = NULL;
	u8 *tl_ptr, *val_ptr, *tlv_ptr, *tl_start;
	u8 *cert_ptr;
	size_t tl_len, val_len, tlv_len;
	size_t len, tl_head_len, cert_len;
	u8 cert_type, tag;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	/* if we didn't return it all last time, return the remainder */
	if (priv->cached) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
			 "returning cached value idx=%d count=%"SC_FORMAT_LEN_SIZE_T"u",
			 idx, count);
		if (idx > priv->cache_buf_len) {
			SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_END_REACHED);
		}
		len = MIN(count, priv->cache_buf_len-idx);
		memcpy(buf, &priv->cache_buf[idx], len);
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, len);
	}

	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
		 "clearing cache idx=%d count=%"SC_FORMAT_LEN_SIZE_T"u",
		 idx, count);
	if (priv->cache_buf) {
		free(priv->cache_buf);
		priv->cache_buf = NULL;
		priv->cache_buf_len = 0;
	}


	if (priv->object_type <= 0)
		 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);

	r = cac_read_file(card, CAC_FILE_TAG, &tl, &tl_len);
	if (r < 0)  {
		goto done;
	}

	r = cac_read_file(card, CAC_FILE_VALUE, &val, &val_len);
	if (r < 0)
		goto done;

	switch (priv->object_type) {
	case CAC_OBJECT_TYPE_TLV_FILE:
		tlv_len = tl_len + val_len;
		priv->cache_buf = malloc(tlv_len);
		if (priv->cache_buf == NULL) {
			r = SC_ERROR_OUT_OF_MEMORY;
			goto done;
		}
		priv->cache_buf_len = tlv_len;

		for (tl_ptr = tl, val_ptr=val, tlv_ptr = priv->cache_buf;
				tl_len >= 2 && tlv_len > 0;
				val_len -= len, tlv_len -= len, val_ptr += len, tlv_ptr += len) {
			/* get the tag and the length */
			tl_start = tl_ptr;
			if (sc_simpletlv_read_tag(&tl_ptr, tl_len, &tag, &len) != SC_SUCCESS)
				break;
			tl_head_len = (tl_ptr - tl_start);
			sc_simpletlv_put_tag(tag, len, tlv_ptr, tlv_len, &tlv_ptr);
			tlv_len -= tl_head_len;
			tl_len -= tl_head_len;

			/* don't crash on bad data */
			if (val_len < len) {
				len = val_len;
			}
			/* if we run out of return space, truncate */
			if (tlv_len < len) {
				len = tlv_len;
			}
			memcpy(tlv_ptr, val_ptr, len);
		}
		break;

	case CAC_OBJECT_TYPE_CERT:
		/* read file */
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
			 " obj= cert_file, val_len=%"SC_FORMAT_LEN_SIZE_T"u (0x%04"SC_FORMAT_LEN_SIZE_T"x)",
			 val_len, val_len);
		cert_len = 0;
		cert_ptr = NULL;
		cert_type = 0;
		for (tl_ptr = tl, val_ptr = val; tl_len >= 2;
		    val_len -= len, val_ptr += len, tl_len -= tl_head_len) {
			tl_start = tl_ptr;
			if (sc_simpletlv_read_tag(&tl_ptr, tl_len, &tag, &len) != SC_SUCCESS)
				break;
			tl_head_len = tl_ptr - tl_start;

			/* incomplete value */
			if (val_len < len)
				break;

			if (tag == CAC_TAG_CERTIFICATE) {
				cert_len = len;
				cert_ptr = val_ptr;
			}
			if (tag == CAC_TAG_CERTINFO) {
				if ((len >= 1) && (val_len >=1)) {
					cert_type = *val_ptr;
				}
			}
			if (tag == CAC_TAG_MSCUID) {
				sc_log_hex(card->ctx, "MSCUID", val_ptr, len);
			}
			if ((val_len < len) || (tl_len < tl_head_len)) {
				break;
			}
		}
		/* if the info byte is 1, then the cert is compressed, decompress it */
		if ((cert_type & 0x3) == 1) {
#ifdef ENABLE_ZLIB
			r = sc_decompress_alloc(&priv->cache_buf, &priv->cache_buf_len,
				cert_ptr, cert_len, COMPRESSION_AUTO);
#else
			sc_log(card->ctx, "CAC compression not supported, no zlib");
			r = SC_ERROR_NOT_SUPPORTED;
#endif
			if (r)
				goto done;
		} else if (cert_len > 0) {
			priv->cache_buf = malloc(cert_len);
			if (priv->cache_buf == NULL) {
				r = SC_ERROR_OUT_OF_MEMORY;
				goto done;
			}
			priv->cache_buf_len = cert_len;
			memcpy(priv->cache_buf, cert_ptr, cert_len);
		} else {
			sc_log(card->ctx, "Can't read zero-length certificate");
			goto done;
		}
		break;
	case CAC_OBJECT_TYPE_GENERIC:
		/* TODO
		 * We have some two buffers in unknown encoding that we
		 * need to present in PKCS#15 layer.
		 */
	default:
		/* Unknown object type */
		sc_log(card->ctx, "Unknown object type: %x", priv->object_type);
		r = SC_ERROR_INTERNAL;
		goto done;
	}

	/* OK we've read the data, now copy the required portion out to the callers buffer */
	priv->cached = 1;
	len = MIN(count, priv->cache_buf_len-idx);
	memcpy(buf, &priv->cache_buf[idx], len);
	r = len;
done:
	if (tl)
		free(tl);
	if (val)
		free(val);
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
}

Project: OpenSC
File: card-epass2003.c

construct_data_tlv(struct sc_card *card, struct sc_apdu *apdu, unsigned char *apdu_buf,
		unsigned char *data_tlv, size_t * data_tlv_len, const unsigned char key_type)
{
	size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8);
	unsigned char pad[4096] = { 0 };
	size_t pad_len;
	size_t tlv_more;	/* increased tlv length */
	unsigned char iv[16] = { 0 };
	epass2003_exdata *exdata = NULL;

	if (!card->drv_data) 
		return SC_ERROR_INVALID_ARGUMENTS;

	exdata = (epass2003_exdata *)card->drv_data;

	/* padding */
	apdu_buf[block_size] = 0x87;
	memcpy(pad, apdu->data, apdu->lc);
	pad[apdu->lc] = 0x80;
	if ((apdu->lc + 1) % block_size)
		pad_len = ((apdu->lc + 1) / block_size + 1) * block_size;
	else
		pad_len = apdu->lc + 1;

	/* encode Lc' */
	if (pad_len > 0x7E) {
		/* Lc' > 0x7E, use extended APDU */
		apdu_buf[block_size + 1] = 0x82;
		apdu_buf[block_size + 2] = (unsigned char)((pad_len + 1) / 0x100);
		apdu_buf[block_size + 3] = (unsigned char)((pad_len + 1) % 0x100);
		apdu_buf[block_size + 4] = 0x01;
		tlv_more = 5;
	}
	else {
		apdu_buf[block_size + 1] = (unsigned char)pad_len + 1;
		apdu_buf[block_size + 2] = 0x01;
		tlv_more = 3;
	}
	memcpy(data_tlv, &apdu_buf[block_size], tlv_more);

	/* encrypt Data */
	if (KEY_TYPE_AES == key_type)
		aes128_encrypt_cbc(exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more);
	else
		des3_encrypt_cbc(exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more);

	memcpy(data_tlv + tlv_more, apdu_buf + block_size + tlv_more, pad_len);
	*data_tlv_len = tlv_more + pad_len;
	return 0;
}

Project: OpenSC
File: card-muscle.c

static int muscle_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
{
	if (len == 0)
		return SC_SUCCESS;
	else {
		SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,
				msc_get_challenge(card, len, 0, NULL, rnd),
				"GET CHALLENGE cmd failed");
		return (int) len;
	}
}

Project: OpenSC
File: card-epass2003.c

get_external_key_retries(struct sc_card *card, unsigned char kid, unsigned char *retries)
{
	int r;
	struct sc_apdu apdu;
	unsigned char random[16] = { 0 };

	r = sc_get_challenge(card, random, 8);
	LOG_TEST_RET(card->ctx, r, "get challenge get_external_key_retries failed");

	sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x82, 0x01, 0x80 | kid);
	apdu.resp = NULL;
	apdu.resplen = 0;

	r = sc_transmit_apdu_t(card, &apdu);
	LOG_TEST_RET(card->ctx, r, "APDU get_external_key_retries failed");

	if (retries && ((0x63 == (apdu.sw1 & 0xff)) && (0xC0 == (apdu.sw2 & 0xf0)))) {
		*retries = (apdu.sw2 & 0x0f);
		r = SC_SUCCESS;
	}
	else {
		LOG_TEST_RET(card->ctx, r, "get_external_key_retries failed");
		r = SC_ERROR_CARD_CMD_FAILED;
	}

	return r;
}

Project: OpenSC
File: sc.c

int _sc_parse_atr(sc_reader_t *reader)
{
	u8 *p = reader->atr.value;
	int atr_len = (int) reader->atr.len;
	int n_hist, x;
	int tx[4] = {-1, -1, -1, -1};
	int i, FI, DI;
	const int Fi_table[] = {
		372, 372, 558, 744, 1116, 1488, 1860, -1,
		-1, 512, 768, 1024, 1536, 2048, -1, -1 };
	const int f_table[] = {
		40, 50, 60, 80, 120, 160, 200, -1,
		-1, 50, 75, 100, 150, 200, -1, -1 };
	const int Di_table[] = {
		-1, 1, 2, 4, 8, 16, 32, -1,
		12, 20, -1, -1, -1, -1, -1, -1 };

	reader->atr_info.hist_bytes_len = 0;
	reader->atr_info.hist_bytes = NULL;

	if (atr_len == 0) {
		sc_log(reader->ctx, "empty ATR - card not present?\n");
		return SC_ERROR_INTERNAL;
	}

	if (p[0] != 0x3B && p[0] != 0x3F) {
		sc_log(reader->ctx, "invalid sync byte in ATR: 0x%02X\n", p[0]);
		return SC_ERROR_INTERNAL;
	}
	n_hist = p[1] & 0x0F;
	x = p[1] >> 4;
	p += 2;
	atr_len -= 2;
	for (i = 0; i < 4 && atr_len > 0; i++) {
                if (x & (1 << i)) {
                        tx[i] = *p;
                        p++;
                        atr_len--;
                } else
                        tx[i] = -1;
        }
	if (tx[0] >= 0) {
		reader->atr_info.FI = FI = tx[0] >> 4;
		reader->atr_info.DI = DI = tx[0] & 0x0F;
		reader->atr_info.Fi = Fi_table[FI];
		reader->atr_info.f = f_table[FI];
		reader->atr_info.Di = Di_table[DI];
	} else {
		reader->atr_info.Fi = -1;
		reader->atr_info.f = -1;
		reader->atr_info.Di = -1;
	}
	if (tx[2] >= 0)
		reader->atr_info.N = tx[3];
	else
		reader->atr_info.N = -1;
	while (tx[3] > 0 && tx[3] & 0xF0 && atr_len > 0) {
		x = tx[3] >> 4;
		for (i = 0; i < 4 && atr_len > 0; i++) {
	                if (x & (1 << i)) {
	                        tx[i] = *p;
	                        p++;
	                        atr_len--;
	                } else
	                        tx[i] = -1;
		}
	}
	if (atr_len <= 0)
		return SC_SUCCESS;
	if (n_hist > atr_len)
		n_hist = atr_len;
	reader->atr_info.hist_bytes_len = n_hist;
	reader->atr_info.hist_bytes = p;
	return SC_SUCCESS;
}

Project: OpenSC
File: card-muscle.c

static void muscle_load_file_acls(sc_file_t* file, mscfs_file_t *file_data)
{
	muscle_load_single_acl(file, SC_AC_OP_READ, file_data->read);
	muscle_load_single_acl(file, SC_AC_OP_WRITE, file_data->write);
	muscle_load_single_acl(file, SC_AC_OP_UPDATE, file_data->write);
	muscle_load_single_acl(file, SC_AC_OP_DELETE, file_data->delete);
}

Project: OpenSC
File: sc.c

u8 *ushort2bebytes(u8 *buf, unsigned short x)
{
	if (buf != NULL) {
		buf[1] = (u8) (x & 0xff);
		buf[0] = (u8) ((x >> 8) & 0xff);
	}
	return buf;
}

Project: OpenSC
File: sc.c

int sc_mutex_create(const sc_context_t *ctx, void **mutex)
{
	if (ctx == NULL)
		return SC_ERROR_INVALID_ARGUMENTS;
	if (ctx->thread_ctx != NULL && ctx->thread_ctx->create_mutex != NULL)
		return ctx->thread_ctx->create_mutex(mutex);
	else
		return SC_SUCCESS;
}

Project: OpenSC
File: card-muscle.c

static int muscle_select_file(sc_card_t *card, const sc_path_t *path_in,
			     sc_file_t **file_out)
{
	int r;

	assert(card != NULL && path_in != NULL);

	switch (path_in->type) {
	case SC_PATH_TYPE_FILE_ID:
		r = select_item(card, path_in, file_out, 1);
		break;
	case SC_PATH_TYPE_DF_NAME:
		r = select_item(card, path_in, file_out, 0);
		break;
	case SC_PATH_TYPE_PATH:
		r = select_item(card, path_in, file_out, -1);
		break;
	default:
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
	}
	if(r > 0) r = 0;
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r);
}

Project: OpenSC
File: card-muscle.c

static int muscle_card_generate_key(sc_card_t *card, sc_cardctl_muscle_gen_key_info_t *info)
{
	return msc_generate_keypair(card,
		info->privateKeyLocation,
		info->publicKeyLocation,
		info->keyType,
		info->keySize,
		0);
}

Project: OpenSC
File: card-cac.c

static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, u8 *tl,
						 size_t tl_len, u8 *val, size_t val_len)
{
	size_t len = 0;
	u8 *tl_end = tl + tl_len;
	u8 *val_end = val + val_len;
	sc_path_t new_path;
	int r;


	for (; (tl < tl_end) && (val< val_end); val += len) {
		/* get the tag and the length */
		u8 tag;
		if (sc_simpletlv_read_tag(&tl, tl_end - tl, &tag, &len) != SC_SUCCESS)
			break;
		switch (tag) {
		case CAC_TAG_CUID:
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:CUID");
			r = cac_parse_cuid(card, priv, (cac_cuid_t *)val, len);
			if (r < 0)
				return r;
			break;
		case CAC_TAG_CC_VERSION_NUMBER:
			if (len != 1) {
				sc_log(card->ctx, "TAG: CC Version: "
				    "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len);
				break;
			}
			/* ignore the version numbers for now */
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
				"TAG: CC Version = 0x%02x", *val);
			break;
		case CAC_TAG_GRAMMAR_VERION_NUMBER:
			if (len != 1) {
				sc_log(card->ctx, "TAG: Grammar Version: "
				    "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len);
				break;
			}
			/* ignore the version numbers for now */
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
				"TAG: Grammar Version = 0x%02x", *val);
			break;
		case CAC_TAG_CARDURL:
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:CARDURL");
			r = cac_parse_cardurl(card, priv, (cac_card_url_t *)val, len);
			if (r < 0)
				return r;
			break;
		/*
		 * The following are really for file systems cards. This code only cares about CAC VM cards
		 */
		case CAC_TAG_PKCS15:
			if (len != 1) {
				sc_log(card->ctx, "TAG: PKCS15: "
				    "Invalid length %"SC_FORMAT_LEN_SIZE_T"u", len);
				break;
			}
			/* TODO should verify that this is '0'. If it's not
			 * zero, we should drop out of here and let the PKCS 15
			 * code handle this card */
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG: PKCS15 = 0x%02x", *val);
			break;
		case CAC_TAG_DATA_MODEL:
		case CAC_TAG_CARD_APDU:
		case CAC_TAG_CAPABILITY_TUPLES:
		case CAC_TAG_STATUS_TUPLES:
		case CAC_TAG_REDIRECTION:
		case CAC_TAG_ERROR_CODES:
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:FSSpecific(0x%02x)", tag);
			break;
		case CAC_TAG_ACCESS_CONTROL:
			/* TODO handle access control later */
			sc_log_hex(card->ctx, "TAG:ACCESS Control", val, len);
			break;
		case CAC_TAG_NEXT_CCC:
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:NEXT CCC");
			r = cac_path_from_cardurl(card, &new_path, (cac_card_url_t *)val, len);
			if (r < 0)
				return r;

			r = cac_select_file_by_type(card, &new_path, NULL, SC_CARD_TYPE_CAC_II);
			if (r < 0)
				return r;

			r = cac_process_CCC(card, priv);
			if (r < 0)
				return r;
			break;
		default:
			/* ignore tags we don't understand */
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"TAG:Unknown (0x%02x)",tag );
			break;
		}
	}
	return SC_SUCCESS;
}

Project: OpenSC
File: card-cac.c

static int cac_get_ACA_path(sc_card_t *card, sc_path_t *path)
{
	cac_private_data_t * priv = CAC_DATA(card);

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL);
	if (priv->aca_path) {
		*path = *priv->aca_path;
	}
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS);
}

Project: OpenSC
File: card-cac.c

static int cac_process_ACA(sc_card_t *card, cac_private_data_t *priv)
{
	int r;
	u8 *val = NULL;
	size_t val_len;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	/* Assuming ACA is already selected */
	r = cac_get_acr(card, CAC_ACR_SERVICE, &val, &val_len);
	if (r < 0)
		goto done;

	r = cac_parse_ACA_service(card, priv, val, val_len);
        if (r == SC_SUCCESS) {
		priv->aca_path = malloc(sizeof(sc_path_t));
		if (!priv->aca_path) {
			r = SC_ERROR_OUT_OF_MEMORY;
			goto done;
		}
		memcpy(priv->aca_path, &cac_ACA_Path, sizeof(sc_path_t));
	}
done:
	if (val)
		free(val);
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
}

Project: OpenSC
File: card-epass2003.c

epass2003_hook_path(struct sc_path *path, int inc)
{
	u8 fid_h = path->value[path->len - 2];
	u8 fid_l = path->value[path->len - 1];

	switch (fid_h) {
	case 0x29:
	case 0x30:
	case 0x31:
	case 0x32:
	case 0x33:
	case 0x34:
		if (inc)
			fid_l = fid_l * FID_STEP;
		else
			fid_l = fid_l / FID_STEP;
		path->value[path->len - 1] = fid_l;
		return 1;
	default:
		break;
	}
	return 0;
}

Project: OpenSC
File: cryptoflex-tool.c

static int create_pin_file(const sc_path_t *inpath, int chv, const char *key_id)
{
	char prompt[40], *pin, *puk;
	char buf[30], *p = buf;
	sc_path_t file_id, path;
	sc_file_t *file;
	size_t len;
	int r;

	file_id = *inpath;
	if (file_id.len < 2)
		return -1;
	if (chv == 1)
		sc_format_path("I0000", &file_id);
	else if (chv == 2)
		sc_format_path("I0100", &file_id);
	else
		return -1;
	r = sc_select_file(card, inpath, NULL);
	if (r)
		return -1;
	r = sc_select_file(card, &file_id, NULL);
	if (r == 0)
		return 0;

	sprintf(prompt, "Please enter CHV%d%s: ", chv, key_id);
	pin = getpin(prompt);
	if (pin == NULL)
		return -1;

	sprintf(prompt, "Please enter PUK for CHV%d%s: ", chv, key_id);
	puk = getpin(prompt);
	if (puk == NULL) {
		free(pin);
		return -1;
	}

	memset(p, 0xFF, 3);
	p += 3;
	memcpy(p, pin, 8);
	p += 8;
	*p++ = opt_pin_attempts;
	*p++ = opt_pin_attempts;
	memcpy(p, puk, 8);
	p += 8;
	*p++ = opt_puk_attempts;
	*p++ = opt_puk_attempts;
	len = p - buf;

	free(pin);
	free(puk);

	file = sc_file_new();
	file->type = SC_FILE_TYPE_WORKING_EF;
	file->ef_structure = SC_FILE_EF_TRANSPARENT;
	sc_file_add_acl_entry(file, SC_AC_OP_READ, SC_AC_NEVER, SC_AC_KEY_REF_NONE);
	if (inpath->len == 2 && inpath->value[0] == 0x3F &&
	    inpath->value[1] == 0x00)
		sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, SC_AC_AUT, 1);
	else
		sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, SC_AC_CHV, 2);

	sc_file_add_acl_entry(file, SC_AC_OP_INVALIDATE, SC_AC_AUT, 1);
	sc_file_add_acl_entry(file, SC_AC_OP_REHABILITATE, SC_AC_AUT, 1);
	file->size = len;
	file->id = (file_id.value[0] << 8) | file_id.value[1];
	r = sc_create_file(card, file);
	sc_file_free(file);
	if (r) {
		fprintf(stderr, "PIN file creation failed: %s\n", sc_strerror(r));
		return r;
	}
	path = *inpath;
	sc_append_path(&path, &file_id);
	r = sc_select_file(card, &path, NULL);
	if (r) {
		fprintf(stderr, "Unable to select created PIN file: %s\n", sc_strerror(r));
		return r;
	}
	r = sc_update_binary(card, 0, (const u8 *) buf, len, 0);
	if (r < 0) {
		fprintf(stderr, "Unable to update created PIN file: %s\n", sc_strerror(r));
		return r;
	}

	return 0;
}

Project: OpenSC
File: pkcs15-sc-hsm.c

int sc_pkcs15emu_sc_hsm_get_curve(struct ec_curve **curve, u8 *oid, size_t oidlen)
{
	int i;

	for (i = 0; curves[i].oid.value; i++) {
		if ((curves[i].oid.len == oidlen) && !memcmp(curves[i].oid.value, oid, oidlen)) {
			*curve = &curves[i];
			return SC_SUCCESS;
		}
	}
	return SC_ERROR_INVALID_DATA;
}

Project: OpenSC
File: sc.c

int sc_path_set(sc_path_t *path, int type, const u8 *id, size_t id_len,
	int idx, int count)
{
	if (path == NULL || id == NULL || id_len == 0 || id_len > SC_MAX_PATH_SIZE)
		return SC_ERROR_INVALID_ARGUMENTS;

	memset(path, 0, sizeof(*path));
	memcpy(path->value, id, id_len);
	path->len   = id_len;
	path->type  = type;
	path->index = idx;
	path->count = count;

	return SC_SUCCESS;
}

Project: OpenSC
File: cryptoflex-tool.c

int main(int argc, char *argv[])
{
	int err = 0, r, c, long_optind = 0;
	int action_count = 0;
	int do_read_key = 0;
	int do_generate_key = 0;
	int do_create_key_files = 0;
	int do_list_keys = 0;
	int do_store_key = 0;
	int do_create_pin_file = 0;
	sc_context_param_t ctx_param;

	while (1) {
		c = getopt_long(argc, argv, "P:Vslgc:Rk:r:p:u:e:m:vwa:", options, &long_optind);
		if (c == -1)
			break;
		if (c == '?')
			util_print_usage_and_die(app_name, options, option_help, NULL);
		switch (c) {
		case 'l':
			do_list_keys = 1;
			action_count++;
			break;
		case 'P':
			do_create_pin_file = 1;
			opt_pin_num = atoi(optarg);
			action_count++;
			break;
		case 'R':
			do_read_key = 1;
			action_count++;
			break;
		case 'g':
			do_generate_key = 1;
			action_count++;
			break;
		case 'c':
			do_create_key_files = 1;
			opt_key_count = atoi(optarg);
			action_count++;
			break;
		case 's':
			do_store_key = 1;
			action_count++;
			break;
		case 'k':
			opt_key_num = atoi(optarg);
			if (opt_key_num < 1 || opt_key_num > 15) {
				fprintf(stderr, "Key number invalid.\n");
				exit(2);
			}
			break;
		case 'V':
			opt_pin_num = 1;
			break;
		case 'e':
			opt_exponent = atoi(optarg);
			break;
		case 'm':
			opt_mod_length = atoi(optarg);
			break;
		case 'p':
			opt_prkeyf = optarg;
			break;
		case 'u':
			opt_pubkeyf = optarg;
			break;
		case 'r':
			opt_reader = optarg;
			break;
		case 'v':
			verbose++;
			break;
		case 'w':
			opt_wait = 1;
			break;
		case 'a':
			opt_appdf = optarg;
			break;
		}
	}
	if (action_count == 0)
		util_print_usage_and_die(app_name, options, option_help, NULL);

	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);
	printf("Using card driver: %s\n", card->driver->name);

	if (do_create_pin_file) {
		if ((err = create_pin()) != 0)
			goto end;
		action_count--;
	}
	if (do_create_key_files) {
		if ((err = create_key_files()) != 0)
			goto end;
		action_count--;
	}
	if (do_generate_key) {
		if ((err = generate_key()) != 0)
			goto end;
		action_count--;
	}
	if (do_store_key) {
		if ((err = store_key()) != 0)
			goto end;
		action_count--;
	}
	if (do_list_keys) {
		if ((err = list_keys()) != 0)
			goto end;
		action_count--;
	}
	if (do_read_key) {
		if ((err = read_key()) != 0)
			goto end;
		action_count--;
	}
	if (pincode != NULL) {
		memset(pincode, 0, 8);
		free(pincode);
	}
end:
	if (card) {
		sc_unlock(card);
		sc_disconnect_card(card);
	}
	if (ctx)
		sc_release_context(ctx);
	return err;
}

Project: OpenSC
File: sc.c

sc_remote_apdu_allocate(struct sc_remote_data *rdata,
		struct sc_remote_apdu **new_rapdu)
{
	struct sc_remote_apdu *rapdu = NULL, *rr;

	if (!rdata)
		return SC_ERROR_INVALID_ARGUMENTS;

	rapdu = calloc(1, sizeof(struct sc_remote_apdu));
	if (rapdu == NULL)
		return SC_ERROR_OUT_OF_MEMORY;

	rapdu->apdu.data = &rapdu->sbuf[0];
	rapdu->apdu.resp = &rapdu->rbuf[0];
	rapdu->apdu.resplen = sizeof(rapdu->rbuf);

	if (new_rapdu)
		*new_rapdu = rapdu;

	if (rdata->data == NULL)   {
		rdata->data = rapdu;
		rdata->length = 1;
		return SC_SUCCESS;
	}

	for (rr = rdata->data; rr->next; rr = rr->next)
		;
	rr->next = rapdu;
	rdata->length++;

	return SC_SUCCESS;
}

Project: OpenSC
File: egk-tool.c

void decode_version(unsigned char *bcd, unsigned int *major, unsigned int *minor, unsigned int *fix)
{
	*major = 0;
	*minor = 0;
	*fix = 0;

	/* decode BCD to decimal */
	if ((bcd[0]>>4) < 10 && ((bcd[0]&0xF) < 10) && ((bcd[1]>>4) < 10)) {
		*major = (bcd[0]>>4)*100 + (bcd[0]&0xF)*10 + (bcd[1]>>4);
	}
	if (((bcd[1]&0xF) < 10) && ((bcd[2]>>4) < 10) && ((bcd[2]&0xF) < 10)) {
		*minor = (bcd[1]&0xF)*100 + (bcd[2]>>4)*10 + (bcd[2]&0xF);
	}
	if ((bcd[3]>>4) < 10 && ((bcd[3]&0xF) < 10)
			&& (bcd[4]>>4) < 10 && ((bcd[4]&0xF) < 10)) {
		*fix = (bcd[3]>>4)*1000 + (bcd[3]&0xF)*100
			+ (bcd[4]>>4)*10 + (bcd[4]&0xF);
	}
}

Project: OpenSC
File: util.c

util_warn(const char *fmt, ...)
{
	va_list	ap;

	va_start(ap, fmt);
	fprintf(stderr, "warning: ");
	vfprintf(stderr, fmt, ap);
	fprintf(stderr, "\n");
	va_end(ap);
}

Project: OpenSC
File: card-epass2003.c

des3_decrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH],
		const unsigned char *input, size_t length, unsigned char *output)
{
	unsigned char bKey[24] = { 0 };
	if (keysize == 16) {
		memcpy(&bKey[0], key, 16);
		memcpy(&bKey[16], key, 8);
	}
	else {
		memcpy(&bKey[0], key, 24);
	}

	return openssl_dec(EVP_des_ede3_cbc(), bKey, iv, input, length, output);
}

Project: OpenSC
File: card-epass2003.c

openssl_enc(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned char *iv,
		const unsigned char *input, size_t length, unsigned char *output)
{
	int r = SC_ERROR_INTERNAL;
	EVP_CIPHER_CTX * ctx = NULL;
	int outl = 0;
	int outl_tmp = 0;
	unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = { 0 };

	memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH);
	ctx = EVP_CIPHER_CTX_new();
	if (ctx == NULL)
		goto out;
	EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv_tmp);
	EVP_CIPHER_CTX_set_padding(ctx, 0);

	if (!EVP_EncryptUpdate(ctx, output, &outl, input, length))
		goto out;

	if (!EVP_EncryptFinal_ex(ctx, output + outl, &outl_tmp))
		goto out;

	r = SC_SUCCESS;
out:
	if (ctx)
	    EVP_CIPHER_CTX_free(ctx);
	return r;
}

Project: OpenSC
File: pkcs15-esteid.c

sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card)
{
	sc_card_t *card = p15card->card;
	unsigned char buff[128];
	int r, i;
	size_t field_length = 0, modulus_length = 0;
	sc_path_t tmppath;

	set_string (&p15card->tokeninfo->label, "ID-kaart");
	set_string (&p15card->tokeninfo->manufacturer_id, "AS Sertifitseerimiskeskus");

	/* Select application directory */
	sc_format_path ("3f00eeee5044", &tmppath);
	r = sc_select_file (card, &tmppath, NULL);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "select esteid PD failed");

	/* read the serial (document number) */
	r = sc_read_record (card, SC_ESTEID_PD_DOCUMENT_NR, buff, sizeof(buff), SC_RECORD_BY_REC_NR);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "read document number failed");
	buff[MIN((size_t) r, (sizeof buff)-1)] = '\0';
	set_string (&p15card->tokeninfo->serial_number, (const char *) buff);

	p15card->tokeninfo->flags = SC_PKCS15_TOKEN_PRN_GENERATION
				  | SC_PKCS15_TOKEN_EID_COMPLIANT
				  | SC_PKCS15_TOKEN_READONLY;

	/* add certificates */
	for (i = 0; i < 2; i++) {
		static const char *esteid_cert_names[2] = {
			"Isikutuvastus",
			"Allkirjastamine"};
		static char const *esteid_cert_paths[2] = {
			"3f00eeeeaace",
			"3f00eeeeddce"};
		static int esteid_cert_ids[2] = {1, 2};

		struct sc_pkcs15_cert_info cert_info;
		struct sc_pkcs15_object cert_obj;

		memset(&cert_info, 0, sizeof(cert_info));
		memset(&cert_obj, 0, sizeof(cert_obj));

		cert_info.id.value[0] = esteid_cert_ids[i];
		cert_info.id.len = 1;
		sc_format_path(esteid_cert_paths[i], &cert_info.path);
		strlcpy(cert_obj.label, esteid_cert_names[i], sizeof(cert_obj.label));
		r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
		if (r < 0)
			return SC_ERROR_INTERNAL;
		if (i == 0) {
			sc_pkcs15_cert_t *cert = NULL;
			r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert);
			if (r < 0)
				return SC_ERROR_INTERNAL;
			if (cert->key->algorithm == SC_ALGORITHM_EC)
				field_length = cert->key->u.ec.params.field_length;
			else
				modulus_length = cert->key->u.rsa.modulus.len * 8;
			if (r == SC_SUCCESS) {
				static const struct sc_object_id cn_oid = {{ 2, 5, 4, 3, -1 }};
				u8 *cn_name = NULL;
				size_t cn_len = 0;
				sc_pkcs15_get_name_from_dn(card->ctx, cert->subject,
					cert->subject_len, &cn_oid, &cn_name, &cn_len);
				if (cn_len > 0) {
					char *token_name = malloc(cn_len+1);
					if (token_name) {
						memcpy(token_name, cn_name, cn_len);
						token_name[cn_len] = '\0';
						set_string(&p15card->tokeninfo->label, (const char*)token_name);
						free(token_name);
					}
				}
				free(cn_name);
				sc_pkcs15_free_certificate(cert);
			}
		}
	}

	/* the file with key pin info (tries left) */
	sc_format_path ("3f000016", &tmppath);
	r = sc_select_file (card, &tmppath, NULL);
	if (r < 0)
		return SC_ERROR_INTERNAL;

	/* add pins */
	for (i = 0; i < 3; i++) {
		unsigned char tries_left;
		static const char *esteid_pin_names[3] = {
			"PIN1",
			"PIN2",
			"PUK" };
			
		static const int esteid_pin_min[3] = {4, 5, 8};
		static const int esteid_pin_ref[3] = {1, 2, 0};
		static const int esteid_pin_authid[3] = {1, 2, 3};
		static const int esteid_pin_flags[3] = {0, 0, SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN};
		
		struct sc_pkcs15_auth_info pin_info;
		struct sc_pkcs15_object pin_obj;

		memset(&pin_info, 0, sizeof(pin_info));
		memset(&pin_obj, 0, sizeof(pin_obj));

		/* read the number of tries left for the PIN */
		r = sc_read_record (card, i + 1, buff, sizeof(buff), SC_RECORD_BY_REC_NR);
		if (r < 0)
			return SC_ERROR_INTERNAL;
		tries_left = buff[5];

		pin_info.auth_id.len = 1;
		pin_info.auth_id.value[0] = esteid_pin_authid[i];
		pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
		pin_info.attrs.pin.reference = esteid_pin_ref[i];
		pin_info.attrs.pin.flags = esteid_pin_flags[i];
		pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC;
		pin_info.attrs.pin.min_length = esteid_pin_min[i];
		pin_info.attrs.pin.stored_length = 12;
		pin_info.attrs.pin.max_length = 12;
		pin_info.attrs.pin.pad_char = '\0';
		pin_info.tries_left = (int)tries_left;
		pin_info.max_tries = 3;

		strlcpy(pin_obj.label, esteid_pin_names[i], sizeof(pin_obj.label));
		pin_obj.flags = esteid_pin_flags[i];

		/* Link normal PINs with PUK */
		if (i < 2) {
			pin_obj.auth_id.len = 1;
			pin_obj.auth_id.value[0] = 3;
		}

		r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
		if (r < 0)
			return SC_ERROR_INTERNAL;
	}

	/* add private keys */
	for (i = 0; i < 2; i++) {
		static int prkey_pin[2] = {1, 2};

		static const char *prkey_name[2] = {
			"Isikutuvastus",
			"Allkirjastamine"};

		struct sc_pkcs15_prkey_info prkey_info;
		struct sc_pkcs15_object prkey_obj;

		memset(&prkey_info, 0, sizeof(prkey_info));
		memset(&prkey_obj, 0, sizeof(prkey_obj));

		prkey_info.id.len = 1;
		prkey_info.id.value[0] = prkey_pin[i];
		prkey_info.native = 1;
		prkey_info.key_reference = i + 1;
		prkey_info.field_length = field_length;
		prkey_info.modulus_length = modulus_length;
		if (i == 1)
			prkey_info.usage = SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
		else if(field_length > 0) // ECC has sign and derive usage
			prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DERIVE;
		else
			prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT;

		strlcpy(prkey_obj.label, prkey_name[i], sizeof(prkey_obj.label));
		prkey_obj.auth_id.len = 1;
		prkey_obj.auth_id.value[0] = prkey_pin[i];
		prkey_obj.user_consent = 0;
		prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE;

		if(field_length > 0)
			r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info);
		else
			r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
		if (r < 0)
			return SC_ERROR_INTERNAL;
	}

	return SC_SUCCESS;
}

Project: OpenSC
File: cryptoflex-tool.c

static int bn2cf(const BIGNUM *num, u8 *buf)
{
	u8 tmp[512];
	int r;

	r = BN_bn2bin(num, tmp);
	if (r <= 0)
		return r;
	invert_buf(buf, tmp, r);

	return r;
}

Project: OpenSC
File: card-muscle.c

static int muscle_check_sw(sc_card_t * card, unsigned int sw1, unsigned int sw2) {
	if(sw1 == 0x9C) {
		switch(sw2) {
			case 0x01: /* SW_NO_MEMORY_LEFT */
				return SC_ERROR_NOT_ENOUGH_MEMORY;
			case 0x02: /* SW_AUTH_FAILED */
				return SC_ERROR_PIN_CODE_INCORRECT;
			case 0x03: /* SW_OPERATION_NOT_ALLOWED */
				return SC_ERROR_NOT_ALLOWED;
			case 0x05: /* SW_UNSUPPORTED_FEATURE */
				return SC_ERROR_NO_CARD_SUPPORT;
			case 0x06: /* SW_UNAUTHORIZED */
				return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
			case 0x07: /* SW_OBJECT_NOT_FOUND */
				return SC_ERROR_FILE_NOT_FOUND;
			case 0x08: /* SW_OBJECT_EXISTS */
				return SC_ERROR_FILE_ALREADY_EXISTS;
			case 0x09: /* SW_INCORRECT_ALG */
				return SC_ERROR_INCORRECT_PARAMETERS;
			case 0x0B: /* SW_SIGNATURE_INVALID */
				return SC_ERROR_CARD_CMD_FAILED;
			case 0x0C: /* SW_IDENTITY_BLOCKED */
				return SC_ERROR_AUTH_METHOD_BLOCKED;
			case 0x0F: /* SW_INVALID_PARAMETER */
			case 0x10: /* SW_INCORRECT_P1 */
			case 0x11: /* SW_INCORRECT_P2 */
				return SC_ERROR_INCORRECT_PARAMETERS;
		}
	}
	return iso_ops->check_sw(card, sw1, sw2);
}

Project: OpenSC
File: card-cac.c

int cac_list_compare_path(const void *a, const void *b)
{
	if (a == NULL || b == NULL)
		return 1;
	return memcmp( &((cac_object_t *) a)->path,
		&((cac_object_t *) b)->path, sizeof(sc_path_t));
}

Project: OpenSC
File: card-cac.c

static int cac_process_CCC(sc_card_t *card, cac_private_data_t *priv)
{
	u8 *tl = NULL, *val = NULL;
	size_t tl_len, val_len;
	int r;


	r = cac_read_file(card, CAC_FILE_TAG, &tl, &tl_len);
	if (r < 0)
		goto done;

	r = cac_read_file(card, CAC_FILE_VALUE, &val, &val_len);
	if (r < 0)
		goto done;

	r = cac_parse_CCC(card, priv, tl, tl_len, val, val_len);
done:
	if (tl)
		free(tl);
	if (val)
		free(val);
	return r;
}

Project: OpenSC
File: card-cac.c

static int cac_parse_ACA_service(sc_card_t *card, cac_private_data_t *priv,
    u8 *val, size_t val_len)
{
	size_t len = 0;
	u8 *val_end = val + val_len;
	int r;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	for (; val < val_end; val += len) {
		/* get the tag and the length */
		u8 tag;
		if (sc_simpletlv_read_tag(&val, val_end - val, &tag, &len) != SC_SUCCESS)
			break;

		switch (tag) {
		case CAC_TAG_APPLET_FAMILY:
			if (len != 5) {
				sc_log(card->ctx, "TAG: Applet Information: "
				    "bad length %"SC_FORMAT_LEN_SIZE_T"u", len);
				break;
			}
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
			    "TAG: Applet Information: Family: 0x%02x", val[0]);
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
			    "     Applet Version: 0x%02x 0x%02x 0x%02x 0x%02x",
			    val[1], val[2], val[3], val[4]);
			break;
		case CAC_TAG_NUMBER_APPLETS:
			if (len != 1) {
				sc_log(card->ctx, "TAG: Num applets: "
				    "bad length %"SC_FORMAT_LEN_SIZE_T"u", len);
				break;
			}
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
			    "TAG: Num applets = %hhd", *val);
			break;
		case CAC_TAG_APPLET_ENTRY:
			/* Make sure we match the outer length */
			if (len < 3 || val[2] != len - 3) {
				sc_log(card->ctx, "TAG: Applet Entry: "
				    "bad length (%"SC_FORMAT_LEN_SIZE_T
				    "u) or length of internal buffer", len);
				break;
			}
			sc_debug_hex(card->ctx, SC_LOG_DEBUG_VERBOSE,
			    "TAG: Applet Entry: AID", &val[3], val[2]);
			/* This is SimpleTLV prefixed with applet ID (1B) */
			r = cac_parse_aid(card, priv, &val[3], val[2]);
			if (r < 0)
				return r;
			break;
		default:
			/* ignore tags we don't understand */
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
			    "TAG: Unknown (0x%02x)", tag);
			break;
		}
	}
	return SC_SUCCESS;
}

Project: OpenSC
File: card-cac.c

static void cac_free_private_data(cac_private_data_t *priv)
{
	free(priv->cac_id);
	free(priv->cache_buf);
	free(priv->aca_path);
	list_destroy(&priv->pki_list);
	list_destroy(&priv->general_list);
	free(priv);
	return;
}

Project: OpenSC
File: card-cac.c

static int cac_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left)
{
	/* CAC, like PIV needs Extra validation of (new) PIN during
	 * a PIN change request, to ensure it's not outside the
	 * FIPS 201 4.1.6.1 (numeric only) and * FIPS 140-2
	 * (6 character minimum) requirements.
	 */
	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();

	if (data->cmd == SC_PIN_CMD_CHANGE) {
		int i = 0;
		if (data->pin2.len < 6) {
			return SC_ERROR_INVALID_PIN_LENGTH;
		}
		for(i=0; i < data->pin2.len; ++i) {
			if (!isdigit(data->pin2.data[i])) {
				return SC_ERROR_INVALID_DATA;
			}
		}
	}

	return  iso_drv->ops->pin_cmd(card, data, tries_left);
}

Project: OpenSC
File: egk-tool.c

static int initialize(int reader_id, int verbose,
		sc_context_t **ctx, sc_reader_t **reader)
{
	unsigned int i, reader_count;
	int r;

	if (!ctx || !reader)
		return SC_ERROR_INVALID_ARGUMENTS;

	r = sc_establish_context(ctx, "");
	if (r < 0 || !*ctx) {
		fprintf(stderr, "Failed to create initial context: %s", sc_strerror(r));
		return r;
	}

	(*ctx)->debug = verbose;
	(*ctx)->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER;

	reader_count = sc_ctx_get_reader_count(*ctx);

	if (reader_count == 0) {
		sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "No reader not found.\n");
		return SC_ERROR_NO_READERS_FOUND;
	}

	if (reader_id < 0) {
		/* Automatically try to skip to a reader with a card if reader not specified */
		for (i = 0; i < reader_count; i++) {
			*reader = sc_ctx_get_reader(*ctx, i);
			if (sc_detect_card_presence(*reader) & SC_READER_CARD_PRESENT) {
				reader_id = i;
				sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "Using the first reader"
						" with a card: %s", (*reader)->name);
				break;
			}
		}
		if ((unsigned int) reader_id >= reader_count) {
			sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "No card found, using the first reader.");
			reader_id = 0;
		}
	}

	if ((unsigned int) reader_id >= reader_count) {
		sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "Invalid reader number "
				"(%d), only %d available.\n", reader_id, reader_count);
		return SC_ERROR_NO_READERS_FOUND;
	}

	*reader = sc_ctx_get_reader(*ctx, reader_id);

	return SC_SUCCESS;
}

Project: OpenSC
File: card-cac.c

static int cac_parse_cuid(sc_card_t *card, cac_private_data_t *priv, cac_cuid_t *val, size_t len)
{
	size_t card_id_len;

	if (len < sizeof(cac_cuid_t)) {
		return SC_ERROR_INVALID_DATA;
	}

	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "gsc_rid=%s", sc_dump_hex(val->gsc_rid, sizeof(val->gsc_rid)));
	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "manufacture id=%x", val->manufacturer_id);
	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "cac_type=%d", val->card_type);
	card_id_len = len - (&val->card_id - (u8 *)val);
	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
		 "card_id=%s (%"SC_FORMAT_LEN_SIZE_T"u)",
		 sc_dump_hex(&val->card_id, card_id_len),
		 card_id_len);
	priv->cuid = *val;
	priv->cac_id = malloc(card_id_len);
	if (priv->cac_id == NULL) {
		return SC_ERROR_OUT_OF_MEMORY;
	}
	memcpy(priv->cac_id, &val->card_id, card_id_len);
	priv->cac_id_len = card_id_len;
	return SC_SUCCESS;
}

Project: OpenSC
File: card-epass2003.c

internal_install_pin(struct sc_card *card, sc_epass2003_wkey_data * pin)
{
	int r;
	unsigned char hash[HASH_LEN] = { 0 };

	r = hash_data(pin->key_data.es_secret.key_val, pin->key_data.es_secret.key_len, hash, SC_ALGORITHM_ECDSA_HASH_SHA1);
	LOG_TEST_RET(card->ctx, r, "hash data failed");

	r = install_secret_key(card, 0x04, pin->key_data.es_secret.kid,
			       pin->key_data.es_secret.ac[0],
			       pin->key_data.es_secret.ac[1],
			       pin->key_data.es_secret.EC, hash, HASH_LEN);
	LOG_TEST_RET(card->ctx, r, "Install failed");

	return r;
}

Project: OpenSC
File: card-epass2003.c

epass2003_erase_card(struct sc_card *card)
{
	int r;

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

	r = sc_delete_file(card, sc_get_mf_path());
	LOG_TEST_RET(card->ctx, r, "delete MF failed");

	LOG_FUNC_RETURN(card->ctx, r);
}

Project: OpenSC
File: sc.c

int sc_detect_card_presence(sc_reader_t *reader)
{
	int r;
	LOG_FUNC_CALLED(reader->ctx);
	if (reader->ops->detect_card_presence == NULL)
		LOG_FUNC_RETURN(reader->ctx, SC_ERROR_NOT_SUPPORTED);

	r = reader->ops->detect_card_presence(reader);
	LOG_FUNC_RETURN(reader->ctx, r);
}

Project: OpenSC
File: sc.c

int sc_append_file_id(sc_path_t *dest, unsigned int fid)
{
	u8 id[2] = { fid >> 8, fid & 0xff };

	return sc_append_path_id(dest, id, 2);
}

Project: OpenSC
File: card-muscle.c

struct sc_card_driver * sc_get_muscle_driver(void)
{
	return sc_get_driver();
}

Project: OpenSC
File: cryptoflex-tool.c

static void invert_buf(u8 *dest, const u8 *src, size_t c)
{
	size_t i;

	for (i = 0; i < c; i++)
		dest[i] = src[c-1-i];
}

Project: OpenSC
File: card-epass2003.c

struct sc_card_driver *sc_get_epass2003_driver(void)
{
	return sc_get_driver();
}

Project: OpenSC
File: cryptoflex-tool.c

static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize)
{
	u8 buf[1024], *p = buf;
	u8 bnbuf[256];
	int base = 0;
	int r;
	const BIGNUM *rsa_p, *rsa_q, *rsa_dmp1, *rsa_dmq1, *rsa_iqmp;

	switch (RSA_bits(rsa)) {
	case 512:
		base = 32;
		break;
	case 768:
		base = 48;
		break;
	case 1024:
		base = 64;
		break;
	case 2048:
		base = 128;
		break;
	}
	if (base == 0) {
		fprintf(stderr, "Key length invalid.\n");
		return 2;
	}
	*p++ = (5 * base + 3) >> 8;
	*p++ = (5 * base + 3) & 0xFF;
	*p++ = opt_key_num;

	RSA_get0_factors(rsa, &rsa_p, &rsa_q);

	r = bn2cf(rsa_p, bnbuf);
	if (r != base) {
		fprintf(stderr, "Invalid private key.\n");
		return 2;
	}
	memcpy(p, bnbuf, base);
	p += base;

	r = bn2cf(rsa_q, bnbuf);
	if (r != base) {
		fprintf(stderr, "Invalid private key.\n");
		return 2;
	}
	memcpy(p, bnbuf, base);
	p += base;

	RSA_get0_crt_params(rsa, &rsa_dmp1, &rsa_dmq1, &rsa_iqmp);

	r = bn2cf(rsa_iqmp, bnbuf);
	if (r != base) {
		fprintf(stderr, "Invalid private key.\n");
		return 2;
	}
	memcpy(p, bnbuf, base);
	p += base;

	r = bn2cf(rsa_dmp1, bnbuf);
	if (r != base) {
		fprintf(stderr, "Invalid private key.\n");
		return 2;
	}
	memcpy(p, bnbuf, base);
	p += base;

	r = bn2cf(rsa_dmq1, bnbuf);
	if (r != base) {
		fprintf(stderr, "Invalid private key.\n");
		return 2;
	}
	memcpy(p, bnbuf, base);
	p += base;

	memcpy(key, buf, p - buf);
	*keysize = p - buf;

	return 0;
}

Project: OpenSC
File: cryptoflex-tool.c

static int read_rsa_privkey(RSA **rsa_out)
{
	RSA *rsa = NULL;
	BIO *in = NULL;
	int r;

	in = BIO_new(BIO_s_file());
	if (opt_prkeyf == NULL) {
		fprintf(stderr, "Private key file must be set.\n");
		return 2;
	}
	r = BIO_read_filename(in, opt_prkeyf);
	if (r <= 0) {
		perror(opt_prkeyf);
		return 2;
	}
	rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL);
	if (rsa == NULL) {
		fprintf(stderr, "Unable to load private key.\n");
		return 2;
	}
	BIO_free(in);
	*rsa_out = rsa;
	return 0;
}

Project: OpenSC
File: card-epass2003.c

des3_encrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH],
		const unsigned char *input, size_t length, unsigned char *output)
{
	unsigned char bKey[24] = { 0 };

	if (keysize == 16) {
		memcpy(&bKey[0], key, 16);
		memcpy(&bKey[16], key, 8);
	}
	else {
		memcpy(&bKey[0], key, 24);
	}

	return openssl_enc(EVP_des_ede3_cbc(), bKey, iv, input, length, output);
}

Project: OpenSC
File: egk-tool.c

int uncompress_gzip(void* uncompressed, size_t *uncompressed_len,
		const void* compressed, size_t compressed_len)
{
	return SC_ERROR_NOT_SUPPORTED;
}

Project: OpenSC
File: util.c

const char * util_acl_to_str(const sc_acl_entry_t *e)
{
	static char line[80], buf[20];
	unsigned int acl;

	if (e == NULL)
		return "N/A";
	line[0] = 0;
	while (e != NULL) {
		acl = e->method;

		switch (acl) {
		case SC_AC_UNKNOWN:
			return "N/A";
		case SC_AC_NEVER:
			return "NEVR";
		case SC_AC_NONE:
			return "NONE";
		case SC_AC_CHV:
			strcpy(buf, "CHV");
			if (e->key_ref != SC_AC_KEY_REF_NONE)
				sprintf(buf + 3, "%d", e->key_ref);
			break;
		case SC_AC_TERM:
			strcpy(buf, "TERM");
			break;
		case SC_AC_PRO:
			strcpy(buf, "PROT");
			break;
		case SC_AC_AUT:
			strcpy(buf, "AUTH");
			if (e->key_ref != SC_AC_KEY_REF_NONE)
				sprintf(buf + 4, "%d", e->key_ref);
			break;
		case SC_AC_SEN:
			strcpy(buf, "Sec.Env. ");
			if (e->key_ref != SC_AC_KEY_REF_NONE)
				sprintf(buf + 3, "#%d", e->key_ref);
			break;
		case SC_AC_SCB:
			strcpy(buf, "Sec.ControlByte ");
			if (e->key_ref != SC_AC_KEY_REF_NONE)
				sprintf(buf + 3, "Ox%X", e->key_ref);
			break;
		case SC_AC_IDA:
			strcpy(buf, "PKCS#15 AuthID ");
			if (e->key_ref != SC_AC_KEY_REF_NONE)
				sprintf(buf + 3, "#%d", e->key_ref);
			break;
		default:
			strcpy(buf, "????");
			break;
		}
		strncat(line, buf, sizeof line);
		strncat(line, " ", sizeof line);
		e = e->next;
	}
	line[(sizeof line)-1] = '\0'; /* make sure it's NUL terminated */
	line[strlen(line)-1] = 0; /* get rid of trailing space */
	return line;
}

Project: OpenSC
File: egk-tool.c

main (int argc, char **argv)
{
	struct gengetopt_args_info cmdline;
	struct sc_path path;
	struct sc_context *ctx;
	struct sc_reader *reader = NULL;
	struct sc_card *card;
	unsigned char *data = NULL;
	size_t data_len = 0;
	int r;

	if (cmdline_parser(argc, argv, &cmdline) != 0)
		exit(1);

	r = initialize(cmdline.reader_arg, cmdline.verbose_given, &ctx, &reader);
	if (r < 0) {
		fprintf(stderr, "Can't initialize reader\n");
		exit(1);
	}

	if (sc_connect_card(reader, &card) < 0) {
		fprintf(stderr, "Could not connect to card\n");
		sc_release_context(ctx);
		exit(1);
	}

	sc_path_set(&path, SC_PATH_TYPE_DF_NAME, aid_hca, sizeof aid_hca, 0, 0);
	if (SC_SUCCESS != sc_select_file(card, &path, NULL))
		goto err;

	if (cmdline.pd_flag
			&& read_file(card, "D001", &data, &data_len)
			&& data_len >= 2) {
		size_t len_pd = (data[0] << 8) | data[1];

		if (len_pd + 2 <= data_len) {
			unsigned char uncompressed[1024];
			size_t uncompressed_len = sizeof uncompressed;

			if (uncompress_gzip(uncompressed, &uncompressed_len,
						data + 2, len_pd) == SC_SUCCESS) {
				dump_binary(uncompressed, uncompressed_len);
			} else {
				dump_binary(data + 2, len_pd);
			}
		}
	}

	if ((cmdline.vd_flag || cmdline.gvd_flag)
			&& read_file(card, "D001", &data, &data_len)
			&& data_len >= 8) {
		size_t off_vd  = (data[0] << 8) | data[1];
		size_t end_vd  = (data[2] << 8) | data[3];
		size_t off_gvd = (data[4] << 8) | data[5];
		size_t end_gvd = (data[6] << 8) | data[7];
		size_t len_vd = end_vd - off_vd + 1;
		size_t len_gvd = end_gvd - off_gvd + 1;

		if (off_vd <= end_vd && end_vd < data_len
				&& off_gvd <= end_gvd && end_gvd < data_len) {
			unsigned char uncompressed[1024];
			size_t uncompressed_len = sizeof uncompressed;

			if (cmdline.vd_flag) {
				if (uncompress_gzip(uncompressed, &uncompressed_len,
							data + off_vd, len_vd) == SC_SUCCESS) {
					dump_binary(uncompressed, uncompressed_len);
				} else {
					dump_binary(data + off_vd, len_vd);
				}
			}

			if (cmdline.gvd_flag) {
				if (uncompress_gzip(uncompressed, &uncompressed_len,
							data + off_gvd, len_gvd) == SC_SUCCESS) {
					dump_binary(uncompressed, uncompressed_len);
				} else {
					dump_binary(data + off_gvd, len_gvd);
				}
			}
		}
	}

	if (cmdline.vsd_status_flag
			&& read_file(card, "D00C", &data, &data_len)
			&& data_len >= 25) {
		char *status;
		unsigned int major, minor, fix;

		switch (data[0]) {
			case '0':
				status = "Transactions pending";
				break;
			case '1':
				status = "No transactions pending";
				break;
			default:
				status = "Unknown";
				break;
		}

		decode_version(data+15, &major, &minor, &fix);

		printf(
				"Status      %s\n"
				"Timestamp   %c%c.%c%c.%c%c%c%c at %c%c:%c%c:%c%c\n"
				"Version     %u.%u.%u\n",
				status,
				PRINT(data[7]), PRINT(data[8]),
				PRINT(data[5]), PRINT(data[6]),
				PRINT(data[1]), PRINT(data[2]), PRINT(data[3]), PRINT(data[4]),
				PRINT(data[9]), PRINT(data[10]),
				PRINT(data[11]), PRINT(data[12]),
				PRINT(data[13]), PRINT(data[14]),
				major, minor, fix);
	}

err:
	sc_disconnect_card(card);
	sc_release_context(ctx);
	cmdline_parser_free (&cmdline);

	return 0;
}

Project: OpenSC
File: sc.c

const char *sc_get_version(void)
{
    return sc_version;
}

Project: OpenSC
File: sc.c

void sc_file_dup(sc_file_t **dest, const sc_file_t *src)
{
	sc_file_t *newf;
	const sc_acl_entry_t *e;
	unsigned int op;

	*dest = NULL;
	if (!sc_file_valid(src))
		return;
	newf = sc_file_new();
	if (newf == NULL)
		return;
	*dest = newf;

	memcpy(&newf->path, &src->path, sizeof(struct sc_path));
	memcpy(&newf->name, &src->name, sizeof(src->name));
	newf->namelen = src->namelen;
	newf->type    = src->type;
	newf->shareable    = src->shareable;
	newf->ef_structure = src->ef_structure;
	newf->size    = src->size;
	newf->id      = src->id;
	newf->status  = src->status;
	for (op = 0; op < SC_MAX_AC_OPS; op++) {
		newf->acl[op] = NULL;
		e = sc_file_get_acl_entry(src, op);
		if (e != NULL) {
			if (sc_file_add_acl_entry(newf, op, e->method, e->key_ref) < 0)
				goto err;
		}
	}
	newf->record_length = src->record_length;
	newf->record_count  = src->record_count;

	if (sc_file_set_sec_attr(newf, src->sec_attr, src->sec_attr_len) < 0)
		goto err;
	if (sc_file_set_prop_attr(newf, src->prop_attr, src->prop_attr_len) < 0)
		goto err;
	if (sc_file_set_type_attr(newf, src->type_attr, src->type_attr_len) < 0)
		goto err;
	if (sc_file_set_content(newf, src->encoded_content, src->encoded_content_len) < 0)
		goto err;
	return;
err:
	sc_file_free(newf);
	*dest = NULL;
}

Project: OpenSC
File: util.c

util_getpass (char **lineptr, size_t *len, FILE *stream)
{
#define MAX_PASS_SIZE	128
	char *buf;
	size_t i;
	int ch = 0;
#ifndef _WIN32
	struct termios old, new;

	fflush(stdout);
	if (tcgetattr (fileno (stdout), &old) != 0)
		return -1;
	new = old;
	new.c_lflag &= ~ECHO;
	if (tcsetattr (fileno (stdout), TCSAFLUSH, &new) != 0)
		return -1;
#endif

	buf = calloc(1, MAX_PASS_SIZE);
	if (!buf)
		return -1;

	for (i = 0; i < MAX_PASS_SIZE - 1; i++) {
#ifndef _WIN32
		ch = getchar();
#else
		ch = _getch();
#endif
		if (ch == 0 || ch == 3)
			break;
		if (ch == '\n' || ch == '\r')
			break;

		buf[i] = (char) ch;
	}
#ifndef _WIN32
	tcsetattr (fileno (stdout), TCSAFLUSH, &old);
	fputs("\n", stdout);
#endif
	if (ch == 0 || ch == 3) {
		free(buf);
		return -1;
	}

	if (*lineptr && (!len || *len < i+1)) {
		free(*lineptr);
		*lineptr = NULL;
	}

	if (*lineptr) {
		memcpy(*lineptr,buf,i+1);
		memset(buf, 0, MAX_PASS_SIZE);
		free(buf);
	} else {
		*lineptr = buf;
		if (len)
			*len = MAX_PASS_SIZE;
	}
	return i;
}

Project: OpenSC
File: card-muscle.c

static int muscle_match_card(sc_card_t *card)
{
	sc_apdu_t apdu;
	u8 response[64];
	int r;

	/* Since we send an APDU, the card's logout function may be called...
	 * however it's not always properly nulled out... */
	card->ops->logout = NULL;

	if (msc_select_applet(card, muscleAppletId, sizeof muscleAppletId) == 1) {
		/* Muscle applet is present, check the protocol version to be sure */
		sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x3C, 0x00, 0x00);
		apdu.cla = 0xB0;
		apdu.le = 64;
		apdu.resplen = 64;
		apdu.resp = response;
		r = sc_transmit_apdu(card, &apdu);
		if (r == SC_SUCCESS && response[0] == 0x01) {
			card->type = SC_CARD_TYPE_MUSCLE_V1;
		} else {
			card->type = SC_CARD_TYPE_MUSCLE_GENERIC;
		}
		return 1;
	}
	return 0;
}

Project: OpenSC
File: pkcs15-sc-hsm.c

int sc_pkcs15emu_sc_hsm_encode_cvc(sc_pkcs15_card_t * p15card,
		sc_cvc_t *cvc,
		u8 ** buf, size_t *buflen)
{
	sc_card_t *card = p15card->card;
	struct sc_asn1_entry asn1_cvc[C_ASN1_CVC_SIZE];
	struct sc_asn1_entry asn1_cvcert[C_ASN1_CVCERT_SIZE];
	struct sc_asn1_entry asn1_cvc_body[C_ASN1_CVC_BODY_SIZE];
	struct sc_asn1_entry asn1_cvc_pubkey[C_ASN1_CVC_PUBKEY_SIZE];
	size_t lenchr;
	size_t lencar;
	int r;

	sc_copy_asn1_entry(c_asn1_cvc, asn1_cvc);
	sc_copy_asn1_entry(c_asn1_cvcert, asn1_cvcert);
	sc_copy_asn1_entry(c_asn1_cvc_body, asn1_cvc_body);
	sc_copy_asn1_entry(c_asn1_cvc_pubkey, asn1_cvc_pubkey);

	asn1_cvc_pubkey[1].flags = SC_ASN1_OPTIONAL;
	asn1_cvcert[1].flags = SC_ASN1_OPTIONAL;

	sc_format_asn1_entry(asn1_cvc_pubkey    , &cvc->pukoid, NULL, 1);
	if (cvc->primeOrModulus && (cvc->primeOrModuluslen > 0)) {
		sc_format_asn1_entry(asn1_cvc_pubkey + 1, cvc->primeOrModulus, &cvc->primeOrModuluslen, 1);
	}
	sc_format_asn1_entry(asn1_cvc_pubkey + 2, cvc->coefficientAorExponent, &cvc->coefficientAorExponentlen, 1);
	if (cvc->coefficientB && (cvc->coefficientBlen > 0)) {
		sc_format_asn1_entry(asn1_cvc_pubkey + 3, cvc->coefficientB, &cvc->coefficientBlen, 1);
		sc_format_asn1_entry(asn1_cvc_pubkey + 4, cvc->basePointG, &cvc->basePointGlen, 1);
		sc_format_asn1_entry(asn1_cvc_pubkey + 5, cvc->order, &cvc->orderlen, 1);
		if (cvc->publicPoint && (cvc->publicPointlen > 0)) {
			sc_format_asn1_entry(asn1_cvc_pubkey + 6, cvc->publicPoint, &cvc->publicPointlen, 1);
		}
		sc_format_asn1_entry(asn1_cvc_pubkey + 7, cvc->cofactor, &cvc->cofactorlen, 1);
	}
	if (cvc->modulusSize > 0) {
		sc_format_asn1_entry(asn1_cvc_pubkey + 8, &cvc->modulusSize, NULL, 1);
	}

	sc_format_asn1_entry(asn1_cvc_body    , &cvc->cpi, NULL, 1);
	lencar = strnlen(cvc->car, sizeof cvc->car);
	sc_format_asn1_entry(asn1_cvc_body + 1, &cvc->car, &lencar, 1);
	sc_format_asn1_entry(asn1_cvc_body + 2, &asn1_cvc_pubkey, NULL, 1);
	lenchr = strnlen(cvc->chr, sizeof cvc->chr);
	sc_format_asn1_entry(asn1_cvc_body + 3, &cvc->chr, &lenchr, 1);

	sc_format_asn1_entry(asn1_cvcert    , &asn1_cvc_body, NULL, 1);
	if (cvc->signature && (cvc->signatureLen > 0)) {
		sc_format_asn1_entry(asn1_cvcert + 1, cvc->signature, &cvc->signatureLen, 1);
	}

	sc_format_asn1_entry(asn1_cvc , &asn1_cvcert, NULL, 1);

	r = sc_asn1_encode(card->ctx, asn1_cvc, buf, buflen);
	LOG_TEST_RET(card->ctx, r, "Could not encode card verifiable certificate");

	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}

Project: OpenSC
File: card-muscle.c

static int muscle_finish(sc_card_t *card)
{
	muscle_private_t *priv = MUSCLE_DATA(card);
	mscfs_free(priv->fs);
	free(priv);
	return 0;
}

Project: OpenSC
File: card-muscle.c

static int muscle_create_directory(sc_card_t *card, sc_file_t *file)
{
	mscfs_t *fs = MUSCLE_FS(card);
	msc_id objectId;
	u8* oid = objectId.id;
	unsigned id = file->id;
	unsigned short read_perm = 0, write_perm = 0, delete_perm = 0;
	int objectSize;
	int r;
	if(id == 0) /* No null name files */
		return SC_ERROR_INVALID_ARGUMENTS;

	/* No nesting directories */
	if(fs->currentPath[0] != 0x3F || fs->currentPath[1] != 0x00)
		return SC_ERROR_NOT_SUPPORTED;
	oid[0] = ((id & 0xFF00) >> 8) & 0xFF;
	oid[1] = id & 0xFF;
	oid[2] = oid[3] = 0;

	objectSize = file->size;

	muscle_parse_acls(file, &read_perm, &write_perm, &delete_perm);
	r = msc_create_object(card, objectId, objectSize, read_perm, write_perm, delete_perm);
	mscfs_clear_cache(fs);
	if(r >= 0) return 0;
	return r;
}

Project: OpenSC
File: card-muscle.c

static void muscle_load_dir_acls(sc_file_t* file, mscfs_file_t *file_data)
{
	muscle_load_single_acl(file, SC_AC_OP_SELECT, 0);
	muscle_load_single_acl(file, SC_AC_OP_LIST_FILES, 0);
	muscle_load_single_acl(file, SC_AC_OP_LOCK, 0xFFFF);
	muscle_load_single_acl(file, SC_AC_OP_DELETE, file_data->delete);
	muscle_load_single_acl(file, SC_AC_OP_CREATE, file_data->write);
}

Project: OpenSC
File: card-cac.c

static int cac_init(sc_card_t *card)
{
	int r;
	unsigned long flags;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	r = cac_find_and_initialize(card, 1);
	if (r < 0) {
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_CARD);
	}
	flags = SC_ALGORITHM_RSA_RAW;

	_sc_card_add_rsa_alg(card, 1024, flags, 0); /* mandatory */
	_sc_card_add_rsa_alg(card, 2048, flags, 0); /* optional */
	_sc_card_add_rsa_alg(card, 3072, flags, 0); /* optional */

	card->caps |= SC_CARD_CAP_RNG | SC_CARD_CAP_ISO7816_PIN_INFO;

	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS);
}

Project: OpenSC
File: card-epass2003.c

epass2003_get_serialnr(struct sc_card *card, sc_serial_number_t * serial)
{
	u8 rbuf[8];
	size_t rbuf_len = sizeof(rbuf);

	LOG_FUNC_CALLED(card->ctx);

	if (SC_SUCCESS != get_data(card, 0x80, rbuf, rbuf_len))
		return SC_ERROR_CARD_CMD_FAILED;

	card->serialnr.len = serial->len = 8;
	memcpy(card->serialnr.value, rbuf, 8);
	memcpy(serial->value, rbuf, 8);

	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}

Project: OpenSC
File: pkcs15-esteid.c

int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *p15card,
				struct sc_aid *aid,
				sc_pkcs15emu_opt_t *opts)
{

	if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)
		return sc_pkcs15emu_esteid_init(p15card);
	else {
		int r = esteid_detect_card(p15card);
		if (r)
			return SC_ERROR_WRONG_CARD;
		return sc_pkcs15emu_esteid_init(p15card);
	}
}

Project: OpenSC
File: sc.c

const sc_path_t *sc_get_mf_path(void)
{
	static const sc_path_t mf_path = {
		{0x3f, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2,
		0,
		0,
		SC_PATH_TYPE_PATH,
		{{0},0}
	};
	return &mf_path;
}

Project: OpenSC
File: card-cac.c

static int cac_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num)
{
	int r = SC_SUCCESS;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
		 "flags=%08lx op=%d alg=%d algf=%08x algr=%08x kr0=%02x, krfl=%"SC_FORMAT_LEN_SIZE_T"u\n",
		 env->flags, env->operation, env->algorithm,
		 env->algorithm_flags, env->algorithm_ref, env->key_ref[0],
		 env->key_ref_len);

	if (env->algorithm != SC_ALGORITHM_RSA) {
		 r = SC_ERROR_NO_CARD_SUPPORT;
	}


	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
}

Project: OpenSC
File: card-cac.c

size_t cac_list_meter(const void *el) {
	return sizeof(cac_object_t);
}

Project: OpenSC
File: pkcs15-sc-hsm.c

static int sc_pkcs15emu_sc_hsm_read_tokeninfo (sc_pkcs15_card_t * p15card)
{
	sc_card_t *card = p15card->card;
	int r;
	u8 efbin[512];
	size_t len;

	LOG_FUNC_CALLED(card->ctx);

	/* Read token info */
	len = sizeof efbin;
	r = read_file(p15card, (u8 *) "\x2F\x03", efbin, &len, 1);
	LOG_TEST_RET(card->ctx, r, "Skipping optional EF.TokenInfo");

	r = sc_pkcs15_parse_tokeninfo(card->ctx, p15card->tokeninfo, efbin, len);
	LOG_TEST_RET(card->ctx, r, "Skipping optional EF.TokenInfo");

	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}

Project: OpenSC
File: cryptoflex-tool.c

static int verify_pin(int pin)
{
	char prompt[50];
	int r, tries_left = -1;

	if (pincode == NULL) {
		sprintf(prompt, "Please enter CHV%d: ", pin);
		pincode = (u8 *) getpin(prompt);
		if (pincode == NULL || strlen((char *) pincode) == 0)
			return -1;
	}
	if (pin != 1 && pin != 2)
		return -3;
	r = sc_verify(card, SC_AC_CHV, pin, pincode, 8, &tries_left);
	if (r) {
		memset(pincode, 0, 8);
		free(pincode);
		pincode = NULL;
		fprintf(stderr, "PIN code verification failed: %s\n", sc_strerror(r));
		return -1;
	}
	return 0;
}

Project: OpenSC
File: card-muscle.c

static int select_item(sc_card_t *card, const sc_path_t *path_in, sc_file_t ** file_out, int requiredType)
{
	mscfs_t *fs = MUSCLE_FS(card);
	mscfs_file_t *file_data = NULL;
	int pathlen = path_in->len;
	int r = 0;
	int objectIndex;
	u8* oid;

	mscfs_check_cache(fs);
	r = mscfs_loadFileInfo(fs, path_in->value, path_in->len, &file_data, &objectIndex);
	if(r < 0) SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r);

	/* Check if its the right type */
	if(requiredType >= 0 && requiredType != file_data->ef) {
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS);
	}
	oid = file_data->objectId.id;
	/* Is it a file or directory */
	if(file_data->ef) {
		fs->currentPath[0] = oid[0];
		fs->currentPath[1] = oid[1];
		fs->currentFile[0] = oid[2];
		fs->currentFile[1] = oid[3];
	} else {
		fs->currentPath[0] = oid[pathlen - 2];
		fs->currentPath[1] = oid[pathlen - 1];
		fs->currentFile[0] = 0;
		fs->currentFile[1] = 0;
	}

	fs->currentFileIndex = objectIndex;
	if(file_out) {
		sc_file_t *file;
		file = sc_file_new();
		file->path = *path_in;
		file->size = file_data->size;
		file->id = (oid[2] << 8) | oid[3];
		if(!file_data->ef) {
			file->type = SC_FILE_TYPE_DF;
		} else {
			file->type = SC_FILE_TYPE_WORKING_EF;
			file->ef_structure = SC_FILE_EF_TRANSPARENT;
		}

		/* Setup ACLS */
		if(file_data->ef) {
			muscle_load_file_acls(file, file_data);
		} else {
			muscle_load_dir_acls(file, file_data);
			/* Setup directory acls... */
		}

		file->magic = SC_FILE_MAGIC;
		*file_out = file;
	}
	return 0;
}

Project: OpenSC
File: card-muscle.c

static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd,
				int *tries_left)
{
	muscle_private_t* priv = MUSCLE_DATA(card);
	const int bufferLength = MSC_MAX_PIN_COMMAND_LENGTH;
	u8 buffer[MSC_MAX_PIN_COMMAND_LENGTH];
	switch(cmd->cmd) {
	case SC_PIN_CMD_VERIFY:
		switch(cmd->pin_type) {
		case SC_AC_CHV: {
			sc_apdu_t apdu;
			int r;
			msc_verify_pin_apdu(card, &apdu, buffer, bufferLength, cmd->pin_reference, cmd->pin1.data, cmd->pin1.len);
			cmd->apdu = &apdu;
			cmd->pin1.offset = 5;
			r = iso_ops->pin_cmd(card, cmd, tries_left);
			if(r >= 0)
				priv->verifiedPins |= (1 << cmd->pin_reference);
			return r;
		}
		case SC_AC_TERM:
		case SC_AC_PRO:
		case SC_AC_AUT:
		case SC_AC_NONE:
		default:
			sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported authentication method\n");
			return SC_ERROR_NOT_SUPPORTED;
		}
	case SC_PIN_CMD_CHANGE:
		switch(cmd->pin_type) {
		case SC_AC_CHV: {
			sc_apdu_t apdu;
			msc_change_pin_apdu(card, &apdu, buffer, bufferLength, cmd->pin_reference, cmd->pin1.data, cmd->pin1.len, cmd->pin2.data, cmd->pin2.len);
			cmd->apdu = &apdu;
			return iso_ops->pin_cmd(card, cmd, tries_left);
		}
		case SC_AC_TERM:
		case SC_AC_PRO:
		case SC_AC_AUT:
		case SC_AC_NONE:
		default:
			sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported authentication method\n");
			return SC_ERROR_NOT_SUPPORTED;
		}
	case SC_PIN_CMD_UNBLOCK:
	switch(cmd->pin_type) {
		case SC_AC_CHV: {
			sc_apdu_t apdu;
			msc_unblock_pin_apdu(card, &apdu, buffer, bufferLength, cmd->pin_reference, cmd->pin1.data, cmd->pin1.len);
			cmd->apdu = &apdu;
			return iso_ops->pin_cmd(card, cmd, tries_left);
		}
		case SC_AC_TERM:
		case SC_AC_PRO:
		case SC_AC_AUT:
		case SC_AC_NONE:
		default:
			sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported authentication method\n");
			return SC_ERROR_NOT_SUPPORTED;
		}
	default:
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported command\n");
		return SC_ERROR_NOT_SUPPORTED;

	}

}

Project: OpenSC
File: card-epass2003.c

epass2003_delete_file(struct sc_card *card, const sc_path_t * path)
{
	int r;
	u8 sbuf[2];
	struct sc_apdu apdu;

	LOG_FUNC_CALLED(card->ctx);

	r = sc_select_file(card, path, NULL);
	epass2003_hook_path((struct sc_path *)path, 1);
	if (r == SC_SUCCESS) {
		sbuf[0] = path->value[path->len - 2];
		sbuf[1] = path->value[path->len - 1];
		sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x00, 0x00);
		apdu.lc = 2;
		apdu.datalen = 2;
		apdu.data = sbuf;
	}
	else   {
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
	}

	r = sc_transmit_apdu_t(card, &apdu);
	LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	LOG_TEST_RET(card->ctx, r, "Delete file failed");

	LOG_FUNC_RETURN(card->ctx, r);
}