Beispiel #1
0
static int starcos_init(sc_card_t *card)
{
    unsigned int flags;
    starcos_ex_data *ex_data;

    ex_data = calloc(1, sizeof(starcos_ex_data));
    if (ex_data == NULL)
        return SC_ERROR_OUT_OF_MEMORY;

    card->name = "STARCOS SPK 2.3";
    card->cla  = 0x00;
    card->drv_data = (void *)ex_data;

    flags = SC_ALGORITHM_RSA_PAD_PKCS1
            | SC_ALGORITHM_ONBOARD_KEY_GEN
            | SC_ALGORITHM_RSA_PAD_ISO9796
            | SC_ALGORITHM_RSA_HASH_NONE
            | SC_ALGORITHM_RSA_HASH_SHA1
            | SC_ALGORITHM_RSA_HASH_MD5
            | SC_ALGORITHM_RSA_HASH_RIPEMD160
            | SC_ALGORITHM_RSA_HASH_MD5_SHA1;

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

    card->caps = SC_CARD_CAP_RNG;

    /* we need read_binary&friends with max 128 bytes per read */
    card->max_send_size = 128;
    card->max_recv_size = 128;

    return 0;
}
static int mcrd_init(sc_card_t * card)
{
	unsigned long flags;
	struct mcrd_priv_data *priv;
	sc_path_t tmppath;

	priv = (struct mcrd_priv_data *)calloc(1, sizeof *priv);
	if (!priv)
		return SC_ERROR_OUT_OF_MEMORY;
	card->name = "MICARDO 2.1";
	card->drv_data = priv;
	card->cla = 0x00;
	card->caps |= SC_CARD_CAP_RNG;

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

	priv->curpath[0] = MFID;
	priv->curpathlen = 1;

	sc_format_path ("3f00", &tmppath);
	tmppath.type = SC_PATH_TYPE_PATH;
	sc_select_file (card, &tmppath, NULL);
	                
	
	/* The special file loading thing doesn't work for EstEID */
	if (card->type != SC_CARD_TYPE_MCRD_ESTEID)
		load_special_files(card);
	return SC_SUCCESS;
}
Beispiel #3
0
static int entersafe_init(sc_card_t *card)
{
	unsigned int flags;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	card->name = "entersafe";
	card->cla  = 0x00;
	card->drv_data = NULL;

	flags =SC_ALGORITHM_ONBOARD_KEY_GEN
		 | SC_ALGORITHM_RSA_RAW
		 | 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);
	_sc_card_add_rsa_alg(card,2048, flags, 0);

	card->caps = SC_CARD_CAP_RNG; 

	/* we need read_binary&friends with max 224 bytes per read */
	card->max_send_size = 224;
	card->max_recv_size = 224;
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS);
}
static int entersafe_init(sc_card_t *card)
{
	unsigned int flags;

	SC_FUNC_CALLED(card->ctx, 1);

	card->name = "entersafe";
	card->cla  = 0x00;
	/*card->drv_data = NULL;*/

	flags =SC_ALGORITHM_ONBOARD_KEY_GEN
		 | SC_ALGORITHM_RSA_RAW
		 | SC_ALGORITHM_RSA_HASH_NONE;

	

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

	/*card->caps = SC_CARD_CAP_RNG|SC_CARD_CAP_APDU_EXT; */
	card->caps = SC_CARD_CAP_RNG; 

	card->drv_data = 0;

	/* we need read_binary&friends with max 224 bytes per read */
	if (card->max_send_size > 0xE0)
		card->max_send_size = 0xE0;
	if (card->max_recv_size > 0xE0)
		card->max_recv_size = 0xE0;
	SC_FUNC_RETURN(card->ctx,4,SC_SUCCESS);
}
Beispiel #5
0
static int gemsafe_init(struct sc_card *card)
{
    int	r;
    gemsafe_exdata *exdata = NULL;

    SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

    card->name = "GemSAFE V1";
    card->cla  = 0x00;

    exdata = (gemsafe_exdata *)calloc(1, sizeof(gemsafe_exdata));
    if (!exdata)
        return SC_ERROR_OUT_OF_MEMORY;
    exdata->aid_len = sizeof(exdata->aid);
    if(card->type == SC_CARD_TYPE_GEMSAFEV1_GENERIC) {
        /* try to get a AID from the config file */
        r = get_conf_aid(card, exdata->aid, &exdata->aid_len);
        if (r < 0) {
            /* failed, use default value */
            memcpy(exdata->aid, gemsafe_def_aid, sizeof(gemsafe_def_aid));
            exdata->aid_len = sizeof(gemsafe_def_aid);
        }
    } else if (card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID) {
        memcpy(exdata->aid, gemsafe_pteid_aid, sizeof(gemsafe_pteid_aid));
        exdata->aid_len = sizeof(gemsafe_pteid_aid);
    }

    /* increase lock_count here to prevent sc_unlock to select
     * applet twice in gp_select_applet */
    card->lock_count++;
    /* SELECT applet */
    r = gp_select_applet(card, exdata->aid, exdata->aid_len);
    if (r < 0) {
        free(exdata);
        sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "applet selection failed\n");
        return SC_ERROR_INTERNAL;
    }
    card->lock_count--;

    /* set the supported algorithm */
    r = gemsafe_match_card(card);
    if (r > 0) {
        unsigned long flags;

        flags  = SC_ALGORITHM_RSA_PAD_PKCS1;
        flags |= SC_ALGORITHM_RSA_PAD_ISO9796;
        flags |= SC_ALGORITHM_ONBOARD_KEY_GEN;
        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);
        _sc_card_add_rsa_alg(card, 2048, flags, 0);
    }

    card->drv_data = exdata;

    return 0;
}
Beispiel #6
0
static int ias_init(sc_card_t *card)
{
	unsigned long flags;

	assert(card != NULL);

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
	card->name = "IAS";
	card->cla = 0x00;

	/* Card version detection */
	if (card->type == SC_CARD_TYPE_IAS_PTEID) {
		int r = ias_select_applet(card, ias_aid_pteid, sizeof(ias_aid_pteid));
		if (r != SC_SUCCESS)
			return r;
	/* Add other cards if necessary */
	} else {
		return SC_ERROR_INTERNAL;
	}

	/* Set card capabilities */
	card->caps |= SC_CARD_CAP_RNG;

	/* Set the supported algorithms */
	flags = SC_ALGORITHM_RSA_PAD_PKCS1 |
			SC_ALGORITHM_RSA_HASH_NONE;

    /* Only 1024 bit key sizes were tested */
     _sc_card_add_rsa_alg(card, 1024, flags, 0);

	return SC_SUCCESS;
}
static int atrust_acos_init(struct sc_card *card)
{
	unsigned int flags;
	atrust_acos_ex_data *ex_data;

	ex_data = (atrust_acos_ex_data *) calloc(1, sizeof(atrust_acos_ex_data));
	if (ex_data == NULL)
		return SC_ERROR_OUT_OF_MEMORY;

	card->cla  = 0x00;
	card->drv_data = (void *)ex_data;

	/* set the supported algorithm */

	flags = SC_ALGORITHM_RSA_PAD_PKCS1 
		| SC_ALGORITHM_RSA_HASH_NONE
		| SC_ALGORITHM_RSA_HASH_SHA1
		| SC_ALGORITHM_RSA_HASH_MD5
		| SC_ALGORITHM_RSA_HASH_RIPEMD160
		| SC_ALGORITHM_RSA_HASH_MD5_SHA1;

	if (!strcmp(card->name, ACOS_EMV_A05))
		flags |= SC_ALGORITHM_RSA_HASH_SHA256;

	_sc_card_add_rsa_alg(card, 1536, flags, 0x10001);

	/* we need read_binary&friends with max 128 bytes per read */
	if (card->max_send_size > 128)
		card->max_send_size = 128;
	if (card->max_recv_size > 128)
		card->max_recv_size = 128;

	return 0;
}
Beispiel #8
0
static int flex_init(sc_card_t *card)
{
	struct flex_private_data *data;

	if (!(data = malloc(sizeof(*data))))
		return SC_ERROR_OUT_OF_MEMORY;
	card->drv_data = data;

	card->cla = 0xC0;
	data->aak_key_ref = 1;

	/* Override Cryptoflex defaults for specific card types */
	switch (card->type) {
	case SC_CARD_TYPE_FLEX_CYBER:
		card->cla = 0x00;
		data->aak_key_ref = 0;
		break;
	}

	/* FIXME: Card type detection */
	if (1) {
		unsigned long flags;
		
		flags = SC_ALGORITHM_RSA_RAW;
		flags |= SC_ALGORITHM_RSA_HASH_NONE;
		if (card->flags & FLAG_KEYGEN)
			flags |= SC_ALGORITHM_ONBOARD_KEY_GEN;

		_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);
		_sc_card_add_rsa_alg(card, 2048, flags, 0);
	}

	/* SCardTransmit failed: 8010002f
	 * this can be solved with a small delay. */
	msleep(100);

	/* State that we have an RNG */
	card->caps |= SC_CARD_CAP_RNG;

	return 0;
}
Beispiel #9
0
static int incrypto34_init(sc_card_t *card)
{
	unsigned long	flags;

	card->name = "Incrypto34";
	card->cla = 0x00;

	/* Set up algorithm info. */
	flags = SC_ALGORITHM_NEED_USAGE
		| SC_ALGORITHM_RSA_RAW
		| SC_ALGORITHM_RSA_HASH_NONE
		| SC_ALGORITHM_ONBOARD_KEY_GEN
		;
	_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);

	return 0;
}
Beispiel #10
0
static int asepcos_init(sc_card_t *card)
{
	unsigned long	flags;

	card->name = "Athena ASEPCOS";
	card->cla  = 0x00;

	/* in case of a Java card try to select the ASEPCOS applet */
	if (card->type == SC_CARD_TYPE_ASEPCOS_JAVA) {
		int r = asepcos_select_asepcos_applet(card);
		if (r != SC_SUCCESS)
			return r;
	}

	/* Set up algorithm info. */
	flags =	SC_ALGORITHM_RSA_RAW
		| SC_ALGORITHM_RSA_HASH_NONE
		| SC_ALGORITHM_ONBOARD_KEY_GEN
		;
	_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);
	_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);

	card->caps |= SC_CARD_CAP_APDU_EXT | SC_CARD_CAP_USE_FCI_AC;

	return SC_SUCCESS;
}
Beispiel #11
0
static int
jpki_init(struct sc_card *card)
{
	struct jpki_private_data *drvdata;
	sc_file_t *mf;
	int flags;

	LOG_FUNC_CALLED(card->ctx);

	drvdata = malloc(sizeof (struct jpki_private_data));
	if (!drvdata)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);

	memset(drvdata, 0, sizeof (struct jpki_private_data));

	/* create virtual MF */
	mf = sc_file_new();
	if (!mf) {
		free(drvdata);
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
	}
	sc_format_path("3f00", &mf->path);
	mf->type = SC_FILE_TYPE_DF;
	mf->shareable = 0;
	mf->ef_structure = SC_FILE_EF_UNKNOWN;
	mf->size = 0;
	mf->id = 0x3f00;
	mf->status = SC_FILE_STATUS_ACTIVATED;
	sc_file_add_acl_entry(mf, SC_AC_OP_SELECT, SC_AC_NONE, 0);
	sc_file_add_acl_entry(mf, SC_AC_OP_LIST_FILES, SC_AC_NONE, 0);
	sc_file_add_acl_entry(mf, SC_AC_OP_LOCK, SC_AC_NEVER, 0);
	sc_file_add_acl_entry(mf, SC_AC_OP_DELETE, SC_AC_NEVER, 0);
	sc_file_add_acl_entry(mf, SC_AC_OP_CREATE, SC_AC_NEVER, 0);
	drvdata->mf = mf;
	drvdata->selected = SELECT_MF;

	card->name = "jpki";
	card->drv_data = drvdata;

	flags = SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_PAD_PKCS1;
	_sc_card_add_rsa_alg(card, 2048, flags, 0);

	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
