Beispiel #1
0
static int rutoken_info(sc_card_t *card)
{	
	u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
	sc_serial_number_t serial;
	int r;
	
	r = sc_card_ctl(card, SC_CARDCTL_RUTOKEN_GET_INFO, rbuf);
	if (r) {
		fprintf(stderr, "Error: Get info failed: %s\n", sc_strerror(r));
		return -1;
	}
	printf("Type: %d\n", rbuf[0]);
	printf("Version: %d.%d\n", rbuf[1]>>4, rbuf[1] & 0x0F);
	printf("Memory: %d Kb\n", rbuf[2]*8);
	printf("Protocol version: %d\n", rbuf[3]);
	printf("Software version: %d\n", rbuf[4]);
	printf("Order: %d\n", rbuf[5]);
	
	r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
	if (r) {
		fprintf(stderr, "Error: Get serial failed: %s\n", sc_strerror(r));
		return -1;
	}
	printf("Serial number: ");
	util_hex_dump(stdout, serial.value, serial.len, NULL);
	putchar('\n');
	return 0;
}
Beispiel #2
0
static int entersafe_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
								sc_file_t *df, sc_pkcs15_object_t *pin_obj,
								const unsigned char *pin, size_t pin_len,
								const unsigned char *puk, size_t puk_len)
{
	struct sc_card *card = p15card->card;
	int	r;
	sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
		return SC_ERROR_OBJECT_NOT_VALID;

	{/*pin*/
		 sc_entersafe_wkey_data  data;

		 if (!pin || !pin_len || pin_len > 16)
			  return SC_ERROR_INVALID_ARGUMENTS;

		 data.key_id = auth_info->attrs.pin.reference;
		 data.usage=0x0B;
		 data.key_data.symmetric.EC=0x33;
		 data.key_data.symmetric.ver=0x00;
		 /* pad pin with 0 */
		 memset(data.key_data.symmetric.key_val, 0, sizeof(data.key_data.symmetric.key_val));
		 memcpy(data.key_data.symmetric.key_val, pin, pin_len);
		 data.key_data.symmetric.key_len=16;

		 r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);

		 /* Cache new PIN value. */
		 sc_pkcs15_pincache_add(p15card, pin_obj, pin, pin_len);
	}

	{/*puk*/
		 sc_entersafe_wkey_data  data;

		 if (!puk || !puk_len || puk_len > 16)
			  return SC_ERROR_INVALID_ARGUMENTS;

		 data.key_id = auth_info->attrs.pin.reference+1;
		 data.usage=0x0B;
		 data.key_data.symmetric.EC=0x33;
		 data.key_data.symmetric.ver=0x00;
		 /* pad pin with 0 */
		 memset(data.key_data.symmetric.key_val, 0, sizeof(data.key_data.symmetric.key_val));
		 memcpy(data.key_data.symmetric.key_val, puk, puk_len);
		 data.key_data.symmetric.key_len=16;

		 r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
	}


	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r);
}
Beispiel #3
0
/*
 * Create a new PIN
 */
