Example #1
0
static int
iasecc_parse_docp(struct sc_card *card, unsigned char *data, size_t data_len, struct iasecc_sdo *sdo)
{
	struct sc_context *ctx = card->ctx;
	size_t offs = 0;
	int rv;

	LOG_FUNC_CALLED(ctx);
	while(offs < data_len)   {
		struct iasecc_extended_tlv tlv;

		rv = iasecc_parse_get_tlv(card, data + offs, &tlv);
		LOG_TEST_RET(ctx, rv, "iasecc_parse_get_tlv() get and parse TLV error");

		sc_log(ctx, "iasecc_parse_docp() parse_get_tlv retuned %i; tag %X; size %i",  rv, tlv.tag, tlv.size);

		if (tlv.tag == IASECC_DOCP_TAG_ACLS)   {
			int _rv = iasecc_parse_docp(card, tlv.value, tlv.size, sdo);
			free(tlv.value);
			LOG_TEST_RET(ctx, _rv, "parse error: cannot parse DOCP");
		}
		else if (tlv.tag == IASECC_DOCP_TAG_ACLS_CONTACT)   {
			sdo->docp.acls_contact = tlv;
		}
		else if (tlv.tag == IASECC_DOCP_TAG_ACLS_CONTACTLESS)   {
			sdo->docp.acls_contactless = tlv;
		}
		else if (tlv.tag == IASECC_DOCP_TAG_SIZE)   {
			sdo->docp.size = tlv;
		}
		else if (tlv.tag == IASECC_DOCP_TAG_NAME)   {
			sdo->docp.name = tlv;
		}
		else if (tlv.tag == IASECC_DOCP_TAG_ISSUER_DATA)   {
			sdo->docp.issuer_data = tlv;
		}
		else if (tlv.tag == IASECC_DOCP_TAG_NON_REPUDATION)   {
			sdo->docp.non_repudiation = tlv;
		}
		else if (tlv.tag == IASECC_DOCP_TAG_USAGE_REMAINING)   {
			sdo->docp.usage_remaining = tlv;
		}
		else if (tlv.tag == IASECC_DOCP_TAG_TRIES_MAXIMUM)   {
			sdo->docp.tries_maximum = tlv;
		}
		else if (tlv.tag == IASECC_DOCP_TAG_TRIES_REMAINING)   {
			sdo->docp.tries_remaining = tlv;
		}
		else   {
			LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "iasecc_parse_get_tlv() parse error: non DOCP tag");
		}

		offs += rv;
	}

	rv = iasecc_parse_acls(card, &sdo->docp, 0);
	LOG_TEST_RET(ctx, rv, "Cannot parse ACLs in DOCP");

	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
Example #2
0
static int
iasecc_parse_chv(struct sc_card *card, unsigned char *data, size_t data_len, struct iasecc_sdo_chv *chv)
{
	struct sc_context *ctx = card->ctx;
	size_t offs = 0;
	int rv;

	LOG_FUNC_CALLED(ctx);
	while(offs < data_len)   {
		struct iasecc_extended_tlv tlv;

		rv = iasecc_parse_get_tlv(card, data + offs, &tlv);
		LOG_TEST_RET(ctx, rv, "iasecc_parse_chv() get and parse TLV error");

		sc_log(ctx, "iasecc_parse_chv() get and parse TLV returned %i; tag %X; size %i",  rv, tlv.tag, tlv.size);

		if (tlv.tag == IASECC_SDO_CHV_TAG_SIZE_MAX)
			chv->size_max = tlv;
		else if (tlv.tag == IASECC_SDO_CHV_TAG_SIZE_MIN)
			chv->size_min = tlv;
		else if (tlv.tag == IASECC_SDO_CHV_TAG_VALUE)
			chv->value = tlv;
		else
			LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "parse error: non CHV SDO tag");

		offs += rv;
	}

	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
Example #3
0
static int
iasecc_parse_keyset(struct sc_card *card, unsigned char *data, size_t data_len, struct iasecc_sdo_keyset *keyset)
{
	struct sc_context *ctx = card->ctx;
	size_t offs = 0;
	int rv;

	LOG_FUNC_CALLED(ctx);
	while(offs < data_len)   {
		struct iasecc_extended_tlv tlv;

		rv = iasecc_parse_get_tlv(card, data + offs, &tlv);
		LOG_TEST_RET(ctx, rv, "iasecc_parse_keyset() get and parse TLV error");

		sc_log(ctx, "iasecc_parse_prvkey() get and parse TLV returned %i; tag %X; size %i",  rv, tlv.tag, tlv.size);

		if (tlv.tag == IASECC_SDO_KEYSET_TAG_COMPULSORY)
			keyset->compulsory = tlv;
		else
			LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "parse error: non KeySet SDO tag");

		offs += rv;
	}

	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