Beispiel #12
0
static int cardos_init(sc_card_t *card)
{
	unsigned long	flags, rsa_2048 = 0;

	card->name = "CardOS M4";
	card->cla = 0x00;

	/* Set up algorithm info. */
	flags = SC_ALGORITHM_NEED_USAGE
		| SC_ALGORITHM_RSA_RAW
		| SC_ALGORITHM_RSA_HASH_NONE
		| SC_ALGORITHM_ONBOARD_KEY_GEN
		;
	_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_CARDOS_M4_2) {
		int r = cardos_have_2048bit_package(card);
		if (r < 0)
			return r;
		if (r == 1)
			rsa_2048 = 1;
		card->caps |= SC_CARD_CAP_APDU_EXT;
	} else if (card->type == SC_CARD_TYPE_CARDOS_M4_3 
		|| card->type == SC_CARD_TYPE_CARDOS_M4_2B
		|| card->type == SC_CARD_TYPE_CARDOS_M4_2C
		|| card->type == SC_CARD_TYPE_CARDOS_M4_4
		|| card->type == SC_CARD_TYPE_CARDOS_V5_0) {
		rsa_2048 = 1;
		card->caps |= SC_CARD_CAP_APDU_EXT;
	}

	if (rsa_2048 == 1) {
		_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;
}
Beispiel #13
0
static int mcrd_init(sc_card_t * card)
{
	unsigned long flags;
	struct mcrd_priv_data *priv;
	int r;
	sc_path_t tmppath;
	sc_apdu_t apdu;

	priv = calloc(1, sizeof *priv);
	if (!priv)
		return SC_ERROR_OUT_OF_MEMORY;
	card->drv_data = priv;
	card->cla = 0x00;
	card->caps = SC_CARD_CAP_RNG;


	if (is_esteid_card(card)) {
		/* Reset the MULTOS card to get to a known state */
		if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V11)
			sc_reset(card, 0);

		/* Select the EstEID AID to get to a known state.
		 * For some reason a reset is required as well... */
		if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V30) {
			flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_SHA1 | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA256;
			/* EstEID v3.0 has 2048 bit keys */
			_sc_card_add_rsa_alg(card, 2048, flags, 0);
			sc_reset(card, 0);

			sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xA4, 0x04, 0x00);
			apdu.lc = sizeof(EstEID_v3_AID);
			apdu.data = EstEID_v3_AID;
			apdu.datalen = sizeof(EstEID_v3_AID);
			apdu.resplen = 0;
			apdu.le = 0;
			r = sc_transmit_apdu(card, &apdu);
			SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "SELECT AID: %02X%02X", apdu.sw1, apdu.sw2);
			if(apdu.sw1 != 0x90 && apdu.sw2 != 0x00)
			{
				sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xA4, 0x04, 0x00);
	                        apdu.lc = sizeof(EstEID_v35_AID);
        	                apdu.data = EstEID_v35_AID;
                	        apdu.datalen = sizeof(EstEID_v35_AID);
                        	apdu.resplen = 0;
	                        apdu.le = 0;
				r = sc_transmit_apdu(card, &apdu);
	                        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
        	                sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "SELECT AID: %02X%02X", apdu.sw1, apdu.sw2);
				if (apdu.sw1 != 0x90 && apdu.sw2 != 0x00) {
					sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xA4, 0x04, 0x00);
					apdu.lc = sizeof(AzeDIT_v35_AID);
					apdu.data = AzeDIT_v35_AID;
					apdu.datalen = sizeof(AzeDIT_v35_AID);
					apdu.resplen = 0;
					apdu.le = 0;
					r = sc_transmit_apdu(card, &apdu);
					SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
					sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "SELECT AID: %02X%02X", apdu.sw1, apdu.sw2);
					if (apdu.sw1 != 0x90 && apdu.sw2 != 0x00)
						SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,  SC_ERROR_CARD_CMD_FAILED);
				}
			}
		} else {
			/* EstEID v1.0 and 1.1 have 1024 bit keys */
			flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1;
			_sc_card_add_rsa_alg(card, 1024, flags, 0);
		}
	} else {
		flags = SC_ALGORITHM_RSA_RAW |SC_ALGORITHM_RSA_PAD_PKCS1 | 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);
	}

	priv->curpath[0] = MFID;
	priv->curpathlen = 1;

	sc_format_path ("3f00", &tmppath);
	r = sc_select_file (card, &tmppath, NULL);

	/* Not needed for the fixed EstEID profile */
	if (!is_esteid_card(card))
		load_special_files(card);

	return r;
}
Beispiel #14
0
static int
isoApplet_init(sc_card_t *card)
{
	int r;
	int i;
	unsigned long flags = 0;
	unsigned long ext_flags = 0;
	size_t rlen = SC_MAX_APDU_BUFFER_SIZE;
	u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
	struct isoApplet_drv_data *drvdata;

	LOG_FUNC_CALLED(card->ctx);

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

	card->drv_data = drvdata;
	card->cla = 0x00;

	/* Obtain applet version and specific features */
	r = isoApplet_select_applet(card, isoApplet_aid, ISOAPPLET_AID_LEN, rbuf, &rlen);
	LOG_TEST_RET(card->ctx, r, "Error obtaining applet version.");
	if(rlen < 3)
	{
		assert(sizeof(rbuf) >= 3);
		memset(rbuf, 0x00, 3);
	}
	drvdata->isoapplet_version = ((unsigned int)rbuf[0] << 8) | rbuf[1];
	if(rbuf[2] & ISOAPPLET_API_FEATURE_EXT_APDU)
		card->caps |=  SC_CARD_CAP_APDU_EXT;
	if(rbuf[2] & ISOAPPLET_API_FEATURE_SECURE_RANDOM)
		card->caps |=  SC_CARD_CAP_RNG;
	if(drvdata->isoapplet_version <= 0x0005 || rbuf[2] & ISOAPPLET_API_FEATURE_ECC)
	{
		/* There are Java Cards that do not support ECDSA at all. The IsoApplet
		 * started to report this with version 00.06.
		 *
		 * Curves supported by the pkcs15-init driver are indicated per curve. This
		 * should be kept in sync with the explicit parameters in the pkcs15-init
		 * driver. */
		flags = 0;
		flags |= SC_ALGORITHM_ECDSA_RAW;
		flags |= SC_ALGORITHM_ECDSA_HASH_SHA1;
		flags |= SC_ALGORITHM_ONBOARD_KEY_GEN;
		ext_flags = SC_ALGORITHM_EXT_EC_UNCOMPRESES;
		ext_flags |=  SC_ALGORITHM_EXT_EC_NAMEDCURVE;
		ext_flags |= SC_ALGORITHM_EXT_EC_F_P;
		for (i=0; ec_curves[i].oid.value[0] >= 0; i++)
		{
			if(drvdata->isoapplet_version >= ec_curves[i].min_applet_version)
				_sc_card_add_ec_alg(card, ec_curves[i].size, flags, ext_flags, &ec_curves[i].oid);
		}
	}

	/* RSA */
	flags = 0;
	/* Padding schemes: */
	flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
	/* Hashes are to be done by the host for RSA */
	flags |= SC_ALGORITHM_RSA_HASH_NONE;
	/* Key-generation: */
	flags |= SC_ALGORITHM_ONBOARD_KEY_GEN;
	/* Modulus lengths: */
	_sc_card_add_rsa_alg(card, 2048, flags, 0);

	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
Beispiel #15
0
static int cardos_init(sc_card_t *card)
{
	unsigned long	flags, rsa_2048 = 0;
	size_t data_field_length;
	sc_apdu_t apdu;
	u8 rbuf[2];

	card->name = "CardOS M4";
	card->cla = 0x00;

	/* Set up algorithm info. */
	flags = SC_ALGORITHM_NEED_USAGE
		| SC_ALGORITHM_RSA_RAW
		| SC_ALGORITHM_RSA_HASH_NONE
		| SC_ALGORITHM_ONBOARD_KEY_GEN
		;
	_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_CARDOS_M4_2) {
		int r = cardos_have_2048bit_package(card);
		if (r < 0)
			return r;
		if (r == 1)
			rsa_2048 = 1;
		card->caps |= SC_CARD_CAP_APDU_EXT;
	} else if (card->type == SC_CARD_TYPE_CARDOS_M4_3 
		|| card->type == SC_CARD_TYPE_CARDOS_M4_2B
		|| card->type == SC_CARD_TYPE_CARDOS_M4_2C
		|| card->type == SC_CARD_TYPE_CARDOS_M4_4
		|| card->type == SC_CARD_TYPE_CARDOS_V5_0) {
		rsa_2048 = 1;
		card->caps |= SC_CARD_CAP_APDU_EXT;
	}

	/* probe DATA FIELD LENGTH with GET DATA */
	sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x8D);
	apdu.le = sizeof rbuf;
	apdu.resp = rbuf;
	apdu.resplen = sizeof(rbuf);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,
			sc_transmit_apdu(card, &apdu),
			"APDU transmit failed");
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,
			sc_check_sw(card, apdu.sw1, apdu.sw2),
			"GET DATA command returned error");
	if (apdu.resplen != 2)
		return SC_ERROR_WRONG_LENGTH;
	data_field_length = ((rbuf[0] << 8) | rbuf[1]);

	/* strip the length of possible Lc and Le bytes */
	if (card->caps & SC_CARD_CAP_APDU_EXT)
		card->max_send_size = data_field_length - 6;
	else
		card->max_send_size = data_field_length - 3;
	/* strip the length of SW bytes */
	card->max_recv_size = data_field_length - 2;

	if (rsa_2048 == 1) {
		_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;
}
Beispiel #16
0
static int belpic_init(sc_card_t *card)
{
	struct belpic_priv_data *priv = NULL;
	scconf_block *conf_block;
#ifdef BELPIC_PIN_PAD
	int r;
#endif

	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Belpic V%s", BELPIC_VERSION);
#ifdef HAVE_GUI
	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " with GUI support");