static int
setcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
	sc_file_t *df,
	sc_pkcs15_object_t *pin_obj,
	const u8 *pin, size_t pin_len,
	const u8 *puk, size_t puk_len)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data;
	sc_file_t *pinfile = NULL;
	int r, ignore_ac = 0;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

	if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
		return SC_ERROR_OBJECT_NOT_VALID;

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

	r = sc_select_file(p15card->card, &pinfile->path, &pinfile);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select 'pinfile'");

	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "pinfile->status:%X", pinfile->status);
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create PIN with reference:%X, flags:%X, path:%s",
			auth_info->attrs.pin.reference, auth_info->attrs.pin.flags, sc_print_path(&auth_info->path));

	if (pinfile->status == SC_FILE_STATUS_CREATION)
		ignore_ac = 1;

	r = setcos_create_pin_internal(profile, p15card, ignore_ac, auth_info,
			pin, pin_len, puk, puk_len);

	/* If pinfile is in 'Creation' state and SOPIN has been created,
	 * change status of MF and 'pinfile' to 'Operational:Activated'
	 */
	if (ignore_ac && (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN))   {
		sc_file_t *mf = profile->mf_info->file;

		r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_ACTIVATE_FILE, NULL);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot set 'pinfile' into the activated state");

		r = sc_select_file(p15card->card, &mf->path, NULL);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select MF");

		r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_ACTIVATE_FILE, NULL);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot set MF into the activated state");
	}

	sc_file_free(pinfile);

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
Beispiel #4
0
static int list_sdos(char *sdo_tag)
{
	struct iasecc_sdo sdo;
	struct iasecc_se_info se;
	unsigned sdo_class = 0;
	int rv, ii, jj;

	if (!sdo_tag)
		goto usage;

	if (*sdo_tag == 'x' || *sdo_tag == 'X')
		sdo_class = strtol(sdo_tag + 1, NULL, 16);
	else if ((strlen(sdo_tag) > 2) && (*(sdo_tag + 1) == 'x' || *(sdo_tag + 1) == 'X'))
		sdo_class = strtol(sdo_tag + 2, NULL, 16);
	else
		sdo_class = strtol(sdo_tag, NULL, 10);

	sdo_class &= 0x7F;
	if (sdo_class == IASECC_SDO_CLASS_SE)   {
		for (ii=1; ii<0x20; ii++)   {
			memset(&se, 0, sizeof(se));
			se.reference = ii;

			rv = sc_card_ctl(card, SC_CARDCTL_GET_SE_INFO, &se);
			if (!rv)   {
				printf("Found SE #%X\n", se.reference);
				_iasecc_print_docp(&se.docp);
				for(jj=0; jj<SC_MAX_CRTS_IN_SE && se.crts[jj].tag; jj++)
					_iasecc_print_crt(&se.crts[jj]);
			}
		}
	}
	else   {
		for (ii=1; ii<0x20; ii++)   {
			memset(&sdo, 0, sizeof(sdo));
			sdo.sdo_class = sdo_class;
			sdo.sdo_ref  = ii;

			rv = sc_card_ctl(card, SC_CARDCTL_IASECC_SDO_GET_DATA, &sdo);
			if (!rv)   {
				printf("Found SDO class %X, reference %X\n", sdo.sdo_class, sdo.sdo_ref);
				_iasecc_print_docp(&sdo.docp);
			}
		}
	}
	return 0;
usage:
	puts("Usage: list_sdos <SDO class>");
	return -1;
}
Beispiel #5
0
/*
 * Erase the card
 */
static int
gpk_erase_card(struct sc_profile *pro, sc_pkcs15_card_t *p15card)
{
	int	locked;

	if (sc_card_ctl(p15card->card, SC_CARDCTL_GPK_IS_LOCKED, &locked) == 0
	 && locked) {
		sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL,
			"This card is already personalized, unable to "
			"create PKCS#15 structure.");
		return SC_ERROR_NOT_SUPPORTED;
	}
	return sc_card_ctl(p15card->card, SC_CARDCTL_ERASE_CARD, NULL);
}
Beispiel #6
0
int sc_pkcs15emu_tcos_init_ex(
	sc_pkcs15_card_t   *p15card,
	sc_pkcs15emu_opt_t *opts
){
	sc_card_t         *card = p15card->card;
	sc_context_t      *ctx = p15card->card->ctx;
	sc_serial_number_t serialnr;
	char               serial[30];
	int i, r;

	/* check if we have the correct card OS unless SC_PKCS15EMU_FLAGS_NO_CHECK */
	i=(opts && (opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK));
	if (!i && card->type!=SC_CARD_TYPE_TCOS_V2 && card->type!=SC_CARD_TYPE_TCOS_V3) return SC_ERROR_WRONG_CARD;

	/* get the card serial number */
	r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serialnr);
	if (r < 0) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "unable to get ICCSN\n");
		return SC_ERROR_WRONG_CARD;
	}
        sc_bin_to_hex(serialnr.value, serialnr.len , serial, sizeof(serial), 0);
	serial[19] = '\0';
        p15card->tokeninfo->serial_number = strdup(serial);

	if(!detect_netkey(p15card)) return SC_SUCCESS;
	if(!detect_idkey(p15card)) return SC_SUCCESS;
	if(!detect_unicard(p15card)) return SC_SUCCESS;
	if(!detect_signtrust(p15card)) return SC_SUCCESS;
	if(!detect_datev(p15card)) return SC_SUCCESS;

	return SC_ERROR_INTERNAL;
}
Beispiel #7
0
static int entersafe_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
							   sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key)
{
	sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data;
	sc_card_t *card = p15card->card;
	sc_entersafe_wkey_data data;
	sc_file_t              *tfile;
	const sc_acl_entry_t   *acl_entry;
	int r;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

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

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

	data.key_id = (u8) kinfo->key_reference;
	data.usage=0x22;
	data.key_data.rsa=&key->u.rsa;
	return sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
}
Beispiel #8
0
/**
 * Stores an external (RSA) on the card.
 * @param  profile  profile information for this card
 * @param  card     sc_card_t object to use
 * @param  obj      sc_pkcs15_object_t object with pkcs15 information
 * @param  key      the private key
 * @return SC_SUCCESS on success and an error code otherwise
 **/
