static int infocamere_1600_init(sc_pkcs15_card_t * p15card)
{
	sc_card_t *card = p15card->card;
	sc_path_t path;
	sc_pkcs15_id_t id, auth_id;
	unsigned char serial[17];
	int flags;
	int r;
	int hasAuthCert = 0;

	const char *certLabel[] = { "User Non-repudiation Certificate",
		"User Authentication Certificate"
	};

	const char *certPath[] = { "200020010008", "20002001000E" };

	const char *pinLabel[] =
	    { "Non-repudiation PIN", "Authentication PIN" };
	int retries[] = { 3, -1 };

	const char *keyPath[] = { "200020010004", "20002001000A" };
	const char *keyLabel[] =
	    { "Non repudiation Key", "Authentication Key" };
	static int usage[] = { SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
		SC_PKCS15_PRKEY_USAGE_SIGN
		    | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
		    | SC_PKCS15_PRKEY_USAGE_ENCRYPT
		    | SC_PKCS15_PRKEY_USAGE_DECRYPT
	};

	auth_id.len = 1;
	id.len = 1;

	/* OpenSC doesn't define constants to identify BSOs for
	 * restoring security environment, so we overload
	 * the set_security_env function to support restore_sec_env */
	set_security_env = card->ops->set_security_env;
	card->ops->set_security_env = infocamere_1400_set_sec_env;
	card->ops->compute_signature = do_sign;

	sc_format_path("200020012002", &path);

	r = sc_select_file(card, &path, NULL);

	if (r != SC_SUCCESS)
		return SC_ERROR_WRONG_CARD;

	sc_read_binary(card, 30, serial, 16, 0);
	serial[16] = '\0';

	set_string(&p15card->serial_number, (char *) serial);
	set_string(&p15card->label, "Infocamere 1600 Card");
	set_string(&p15card->manufacturer_id, "Infocamere");

	/* Adding certificates.
	 * Certificates are stored in a ZLib compressed form with
	 * a 4 byte header, so we extract, decompress and cache
	 * them.
	 */
	sc_format_path(certPath[0], &path);
	if (sc_select_file(card, &path, NULL) != SC_SUCCESS)
		return SC_ERROR_WRONG_CARD;

	id.value[0] = 1;

	sc_pkcs15emu_add_cert(p15card,
			      SC_PKCS15_TYPE_CERT_X509, 0,
			      &path, &id, certLabel[0],
			      SC_PKCS15_CO_FLAG_MODIFIABLE);

	sc_format_path(certPath[1], &path);
	if (sc_select_file(card, &path, NULL) == SC_SUCCESS) {
		hasAuthCert = 1;

		id.value[0] = 2;

		sc_pkcs15emu_add_cert(p15card,
				      SC_PKCS15_TYPE_CERT_X509, 1,
				      &path, &id, certLabel[1],
				      SC_PKCS15_CO_FLAG_MODIFIABLE);
	}

	flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE |
	    SC_PKCS15_PIN_FLAG_INITIALIZED |
	    SC_PKCS15_PIN_FLAG_NEEDS_PADDING;

	/* adding PINs & private keys */
	sc_format_path("2000", &path);
	id.value[0] = 1;

	sc_pkcs15emu_add_pin(p15card, &id,
			     pinLabel[0], &path, 1,
			     SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
			     5, 8, flags, retries[0], 0,
			     SC_PKCS15_CO_FLAG_MODIFIABLE |
			     SC_PKCS15_CO_FLAG_PRIVATE);

	sc_format_path(keyPath[0], &path);
	auth_id.value[0] = 1;
	sc_pkcs15emu_add_prkey(p15card, &id,
			       keyLabel[0],
			       SC_PKCS15_TYPE_PRKEY_RSA,
			       1024, usage[0],
			       &path, 1,
			       &auth_id, SC_PKCS15_CO_FLAG_PRIVATE);

	if (hasAuthCert) {
		id.value[0] = 2;

		sc_pkcs15emu_add_pin(p15card, &id,
				     pinLabel[1], &path, 2,
				     SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
				     5, 8, flags, retries[1], 0,
				     SC_PKCS15_CO_FLAG_MODIFIABLE |
				     SC_PKCS15_CO_FLAG_PRIVATE);

		sc_format_path(keyPath[1], &path);
		auth_id.value[0] = 2;
		sc_pkcs15emu_add_prkey(p15card, &id,
				       keyLabel[1],
				       SC_PKCS15_TYPE_PRKEY_RSA,
				       1024, usage[1],
				       &path, 2,
				       &auth_id,
				       SC_PKCS15_CO_FLAG_PRIVATE);
	}

	/* return to MF */
	sc_format_path("3F00", &path);
	r = sc_select_file(card, &path, NULL);

	return SC_SUCCESS;
}
Example #2
0
static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card)
{
	int		    r;
	unsigned int    i;
	struct sc_path  path;
	struct sc_file *file = NULL;
	struct sc_card *card = p15card->card;
	struct sc_apdu  apdu;
	u8		    rbuf[SC_MAX_APDU_BUFFER_SIZE];

	sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Setting pkcs15 parameters\n");

	if (p15card->tokeninfo->label)
		free(p15card->tokeninfo->label);
	p15card->tokeninfo->label = malloc(strlen(APPLET_NAME) + 1);
	if (!p15card->tokeninfo->label)
		return SC_ERROR_INTERNAL;
	strcpy(p15card->tokeninfo->label, APPLET_NAME);

	if (p15card->tokeninfo->serial_number)
		free(p15card->tokeninfo->serial_number);
	p15card->tokeninfo->serial_number = malloc(strlen(DRIVER_SERIAL_NUMBER) + 1);
	if (!p15card->tokeninfo->serial_number)
		return SC_ERROR_INTERNAL;
	strcpy(p15card->tokeninfo->serial_number, DRIVER_SERIAL_NUMBER);

	/* the GemSAFE applet version number */
	sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0xdf, 0x03);
	apdu.cla = 0x80;
	apdu.resp = rbuf;
	apdu.resplen = sizeof(rbuf);
	/* Manual says Le=0x05, but should be 0x08 to return full version numer */
	apdu.le = 0x08;
	apdu.lc = 0;
	apdu.datalen = 0;
	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)
		return SC_ERROR_INTERNAL;
	if (r != SC_SUCCESS)
		return SC_ERROR_INTERNAL;

	/* the manufacturer ID, in this case GemPlus */
	if (p15card->tokeninfo->manufacturer_id)
		free(p15card->tokeninfo->manufacturer_id);
	p15card->tokeninfo->manufacturer_id = malloc(strlen(MANU_ID) + 1);
	if (!p15card->tokeninfo->manufacturer_id)
		return SC_ERROR_INTERNAL;
	strcpy(p15card->tokeninfo->manufacturer_id, MANU_ID);

	/* determine allocated key containers and length of certificates */
	r = gemsafe_get_cert_len(card);
	if (r != SC_SUCCESS)
		return SC_ERROR_INTERNAL;

	/* set certs */
	sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Setting certificates\n");
	for (i = 0; i < gemsafe_cert_max; i++) {
		struct sc_pkcs15_id p15Id;
		struct sc_path path;

		if (gemsafe_cert[i].label == NULL)
			continue;
		sc_format_path(gemsafe_cert[i].path, &path);
		sc_pkcs15_format_id(gemsafe_cert[i].id, &p15Id);
		path.index = gemsafe_cert[i].index;
		path.count = gemsafe_cert[i].count;
		sc_pkcs15emu_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509,
				      gemsafe_cert[i].authority, &path, &p15Id,
				      gemsafe_cert[i].label, gemsafe_cert[i].obj_flags);
	}

	/* set gemsafe_pin */
	sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Setting PIN\n");
	for (i=0; i < gemsafe_pin_max; i++) {
		struct sc_pkcs15_id	p15Id;
		struct sc_path path;

		sc_pkcs15_format_id(gemsafe_pin[i].id, &p15Id);
		sc_format_path(gemsafe_pin[i].path, &path);
		if (gemsafe_pin[i].atr_len == 0 ||
		   (gemsafe_pin[i].atr_len == p15card->card->atr.len &&
		    memcmp(p15card->card->atr.value, gemsafe_pin[i].atr,
			   p15card->card->atr.len) == 0)) {
			sc_pkcs15emu_add_pin(p15card, &p15Id, gemsafe_pin[i].label,
					     &path, gemsafe_pin[i].ref, gemsafe_pin[i].type,
					     gemsafe_pin[i].minlen, gemsafe_pin[i].maxlen,
					     gemsafe_pin[i].flags, gemsafe_pin[i].tries_left,
					     gemsafe_pin[i].pad_char, gemsafe_pin[i].obj_flags);
			break;
		}
	};

	/* set private keys */
	sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Setting private keys\n");
	for (i = 0; i < gemsafe_cert_max; i++) {
		struct sc_pkcs15_id p15Id, authId, *pauthId;
		struct sc_path path;
		int key_ref = 0x03; 

		if (gemsafe_prkeys[i].label == NULL)
			continue;
		sc_pkcs15_format_id(gemsafe_prkeys[i].id, &p15Id);
		if (gemsafe_prkeys[i].auth_id) {
			sc_pkcs15_format_id(gemsafe_prkeys[i].auth_id, &authId);
			pauthId = &authId;
		} else
			pauthId = NULL;
		sc_format_path(gemsafe_prkeys[i].path, &path);
		/* 
		 * The key ref may be different for different sites;
		 * by adding flags=n where the low order 4 bits can be
		 * the key ref we can force it.
		 */
		if ( p15card->card->flags & 0x0F) {
			key_ref = p15card->card->flags & 0x0F;
			sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL,
				 "Overriding key_ref %d with %d\n",
				 gemsafe_prkeys[i].ref, key_ref);
		} else
			key_ref = gemsafe_prkeys[i].ref;
		sc_pkcs15emu_add_prkey(p15card, &p15Id, gemsafe_prkeys[i].label,
				       SC_PKCS15_TYPE_PRKEY_RSA,
				       gemsafe_prkeys[i].modulus_len, gemsafe_prkeys[i].usage,
				       &path, key_ref, pauthId,
				       gemsafe_prkeys[i].obj_flags);
	}

	/* select the application DF */
	sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL,"Selecting application DF\n");
	sc_format_path(GEMSAFE_APP_PATH, &path);
	r = sc_select_file(card, &path, &file);
	if (r != SC_SUCCESS || !file)
		return SC_ERROR_INTERNAL;
	/* set the application DF */
	if (p15card->file_app)
		free(p15card->file_app);
	p15card->file_app = file;

	return SC_SUCCESS;
}
static int sc_pkcs15emu_postecert_init(sc_pkcs15_card_t * p15card)
{
	static int prkey_usage = SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
	static int authprkey_usage = SC_PKCS15_PRKEY_USAGE_SIGN
	    | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
	    | SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT;

	sc_card_t *card = p15card->card;
	sc_path_t path;
	sc_pkcs15_id_t id, auth_id;
	unsigned char certlen[2];
	unsigned char *certi = NULL;
	int index_cert[4];
	int count_cert[4];
	int flags;
	int authority;
	size_t i, count;
	int r;
	int o = 0;

	const char *label = "User Non-repudiation Certificate";
	const char *calabel = "CA Certificate";
	const char *catmslabel = "CA TimeStamper Certificate";
	const char *authlabel = "User Authentication Certificate";

	const char *postecert_auth_cert_path = "504B0001";

	const char *authPIN = "Authentication PIN";
	const char *nonrepPIN = "Non-repudiation PIN";

	const char *authPRKEY = "Authentication Key";
	const char *nonrepPRKEY = "Non repudiation Key";

	/* Get the non-repudiation certificate length */
	sc_format_path(postecert_auth_cert_path, &path);

	if (sc_select_file(card, &path, NULL) < 0) {
		r = SC_ERROR_WRONG_CARD;
		goto failed;
	}

	set_string(&p15card->label, "Postecert & Cnipa Card");
	set_string(&p15card->manufacturer_id, "Postecert");
	set_string(&p15card->serial_number, "0000");

	sc_read_binary(card, 0, certlen, 2, 0);

	/* Now set the certificate offset/len */
	count = (certlen[0] << 8) + certlen[1];
	if (count < 256)
		return SC_ERROR_INTERNAL;

	certi = (unsigned char *) malloc(count);

	if (!certi)
		return SC_ERROR_OUT_OF_MEMORY;

	sc_read_binary(card, 0, certi, count - 500, 0);

	for (i = 2; i < (count - 256); i++) {
		/* this file contain more than one certificate */
		if (*(certi + i) == 0x30 && *(certi + i + 1) == 0x82
		    && *(certi + i + 4) == 0x30 && *(certi + i + 5) == 0x82
		    && *(certi + i + 2) > 1 && *(certi + i + 2) < 8
		    && *(certi + i + 6) <= *(certi + i + 2)) {
			index_cert[o] = i;
			count_cert[o] =
			    (*(certi + i + 2) << 8) + *(certi + i + 3) + 4;
			o++;
			if (o > 4)
				break;
			i += (*(certi + i + 2) << 8) + *(certi + i + 3);
		}
	}

	free(certi);

	path.index = index_cert[0];
	path.count = count_cert[0];

	id.value[0] = 1;
	id.len = 1;

	authority = 1;

	sc_pkcs15emu_add_cert(p15card,
			      SC_PKCS15_TYPE_CERT_X509, authority,
			      &path, &id, calabel, SC_PKCS15_CO_FLAG_MODIFIABLE);

	path.index = index_cert[1];
	path.count = count_cert[1];

	id.value[0] = 2;
	id.len = 1;

	authority = 1;

	sc_pkcs15emu_add_cert(p15card,
			      SC_PKCS15_TYPE_CERT_X509, authority,
			      &path, &id, catmslabel, SC_PKCS15_CO_FLAG_MODIFIABLE);

	path.index = index_cert[2];
	path.count = count_cert[2];

	id.value[0] = 3;
	id.len = 1;

	authority = 0;

	sc_pkcs15emu_add_cert(p15card,
			      SC_PKCS15_TYPE_CERT_X509, authority,
			      &path, &id, label, SC_PKCS15_CO_FLAG_MODIFIABLE);

	path.index = index_cert[3];
	path.count = count_cert[3];

	id.value[0] = 4;
	id.len = 1;

	sc_pkcs15emu_add_cert(p15card,
			      SC_PKCS15_TYPE_CERT_X509, authority,
			      &path, &id, authlabel, SC_PKCS15_CO_FLAG_MODIFIABLE);


	flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE |
	    SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_NEEDS_PADDING;

	/* add authentication PIN */
	sc_format_path("3F00504B", &path);
	id.value[0] = 1;
	sc_pkcs15emu_add_pin(p15card, &id,
			     authPIN, &path, 0x82,
			     SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
			     6, 14, flags, 3, 0,
			     SC_PKCS15_CO_FLAG_MODIFIABLE |
			     SC_PKCS15_CO_FLAG_PRIVATE);

	/* add authentication private key */
	id.value[0] = 4;
	auth_id.value[0] = 1;
	auth_id.len = 1;
	sc_pkcs15emu_add_prkey(p15card, &id,
			       authPRKEY,
			       SC_PKCS15_TYPE_PRKEY_RSA,
			       1024, authprkey_usage,
			       &path, 0x06, &auth_id, SC_PKCS15_CO_FLAG_PRIVATE);

	/* add non repudiation PIN */
	sc_format_path("3F00504B", &path);
	id.value[0] = 2;
	sc_pkcs15emu_add_pin(p15card, &id,
			     nonrepPIN, &path, 0x82,
			     SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
			     6, 14, flags, 3, 0,
			     SC_PKCS15_CO_FLAG_MODIFIABLE |
			     SC_PKCS15_CO_FLAG_PRIVATE);


	/* add non repudiation private key */
	id.value[0] = 3;
	auth_id.value[0] = 2;
	sc_pkcs15emu_add_prkey(p15card, &id,
			       nonrepPRKEY,
			       SC_PKCS15_TYPE_PRKEY_RSA,
			       1024, prkey_usage,
			       &path, 0x01, &auth_id, SC_PKCS15_CO_FLAG_PRIVATE);

	/* return to MF */
	sc_format_path("3F00", &path);
	r = sc_select_file(card, &path, NULL);
	if (r != SC_SUCCESS)
		return r;

	{
		/* save old signature funcs */
		set_security_env = card->ops->set_security_env;
		/* set new one              */
		card->ops->set_security_env  = set_sec_env;
		card->ops->compute_signature = do_sign;
	}
	return 0;

failed:
	sc_error(card->ctx,
		 "Failed to initialize Postecert and Cnipa emulation: %s\n",
		 sc_strerror(r));
	return r;
}
static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card)
{
    const char *fn_name = "sc_pkcs15emu_gemsafe_init";

    int    r, i;
	int	   key_ref = 0x03; 
    struct sc_path path;
    struct sc_file *file = NULL;
    struct sc_card *card = p15card->card;
    struct sc_apdu apdu;
    u8     rbuf[SC_MAX_APDU_BUFFER_SIZE];
    char * endptr;
    float version=0.0;

    sc_debug(p15card->card->ctx, "%s: Setting pkcs15 parameters\n", fn_name);

    if (p15card->label)
    	free(p15card->label);
    p15card->label = malloc(strlen(APPLET_NAME) + 1);
    if (!p15card->label)
    	return SC_ERROR_INTERNAL;
    strcpy(p15card->label, APPLET_NAME);

    if (p15card->serial_number)
	    free(p15card->serial_number);
    p15card->serial_number = malloc(strlen(DRIVER_SERIAL_NUMBER) + 1);
    if (!p15card->serial_number)
	    return SC_ERROR_INTERNAL;
    strcpy(p15card->serial_number, DRIVER_SERIAL_NUMBER);

    /* the GemSAFE applet version number */
    sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0xdf, 0x03);
    apdu.cla = 0x80;
    apdu.resp = rbuf;
    apdu.resplen = sizeof(rbuf);
    /* Manual says Le=0x05, but should be 0x08 to return full version numer */
    apdu.le = 0x08;
    apdu.lc = 0;
    apdu.datalen = 0;
    r = sc_transmit_apdu(card, &apdu);
    SC_TEST_RET(card->ctx, r, "APDU transmit failed");
    if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00)
	    return SC_ERROR_INTERNAL;
    if (r != SC_SUCCESS)
	    return SC_ERROR_INTERNAL;
    endptr = (char *)(apdu.resp + apdu.resplen);
    version = strtod( (const char *)(apdu.resp + 4), &endptr);
    sc_debug(p15card->card->ctx, "%s: version (float): %f, version (int): %d\n",
    	    fn_name, version, (int)version);
    p15card->version = (int)version;

    /* the manufacturer ID, in this case GemPlus */
    if (p15card->manufacturer_id)
	    free(p15card->manufacturer_id);
    p15card->manufacturer_id = malloc(strlen(MANU_ID) + 1);
    if (!p15card->manufacturer_id)
	    return SC_ERROR_INTERNAL;
    strcpy(p15card->manufacturer_id, MANU_ID);

    /* set certs */
    sc_debug(p15card->card->ctx, "%s: Setting certificate\n", fn_name);
    for (i = 0; gemsafe_cert[i].label; i++) {
	    struct sc_pkcs15_id  p15Id;

	    sc_format_path(gemsafe_cert[i].path, &path);
	    if (!gemsafe_get_cert_len(card, &path, &key_ref))
		    /* skip errors */
		    continue;
	    sc_pkcs15_format_id(gemsafe_cert[i].id, &p15Id);
	    sc_pkcs15emu_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509,
			    gemsafe_cert[i].authority, &path, &p15Id,
			    gemsafe_cert[i].label, gemsafe_cert[i].obj_flags);
    }
    /* set gemsafe_pin */
    sc_debug(p15card->card->ctx, "%s: Setting PIN\n", fn_name);
    for (i = 0; gemsafe_pin[i].label; i++) {
	    struct sc_pkcs15_id  p15Id;

	    sc_pkcs15_format_id(gemsafe_pin[i].id, &p15Id);
	    sc_pkcs15emu_add_pin(p15card, &p15Id, gemsafe_pin[i].label,
			    &path, gemsafe_pin[i].ref, gemsafe_pin[i].type,
			    gemsafe_pin[i].minlen, gemsafe_pin[i].maxlen,
			    gemsafe_pin[i].flags,
			    gemsafe_pin[i].tries_left, gemsafe_pin[i].pad_char,
			    gemsafe_pin[i].obj_flags);
    }
    /* set private keys */
    sc_debug(p15card->card->ctx, "%s: Setting private key\n", fn_name);
    for (i = 0; gemsafe_prkeys[i].label; i++) {
	    struct sc_pkcs15_id p15Id,
				authId, *pauthId;
	    sc_pkcs15_format_id(gemsafe_prkeys[i].id, &p15Id);
	    if (gemsafe_prkeys[i].auth_id) {
		    sc_pkcs15_format_id(gemsafe_prkeys[i].auth_id, &authId);
		    pauthId = &authId;
	    } else
		    pauthId = NULL;
			/*
			 * the key ref may be different for different sites 
			 * by adding flags=n where the low order 4 bits can be
			 * the key ref we can force it. 
			 */
			if ( p15card->card->flags & 0x0F) {
				key_ref = p15card->card->flags & 0x0F;
				sc_debug(p15card->card->ctx,
					"Overriding key_ref  with %d\n", key_ref);
			} 
	    sc_pkcs15emu_add_prkey(p15card, &p15Id, gemsafe_prkeys[i].label,
			    SC_PKCS15_TYPE_PRKEY_RSA,
			    gemsafe_prkeys[i].modulus_len, gemsafe_prkeys[i].usage,
			    &path, key_ref, pauthId,
			    gemsafe_prkeys[i].obj_flags);
    }

    /* select the application DF */
    sc_debug(p15card->card->ctx,"%s: Selecting application DF\n", fn_name);
    sc_format_path("3F001600", &path);
    r = sc_select_file(card, &path, &file);
    if (r != SC_SUCCESS || !file)
	    return SC_ERROR_INTERNAL;
    /* set the application DF */
    if (p15card->file_app)
	    free(p15card->file_app);
    p15card->file_app = file;

    return SC_SUCCESS;

}