#endif
#ifdef BELPIC_PIN_PAD
	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " with support for pin pad reader libs");
#endif
	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "\n");

	if (card->type < 0)
		card->type = SC_CARD_TYPE_BELPIC_EID;	/* Unknown card: assume it's the Belpic Card */

	priv = calloc(1, sizeof(struct belpic_priv_data));
	if (priv == NULL)
		return SC_ERROR_OUT_OF_MEMORY;
	card->drv_data = priv;
	card->cla = 0x00;
	if (card->type == SC_CARD_TYPE_BELPIC_EID) {
		_sc_card_add_rsa_alg(card, 1024,
				     SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE, 0);
	}

	/* V1 applets have a problem: if the card sends a 6C XX (only XX bytes available),
	 * and we resend the command too soon (i.e. the reader is too fast), the card
	 * doesn't respond. So we build in a delay. */
	card->wait_resend_apdu = 40;

	/* State that we have an RNG */
	card->caps |= SC_CARD_CAP_RNG;
	/* State that we don't return FCI (no file type, no file size, ...) */
	card->caps |= SC_CARD_CAP_NO_FCI;

	/* Language prefences */
	priv->lang = -1;
	conf_block = get_belpic_conf(card->ctx, "belpic_general");
	if (conf_block != NULL) {
		char *lang = (char *) scconf_get_str(conf_block, "force_language", NULL);
		if (lang != NULL && strlen(lang) == 2)
			priv->lang = str2lang(card->ctx, lang);
	}