static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
                             sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key)
{
    sc_card_t *card = p15card->card;
    sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data;
    struct sc_pkcs15_prkey_rsa *rsa = &(key->u.rsa);
    sc_cardctl_openpgp_keystore_info_t key_info;
    int r;

    LOG_FUNC_CALLED(card->ctx);

    if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
        sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "only RSA is currently supported");
        return SC_ERROR_NOT_SUPPORTED;
    }

    memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keystore_info_t));
    key_info.keytype = kinfo->id.value[0];
    key_info.e = rsa->exponent.data;
    key_info.e_len = rsa->exponent.len;
    key_info.p = rsa->p.data;
    key_info.p_len = rsa->p.len;
    key_info.q = rsa->q.data;
    key_info.q_len = rsa->q.len;
    key_info.n = rsa->modulus.data;
    key_info.n_len = rsa->modulus.len;
    r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info);

    LOG_FUNC_RETURN(card->ctx, r);
}
Beispiel #9
0
int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len)
{
	int r;
	sc_cardctl_openpgp_keygen_info_t key_info;
	u8 fingerprints[60];
	sc_path_t path;
	sc_file_t *file;

	if (key_id < 1 || key_id > 3) {
		printf("Unknown key ID %d.\n", key_id);
		return 1;
	}
	memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keygen_info_t));
	key_info.keytype = key_id;
	key_info.modulus_len = key_len;
	key_info.modulus = malloc(key_len/8);
	r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info);
	free(key_info.modulus);
	if (r < 0) {
		printf("Failed to generate key. Error %s.\n", sc_strerror(r));
		return 1;
	}
	sc_format_path("006E007300C5", &path);
	r = sc_select_file(card, &path, &file);
	r = sc_read_binary(card, 0, fingerprints, 60, 0);
	if (r < 0) {
		printf("Failed to retrieve fingerprints. Error %s.\n", sc_strerror(r));
		return 1;
	}
	printf("Fingerprint:\n%s\n", (char *)sc_dump_hex(fingerprints + 20*(key_id - 1), 20));
	return 0;
}
Beispiel #10
0
static int rutoken_cipher(sc_card_t *card, u8 keyid,
		const u8 *in, size_t inlen,
		u8 *out, size_t outlen, int oper)
{
	int r;
	struct sc_rutoken_decipherinfo inf = { in, inlen, out, outlen };
	sc_security_env_t env;
	int cmd = (oper == OP_ENCRYPT) ?
			SC_CARDCTL_RUTOKEN_GOST_ENCIPHER :
			SC_CARDCTL_RUTOKEN_GOST_DECIPHER;

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

	/*  set security env  */
	r = sc_set_security_env(card, &env, 0);
	if (r) {
		fprintf(stderr, "Error: Cipher failed (set security environment): %s\n",
		        sc_strerror(r));
		return -1;
	}
	/*  cipher  */
	r = sc_card_ctl(card, cmd, &inf);
	if (r) {
		fprintf(stderr, "Error: Cipher failed: %s\n", sc_strerror(r));
		return -1;
	}
	return 0;
}
Beispiel #11
0
static int generate_gostkey(sc_card_t *card, u8 keyid, u8 keyoptions)
{
	const sc_SecAttrV2_t gk_sec_attr = 
		{0x44, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 2};
	sc_DOHdrV2_t paramkey;
	int r;

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

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

        r = sc_card_ctl(card, SC_CARDCTL_RUTOKEN_GENERATE_KEY_DO, &paramkey);
	if (r) {
		fprintf(stderr, "Error: Generate GOST key failed: %s\n", sc_strerror(r));
		return -1;
	}
	return 0;
}
/*
 * Erase the card.
 */
