예제 #1
0
파일: card-npa.c 프로젝트: AktivCo/OpenSC
static int npa_match_card(sc_card_t * card)
{
	int r = 0;

	if (0 == r && SC_SUCCESS == sc_enum_apps(card)) {
		unsigned char esign_aid_0[] = {
			0xE8, 0x28, 0xBD, 0x08, 0x0F, 0xA0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E,
		}, esign_aid_1[] = {
			0xa0, 0x00, 0x00, 0x02, 0x47, 0x10, 0x01,
		}, esign_aid_2[] = {
			0xe8, 0x07, 0x04, 0x00, 0x7f, 0x00, 0x07, 0x03, 0x02,
		}, esign_aid_3[] = {
			0xA0, 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, 0x49, 0x47, 0x4E,
		};
		int i, found_0 = 0, found_1 = 0, found_2 = 0, found_3 = 0;
		for (i = 0; i < card->app_count; i++)   {
			struct sc_app_info *app_info = card->app[i];
			if (sizeof esign_aid_0 == app_info->aid.len
					&& 0 == memcmp(esign_aid_0, app_info->aid.value,
						sizeof esign_aid_0))
				found_0 = 1;
			if (sizeof esign_aid_1 == app_info->aid.len
					&& 0 == memcmp(esign_aid_1, app_info->aid.value,
						sizeof esign_aid_1))
				found_1 = 1;
			if (sizeof esign_aid_2 == app_info->aid.len
					&& 0 == memcmp(esign_aid_2, app_info->aid.value,
						sizeof esign_aid_2))
				found_2 = 1;
			if (sizeof esign_aid_3 == app_info->aid.len
					&& 0 == memcmp(esign_aid_3, app_info->aid.value,
						sizeof esign_aid_3))
				found_3 = 1;
		}
		if (found_0 && found_1 && found_2 && found_3) {
			card->type = SC_CARD_TYPE_NPA;
			r = 1;
		}
	}

	return r;
}
예제 #2
0
static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card)
{
	unsigned char *buf = NULL;
	int    err, ok = 0;
	size_t len;
	sc_path_t tmppath;
	sc_card_t    *card = p15card->card;
	sc_context_t *ctx  = card->ctx;
	sc_pkcs15_tokeninfo_t tokeninfo;

	if (ctx->debug > 4)
		sc_debug(ctx, "trying normal pkcs15 processing\n");

	/* Enumerate apps now */
	if (card->app_count < 0) {
		err = sc_enum_apps(card);
		if (err < 0 && err != SC_ERROR_FILE_NOT_FOUND) {
			sc_error(ctx, "unable to enumerate apps: %s\n", sc_strerror(err));
			goto end;
		}
	}
	p15card->file_app = sc_file_new();
	if (p15card->file_app == NULL) {
		err = SC_ERROR_OUT_OF_MEMORY;
		goto end;
	}
	sc_format_path("3F005015", &p15card->file_app->path);
	if (card->app_count > 0) {
		const sc_app_info_t *info;
		
		info = sc_find_pkcs15_app(card);
		if (info != NULL) {
			if (info->path.len)
				p15card->file_app->path = info->path;
			if (info->ddo != NULL)
				parse_ddo(p15card, info->ddo, info->ddo_len);
		}
	}

	/* Check if pkcs15 directory exists */
	sc_ctx_suppress_errors_on(card->ctx);
	err = sc_select_file(card, &p15card->file_app->path, NULL);
#if 1
	/* If the above test failed on cards without EF(DIR),
	 * try to continue read ODF from 3F005031. -aet
	 */
	if ((err == SC_ERROR_FILE_NOT_FOUND) &&
	    (card->app_count < 1)) {
		sc_format_path("3F00", &p15card->file_app->path);
		err = SC_NO_ERROR;
	}
#endif
	sc_ctx_suppress_errors_off(card->ctx);
	if (err < 0)
		goto end;

	if (p15card->file_odf == NULL) {
		/* check if an ODF is present; suppress errors as we
		 * don't know yet whether we have a pkcs15 card */
		tmppath = p15card->file_app->path;
		sc_append_path_id(&tmppath, (const u8 *) "\x50\x31", 2);
		sc_ctx_suppress_errors_on(card->ctx);
		err = sc_select_file(card, &tmppath, &p15card->file_odf);
		sc_ctx_suppress_errors_off(card->ctx);
		
	} else {
		tmppath = p15card->file_odf->path;
		sc_file_free(p15card->file_odf);
		p15card->file_odf = NULL;
		err = sc_select_file(card, &tmppath, &p15card->file_odf);
	}
	if (err != SC_SUCCESS) {
		char pbuf[SC_MAX_PATH_STRING_SIZE];

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

		sc_debug(ctx, "EF(ODF) not found in '%s'\n", pbuf);
		goto end;
	}

	if ((len = p15card->file_odf->size) == 0) {
		sc_error(card->ctx, "EF(ODF) is empty\n");
		goto end;
	}
	buf = malloc(len);
	if(buf == NULL)
		return SC_ERROR_OUT_OF_MEMORY;
	err = sc_read_binary(card, 0, buf, len, 0);
	if (err < 0)
		goto end;
	if (err < 2) {
		err = SC_ERROR_PKCS15_APP_NOT_FOUND;
		goto end;
	}
	len = err;
	if (parse_odf(buf, len, p15card)) {
		err = SC_ERROR_PKCS15_APP_NOT_FOUND;
		sc_error(card->ctx, "Unable to parse ODF\n");
		goto end;
	}
	free(buf);
	buf = NULL;

	if (card->ctx->debug) {
		sc_pkcs15_df_t *df;

		sc_debug(card->ctx, "The following DFs were found:\n");
		for (df = p15card->df_list; df; df = df->next) {
			char pbuf[SC_MAX_PATH_STRING_SIZE];

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

			sc_debug(card->ctx,
				"  DF type %u, path %s, index %u, count %d\n",
				df->type, pbuf, df->path.index, df->path.count);
		}
	}

	if (p15card->file_tokeninfo == NULL) {
		tmppath = p15card->file_app->path;
		sc_append_path_id(&tmppath, (const u8 *) "\x50\x32", 2);
	} else {
		tmppath = p15card->file_tokeninfo->path;
		sc_file_free(p15card->file_tokeninfo);
		p15card->file_tokeninfo = NULL;
	}
	err = sc_select_file(card, &tmppath, &p15card->file_tokeninfo);
	if (err)
		goto end;

	if ((len = p15card->file_tokeninfo->size) == 0) {
		sc_error(card->ctx, "EF(TokenInfo) is empty\n");
		goto end;
	}
	buf = malloc(len);
	if(buf == NULL)
		return SC_ERROR_OUT_OF_MEMORY;
	err = sc_read_binary(card, 0, buf, len, 0);
	if (err < 0)
		goto end;
	if (err <= 2) {
		err = SC_ERROR_PKCS15_APP_NOT_FOUND;
		goto end;
	}

	memset(&tokeninfo, 0, sizeof(tokeninfo));
	err = sc_pkcs15_parse_tokeninfo(ctx, &tokeninfo, buf, (size_t)err);
	if (err != SC_SUCCESS)
		goto end;
	p15card->version         = tokeninfo.version;
	p15card->label           = tokeninfo.label;
	p15card->serial_number   = tokeninfo.serial_number;
	p15card->manufacturer_id = tokeninfo.manufacturer_id;
	p15card->last_update     = tokeninfo.last_update;
	p15card->flags           = tokeninfo.flags;
	p15card->preferred_language = tokeninfo.preferred_language;
	p15card->seInfo          = tokeninfo.seInfo;
	p15card->num_seInfo      = tokeninfo.num_seInfo;

	/* for cardos cards initialized by Siemens: sign with decrypt */
	if (strcmp(p15card->card->driver->short_name,"cardos") == 0
                && ( strcmp(p15card->manufacturer_id,"Siemens AG (C)") == 0
			|| strcmp(p15card->manufacturer_id,"Prime") == 0 ))
		p15card->flags |= SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT;

	ok = 1;
end:
	if(buf != NULL)
		free(buf);
	if (!ok) {
		sc_pkcs15_card_clear(p15card);
		return err;
	}

	return SC_SUCCESS;
}