#ifdef GET_LANG_FROM_CARD
	if (priv->lang == -1)
		priv->lang = get_language(card);
#endif

	card->max_pin_len = BELPIC_MAX_USER_PIN_LEN;

#ifdef HAVE_GUI
	r = scgui_init();
	if (r != 0)
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "scgui_init() returned error %d\n", i);
#endif

#ifdef BELPIC_PIN_PAD
	r = belpic_detect_pin_pad(card, priv);
	if (r == 1)
		card->reader->capabilities |= SC_READER_CAP_PIN_PAD;
	else if (r < 0)
		return r;	/* error loading/initing pin pad lib */

	conf_block = get_belpic_conf(card->ctx, "belpic_pin_pad");
	if (conf_block != NULL) {
		if (scconf_get_bool(conf_block, "msg_auth_pin", 1))
			priv->options |= PP_MSG_AUTH_PIN;
		if (scconf_get_bool(conf_block, "msg_wrong_pin", 1))
			priv->options |= PP_MSG_WRONG_PIN;
		if (scconf_get_bool(conf_block, "msg_changepin_mismatch", 1))
			priv->options |= PP_MSG_CHANGEPIN_MISMATCH;
		if (scconf_get_bool(conf_block, "msg_pin_blocked", 1))
			priv->options |= PP_MSG_PIN_BLOCKED;
	}
#endif

	return 0;
}