static int
myeid_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card) {
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_cardctl_myeid_data_obj data_obj;
	struct sc_file *mf = NULL;
	unsigned char data[8];
	int r;

	LOG_FUNC_CALLED(ctx);

	r = myeid_get_init_applet_data(profile, p15card, data, sizeof (data));
	LOG_TEST_RET(ctx, r, "Get init applet date error");

	/* Select parent DF and verify PINs/key as necessary */
	r = sc_select_file(p15card->card, sc_get_mf_path(), &mf);
	LOG_TEST_RET(ctx, r, "Cannot select MF");

	/* ACLs are not actives if file is not in the operational state */
	if (mf->status == SC_FILE_STATUS_ACTIVATED)
		r = sc_pkcs15init_authenticate(profile, p15card, mf, SC_AC_OP_DELETE);
	LOG_TEST_RET(ctx, r, "'DELETE' authentication failed on MF");

	data_obj.P1 = 0x01;
	data_obj.P2 = 0xE0;
	data_obj.Data = data;
	data_obj.DataLen = sizeof (data);

	r = sc_card_ctl(p15card->card, SC_CARDCTL_MYEID_PUTDATA, &data_obj);

	LOG_FUNC_RETURN(p15card->card->ctx, r);
}
Beispiel #13
0
/*
 * On-board key generation.
 */
static int
gpk_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
                        sc_pkcs15_object_t *obj,
                        sc_pkcs15_pubkey_t *pubkey)
{
	struct sc_cardctl_gpk_genkey args;
	sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
	unsigned int    keybits;
	sc_file_t	*keyfile;
	int             r, n;

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

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

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

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

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

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

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

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

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

	pubkey->algorithm = SC_ALGORITHM_RSA;
	return gpk_read_rsa_key(p15card->card, &pubkey->u.rsa);
}
Beispiel #14
0
static int sc_pkcs15emu_entersafe_init( sc_pkcs15_card_t *p15card)
{
	int    r;
	char   buf[256];
	sc_card_t *card = p15card->card;
	sc_serial_number_t serial;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	/* get serial number */
	r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
	if (r != SC_SUCCESS)
		return SC_ERROR_INTERNAL;
	r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0);
	if (r != SC_SUCCESS)
		return SC_ERROR_INTERNAL;
	if (p15card->tokeninfo->serial_number)
		free(p15card->tokeninfo->serial_number);
	p15card->tokeninfo->serial_number = malloc(strlen(buf) + 1);
	if (!p15card->tokeninfo->serial_number)
		return SC_ERROR_INTERNAL;
	strcpy(p15card->tokeninfo->serial_number, buf);

	/* the manufacturer ID, in this case Giesecke & Devrient GmbH */
	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);

	return SC_SUCCESS;
}
Beispiel #15
0
/*
 * Create an empty security environment
 */