Example #4
0
static int
iasecc_parse_pubkey(struct sc_card *card, unsigned char *data, size_t data_len, struct iasecc_sdo_pubkey *pubkey)
{
	struct sc_context *ctx = card->ctx;
	size_t offs = 0;
	int rv;

	LOG_FUNC_CALLED(ctx);
	while(offs < data_len)   {
		struct iasecc_extended_tlv tlv;

		rv = iasecc_parse_get_tlv(card, data + offs, &tlv);
		LOG_TEST_RET(ctx, rv, "iasecc_parse_pubkey() get and parse TLV error");

		sc_log(ctx,
		       "iasecc_parse_pubkey() get and parse TLV returned %i; tag %X; size %"SC_FORMAT_LEN_SIZE_T"u",
		       rv, tlv.tag, tlv.size);

		if (tlv.tag == IASECC_SDO_PUBKEY_TAG_N)
			pubkey->n = tlv;
		else if (tlv.tag == IASECC_SDO_PUBKEY_TAG_E)
			pubkey->e = tlv;
		else if (tlv.tag == IASECC_SDO_PUBKEY_TAG_CHR)
			pubkey->chr = tlv;
		else if (tlv.tag == IASECC_SDO_PUBKEY_TAG_CHA)
			pubkey->cha = tlv;
		else if (tlv.tag == IASECC_SDO_PUBKEY_TAG_COMPULSORY)
			pubkey->compulsory = tlv;
		else
			LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "parse error: non PubKey SDO tag");

		offs += rv;
	}

	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
Example #5
0
static int
iasecc_sdo_parse_data(struct sc_card *card, unsigned char *data, struct iasecc_sdo *sdo)
{
	struct sc_context *ctx = card->ctx;
	struct iasecc_extended_tlv tlv;
	int tlv_size, rv;

	LOG_FUNC_CALLED(ctx);
	sc_log(ctx, "iasecc_sdo_parse_data() class %X; ref %X", sdo->sdo_class, sdo->sdo_ref);

	tlv_size = iasecc_parse_get_tlv(card, data, &tlv);
	LOG_TEST_RET(ctx, tlv_size, "parse error: get TLV");

	sc_log(ctx, "iasecc_sdo_parse_data() tlv.tag 0x%X", tlv.tag);
	if (tlv.tag == IASECC_DOCP_TAG)   {
		sc_log(ctx, "iasecc_sdo_parse_data() parse IASECC_DOCP_TAG: 0x%X; size %i", tlv.tag, tlv.size);
		rv = iasecc_parse_docp(card, tlv.value, tlv.size, sdo);
		sc_log(ctx, "iasecc_sdo_parse_data() parsed IASECC_DOCP_TAG rv %i", rv);
		free(tlv.value);
		LOG_TEST_RET(ctx, rv, "parse error: cannot parse DOCP");
	}
	else if (tlv.tag == IASECC_DOCP_TAG_NON_REPUDATION)   {
		sdo->docp.non_repudiation = tlv;
	}
	else if (tlv.tag == IASECC_DOCP_TAG_USAGE_REMAINING)   {
		sdo->docp.usage_remaining = tlv;
	}
	else if (tlv.tag == IASECC_DOCP_TAG_TRIES_MAXIMUM)   {
		sdo->docp.tries_maximum = tlv;
	}
	else if (tlv.tag == IASECC_DOCP_TAG_TRIES_REMAINING)   {
		sdo->docp.tries_remaining = tlv;
	}
	else if (tlv.tag == IASECC_SDO_CHV_TAG)   {
		if (sdo->sdo_class != IASECC_SDO_CLASS_CHV)
			LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: IASECC_SDO_CHV_TAG tag in non User CHV SDO");

		rv = iasecc_parse_chv(card, tlv.value, tlv.size, &sdo->data.chv);
		LOG_TEST_RET(ctx, rv, "parse error: cannot parse SDO CHV data");

		free(tlv.value);
	}
	else if (tlv.tag == IASECC_SDO_PUBKEY_TAG)   {
		if (sdo->sdo_class != IASECC_SDO_CLASS_RSA_PUBLIC)
			LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: SDO_PUBLIC_KEY tag in non PUBLIC_KEY SDO");

		rv = iasecc_parse_pubkey(card, tlv.value, tlv.size, &sdo->data.pub_key);
		LOG_TEST_RET(ctx, rv, "parse error: cannot parse SDO PUBLIC KEY data");

		free(tlv.value);
	}
	else if (tlv.tag == IASECC_SDO_PRVKEY_TAG)   {
		if (sdo->sdo_class != IASECC_SDO_CLASS_RSA_PRIVATE)
			LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: SDO_PRIVATE_KEY tag in non PRIVATE_KEY SDO");

		rv = iasecc_parse_prvkey(card, tlv.value, tlv.size, &sdo->data.prv_key);
		LOG_TEST_RET(ctx, rv, "parse error: cannot parse SDO PRIVATE KEY data");

		free(tlv.value);
	}
	else if (tlv.tag == IASECC_SDO_KEYSET_TAG)   {
		if (sdo->sdo_class != IASECC_SDO_CLASS_KEYSET)
			LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: SDO_KEYSET tag in non KEYSET SDO");

		rv = iasecc_parse_keyset(card, tlv.value, tlv.size, &sdo->data.keyset);
		LOG_TEST_RET(ctx, rv, "parse error: cannot parse SDO KEYSET data");

		free(tlv.value);
	}
	else   {
		sc_log(ctx, "iasecc_sdo_parse_data() non supported tag 0x%X", tlv.tag);
		LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
	}

	return tlv_size;
}