static int
incrypto34_create_sec_env(struct sc_profile *profile, struct sc_card *card,
		unsigned int se_id, unsigned int key_id)
{
	struct sc_cardctl_incrypto34_obj_info args;
	struct tlv	tlv;
	unsigned char	buffer[64];

	tlv_init(&tlv, buffer, sizeof(buffer));
	tlv_next(&tlv, 0x83);
	tlv_add(&tlv, se_id);

	tlv_next(&tlv, 0x86);
	tlv_add(&tlv, 0);
	tlv_add(&tlv, 0);

	tlv_next(&tlv, 0x8f);
	tlv_add(&tlv, key_id);
	tlv_add(&tlv, key_id);
	tlv_add(&tlv, key_id);
	tlv_add(&tlv, key_id);
	tlv_add(&tlv, key_id);
	tlv_add(&tlv, key_id);

	args.data = buffer;
	args.len = tlv_len(&tlv);
	return sc_card_ctl(card, SC_CARDCTL_INCRYPTO34_PUT_DATA_SECI, &args);
}
Beispiel #16
0
/*
 * Create an empty security environment
 */
static int
cardos_create_sec_env(struct sc_profile *profile, sc_card_t *card,
		unsigned int se_id, unsigned int key_id)
{
	struct sc_cardctl_cardos_obj_info args;
	struct tlv	tlv;
	unsigned char	buffer[64];
	int		r;

	tlv_init(&tlv, buffer, sizeof(buffer));
	tlv_next(&tlv, 0x83);
	tlv_add(&tlv, se_id);

	tlv_next(&tlv, 0x86);
	tlv_add(&tlv, 0);
	tlv_add(&tlv, 0);

	tlv_next(&tlv, 0x8f);
	tlv_add(&tlv, key_id);
	tlv_add(&tlv, key_id);
	tlv_add(&tlv, key_id);
	tlv_add(&tlv, key_id);
	tlv_add(&tlv, key_id);
	tlv_add(&tlv, key_id);

	args.data = buffer;
	args.len = tlv_len(&tlv);

	/* ensure we are in the correct lifecycle */
	r = sc_pkcs15init_set_lifecycle(card, SC_CARDCTRL_LIFECYCLE_ADMIN);
	if (r < 0 && r != SC_ERROR_NOT_SUPPORTED)
		return r;

	return sc_card_ctl(card, SC_CARDCTL_CARDOS_PUT_DATA_SECI, &args);
}
Beispiel #17
0
/*
 * Generate key
 */
static int
cflex_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
			sc_pkcs15_object_t *obj,
			sc_pkcs15_pubkey_t *pubkey)
{
	struct sc_cardctl_cryptoflex_genkey_info args;
	sc_card_t *card = p15card->card;
	sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
	unsigned int	keybits;
	unsigned char	raw_pubkey[256];
	sc_file_t	*prkf = NULL, *pukf = NULL;
	int		r;

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

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

	keybits = key_info->modulus_length;

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

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

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

out:	if (pukf)
		sc_file_free(pukf);
	if (prkf)
		sc_file_free(prkf);
	return r;
}
/*
 * Store a private key
 */
static int
myeid_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
		struct sc_pkcs15_object *object, 
		struct sc_pkcs15_prkey *prkey)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_card *card = p15card->card;
	struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
	struct sc_cardctl_myeid_gen_store_key_info args;
	struct sc_file *file = NULL;
	int r, keybits = key_info->modulus_length;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported");

	/* Check that the card supports the requested modulus length */
	if (sc_card_find_rsa_alg(p15card->card, keybits) == NULL)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Unsupported key size");

	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "store MyEID key with ID:%s and path:%s", 
			sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path));

	r = sc_select_file(card, &key_info->path, &file);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot store MyEID key: select key file failed");
	
	r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No authorisation to store MyEID private key");

	if (file) 
		sc_file_free(file);

	/* Fill in data structure */
	memset(&args, 0, sizeof(args));
	args.mod_len = keybits;
	args.op_type    = OP_TYPE_STORE;
	args.pubexp_len = prkey->u.rsa.exponent.len;
	args.pubexp     = prkey->u.rsa.exponent.data;
	args.primep_len = prkey->u.rsa.p.len;
	args.primep     = prkey->u.rsa.p.data;
	args.primeq_len = prkey->u.rsa.q.len;
	args.primeq     = prkey->u.rsa.q.data;

	args.dp1_len    = prkey->u.rsa.dmp1.len;
	args.dp1        = prkey->u.rsa.dmp1.data;
	args.dq1_len    = prkey->u.rsa.dmq1.len;
	args.dq1        = prkey->u.rsa.dmq1.data;
	args.invq_len   = prkey->u.rsa.iqmp.len;
	args.invq       = prkey->u.rsa.iqmp.data;

	args.mod_len    = prkey->u.rsa.modulus.len;
	args.mod        = prkey->u.rsa.modulus.data;		

	/* Store RSA key  */
	r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_STORE_KEY, &args);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Card control 'MYEID_GENERATE_STORE_KEY' failed");

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
/*
 * Create a new PIN
 */
static int 
myeid_create_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
		struct sc_file *df, struct sc_pkcs15_object *pin_obj,
		const unsigned char *pin, size_t pin_len,
		const unsigned char *puk, size_t puk_len)
{
	struct sc_context *ctx = p15card->card->ctx;
	unsigned char  data[20];
	struct sc_cardctl_myeid_data_obj data_obj;
	struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data;
        struct sc_pkcs15_auth_info puk_ainfo;
	int	r;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PIN('%s',ref:%i,flags:0x%X,pin_len:%d,puk_len:%d)\n",
                            pin_obj->label, auth_info->attrs.pin.reference, auth_info->attrs.pin.flags, pin_len, puk_len);

	if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
		return SC_ERROR_OBJECT_NOT_VALID;
	if (auth_info->attrs.pin.reference >= MYEID_MAX_PINS)
		return SC_ERROR_INVALID_ARGUMENTS;
	if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4)
		return SC_ERROR_INVALID_PIN_LENGTH;

	sc_profile_get_pin_info(profile, (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) 
			? SC_PKCS15INIT_SO_PUK : SC_PKCS15INIT_USER_PUK, 
			&puk_ainfo);

	memset(data, 0, sizeof(data));
	/* Make command to add a pin-record */
	data_obj.P1 = 0x01;
	data_obj.P2 = auth_info->attrs.pin.reference;	/* myeid pin number */
	
	memset(data, auth_info->attrs.pin.pad_char, 8);
	memcpy(&data[0], (u8 *)pin, pin_len);   /* copy pin */

	memset(&data[8], puk_ainfo.attrs.pin.pad_char, 8);
	memcpy(&data[8], (u8 *)puk, puk_len);   /* copy puk */

	if(auth_info->tries_left > 0 && auth_info->tries_left < 15)
		data[16] = auth_info->tries_left;
	else
		data[16] = 5;	/* default value */

	if(puk_ainfo.tries_left > 0 && puk_ainfo.tries_left < 15)
		data[17] = puk_ainfo.tries_left;
	else
		data[17] = 5;	/* default value */

	data[18] = 0x00;

	data_obj.Data    = data;
	data_obj.DataLen = 19;

	r = sc_card_ctl(p15card->card, SC_CARDCTL_MYEID_PUTDATA, &data_obj);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Initialize PIN failed");

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
Beispiel #20
0
static int entersafe_erase_card(struct sc_profile *profile, sc_pkcs15_card_t *p15card)
{
	SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);

	if (sc_select_file(p15card->card, sc_get_mf_path(), NULL) < 0)
		return SC_SUCCESS;

	return sc_card_ctl(p15card->card,SC_CARDCTL_ERASE_CARD,0);
}
Beispiel #21
0
/*
 * Lock a file operation
 */
static int
gpk_lock(sc_card_t *card, sc_file_t *file, unsigned int op)
{
	struct sc_cardctl_gpk_lock	args;

	args.file = file;
	args.operation = op;
	return sc_card_ctl(card, SC_CARDCTL_GPK_LOCK, &args);
}
/*
 * Create a new PIN
 */
static int myeid_create_pin_internal(sc_profile_t *profile, sc_card_t *card,
		int ignore_ac, sc_pkcs15_pin_info_t *pin_info,
		const u8 *pin, size_t pin_len,
		const u8 *puk, size_t puk_len)
{
	u8  data[20];
	int so_pin_ref;
	int	r,type, puk_tries;
	struct sc_cardctl_myeid_data_obj data_obj;
	sc_file_t *pinfile = NULL;

	SC_FUNC_CALLED(card->ctx, 1);
	sc_debug(card->ctx, "pin (%d), pin_len (%d), puk_len(%d) \n",
                            pin_info->reference, pin_len, puk_len);

	if (pin_info->reference >= MYEID_MAX_PINS)
		return SC_ERROR_INVALID_ARGUMENTS;
	if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4)
		return SC_ERROR_INVALID_PIN_LENGTH;

	if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN)
	  type = SC_PKCS15INIT_SO_PIN;
	else
	  type = SC_PKCS15INIT_USER_PIN;

	sc_debug(card->ctx, "pin type (%s)\n",
                             (type == SC_PKCS15INIT_SO_PIN) ? "SO_PIN": "USER_PIN");

	memset(data, 0xFF, sizeof(data));
	/* Make command to add a pin-record */
	data_obj.P1 = 01;
	data_obj.P2 = pin_info->reference;	/* myeid pin number */
	
	memcpy(&data[0], (u8 *)pin, pin_len);   /* copy pin*/
	memcpy(&data[8], (u8 *)puk, puk_len);   /* copy puk */

        data[16] = 0x00;
	data[17] = 0x00;
	data[18] = 0x00;

	data_obj.Data    = data;
	data_obj.DataLen = 16;

	puk_tries = myeid_puk_retries(profile, pin_info);
	if(pin_info->tries_left > 0 && pin_info->tries_left < 15 &&
           puk_tries > 0 && puk_tries < 15)
	{
	    /* Optional PIN locking */
	    data[16] = (pin_info->tries_left & 0x0F);
	    data[17] = (puk_tries & 0x0F);
	    data_obj.DataLen = 19;
	}

	r = sc_card_ctl(card, SC_CARDCTL_MYEID_PUTDATA, &data_obj);

	SC_FUNC_RETURN(card->ctx, 1, r);
}
Beispiel #23
0
/*
 * Store a private key object.
 */
static int
muscle_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
			sc_pkcs15_object_t *obj,
			sc_pkcs15_prkey_t *key)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
	sc_file_t* prkf;
	struct sc_pkcs15_prkey_rsa *rsa;
	sc_cardctl_muscle_key_info_t info;
	int		r;
	
	if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Muscle supports RSA keys only.");
		return SC_ERROR_NOT_SUPPORTED;
	}
	/* Verification stuff */
	/* Used for verification AND for obtaining private key acls */
	r = sc_profile_get_file_by_path(profile, &key_info->path, &prkf);
	if(!prkf) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_NOT_SUPPORTED);
	r = sc_pkcs15init_authenticate(profile, p15card, prkf, SC_AC_OP_CRYPTO);
	if (r < 0) {
		sc_file_free(prkf);
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_NOT_SUPPORTED);
	}
	sc_file_free(prkf);
	r = muscle_select_key_reference(profile, p15card, key_info);
	if (r < 0) {
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,r);
	}
	rsa = &key->u.rsa;
	
	info.keySize = rsa->modulus.len << 3;
	info.keyType = 0x03; /* CRT type */
	info.keyLocation = key_info->key_reference * 2; /* Mult by 2 to preserve even/odd keynumber structure */
	
	info.pLength = rsa->p.len;
	info.pValue = rsa->p.data;
	info.qLength = rsa->q.len;
	info.qValue = rsa->q.data;
	
	info.pqLength = rsa->iqmp.len;
	info.pqValue = rsa->iqmp.data;
	
	info.dp1Length = rsa->dmp1.len;
	info.dp1Value = rsa->dmp1.data;
	info.dq1Length = rsa->dmq1.len;
	info.dq1Value = rsa->dmq1.data;
	
	r = sc_card_ctl(p15card->card, SC_CARDCTL_MUSCLE_IMPORT_KEY, &info);
	if (r < 0) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unable to import key");
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,r);
	}
	return r;
}
Beispiel #24
0
static int
gpk_pkfile_init_private(sc_card_t *card,
		sc_file_t *file, unsigned int privlen)
{
	struct sc_cardctl_gpk_pkinit args;

	args.file = file;
	args.privlen = privlen;
	return sc_card_ctl(card, SC_CARDCTL_GPK_PKINIT, &args);
}
Beispiel #25
0
static int westcos_pkcs15init_finalize_card(sc_profile_t *profile, sc_card_t *card)
{
	int r;

	/* be sure authentificate card */
	r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_AUT_KEY, NULL);
	if(r) return (r);

	return sc_pkcs15init_set_lifecycle(card, SC_CARDCTRL_LIFECYCLE_USER);
}
Beispiel #26
0
/*
 * Erase everything that's on the card
 */
static int rtecp_erase(sc_profile_t *profile, sc_pkcs15_card_t *p15card)
{
	int r;

	if (!profile || !p15card || !p15card->card)
		return SC_ERROR_INVALID_ARGUMENTS;
	r = sc_card_ctl(p15card->card, SC_CARDCTL_RTECP_INIT, NULL);
	if (r == SC_SUCCESS)
		sc_free_apps(p15card->card);
	return r;
}
Beispiel #27
0
/* pre secure channel creator initialization routine */
static int dnie_create_pre_ops(sc_card_t * card, cwa_provider_t * provider)
{
	sc_serial_number_t serial;

	/* make sure that this cwa provider is used with a working DNIe card */
	if (card->type != SC_CARD_TYPE_DNIE_USER)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD);

	/* ensure that Card Serial Number is properly cached */
	return sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
}
static void print_serial(sc_card_t *in_card)
{
	int r;
	sc_serial_number_t serial;

	r = sc_card_ctl(in_card, SC_CARDCTL_GET_SERIALNR, &serial);
	if (r)
		fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_GET_SERIALNR, *) failed\n");
	else
		hex_dump_asc(stdout, serial.value, serial.len, -1);
}
Beispiel #29
0
static int
gpk_pkfile_load_private(sc_card_t *card, sc_file_t *file,
			u8 *data, unsigned int len, unsigned int datalen)
{
	struct sc_cardctl_gpk_pkload args;

	args.file = file;
	args.data = data;
	args.len  = len;
	args.datalen = datalen;
	return sc_card_ctl(card, SC_CARDCTL_GPK_PKLOAD, &args);
}
Beispiel #30
0
static int entersafe_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
								  sc_pkcs15_object_t *obj, sc_pkcs15_pubkey_t *pubkey)
{
	int r;
	sc_entersafe_gen_key_data	gendat;
	sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data;
	sc_card_t *card = p15card->card;
	sc_file_t              *tfile;
	const sc_acl_entry_t   *acl_entry;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA)
		return SC_ERROR_NOT_SUPPORTED;

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

	/* generate key pair */
	gendat.key_id     = (u8) kinfo->key_reference;
	gendat.key_length = (size_t) kinfo->modulus_length;
	gendat.modulus    = NULL;
	r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_GENERATE_KEY, &gendat);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "EnterSafe generate RSA key pair failed");

	/* get the modulus via READ PUBLIC KEY */
	if (pubkey) {
		u8 *buf;
		struct sc_pkcs15_pubkey_rsa *rsa = &pubkey->u.rsa;
		/* set the modulus */
		rsa->modulus.data = gendat.modulus;
		rsa->modulus.len  = kinfo->modulus_length >> 3;
		/* set the exponent (always 0x10001) */
		buf = malloc(3);
		if (!buf)
			return SC_ERROR_OUT_OF_MEMORY;
		buf[0] = 0x01;
		buf[1] = 0x00;
		buf[2] = 0x01;
		rsa->exponent.data = buf;
		rsa->exponent.len  = 3;

		pubkey->algorithm = SC_ALGORITHM_RSA;
	} else