int iasecc_se_parse(struct sc_card *card, unsigned char *data, size_t data_len, struct iasecc_se_info *se) { struct sc_context *ctx = card->ctx; size_t size, offs, size_size; int rv; LOG_FUNC_CALLED(ctx); if (*data == IASECC_SDO_TEMPLATE_TAG) { size_size = iasecc_parse_size(data + 1, &size); LOG_TEST_RET(ctx, size_size, "parse error: invalid size data of IASECC_SDO_TEMPLATE"); data += size_size + 1; data_len = size; sc_log(ctx, "IASECC_SDO_TEMPLATE: size %i, size_size %i", size, size_size); if (*data != IASECC_SDO_TAG_HEADER) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); if ((*(data + 1) & 0x7F) != IASECC_SDO_CLASS_SE) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); size_size = iasecc_parse_size(data + 3, &size); LOG_TEST_RET(ctx, size_size, "parse error: invalid SDO SE data size"); if (data_len != size + size_size + 3) LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: invalide SDO SE data size"); data += 3 + size_size; data_len = size; sc_log(ctx, "IASECC_SDO_TEMPLATE SE: size %i, size_size %i", size, size_size); } if (*data != IASECC_SDO_CLASS_SE) { sc_log(ctx, "Invalid SE tag 0x%X; data length %i", *data, data_len); LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED); } size_size = iasecc_parse_size(data + 1, &size); LOG_TEST_RET(ctx, size_size, "parse error: invalid size data"); if (data_len != size + size_size + 1) LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: invalide SE data size"); offs = 1 + size_size; for (; offs < data_len;) { rv = iasecc_crt_parse(card, data + offs, se); LOG_TEST_RET(ctx, rv, "parse error: invalid SE data"); offs += rv; } if (offs != data_len) LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: not totaly parsed"); LOG_FUNC_RETURN(ctx, SC_SUCCESS); }
int iasecc_sdo_parse(struct sc_card *card, unsigned char *data, size_t data_len, struct iasecc_sdo *sdo) { struct sc_context *ctx = card->ctx; size_t size, offs, size_size; int rv; LOG_FUNC_CALLED(ctx); if (*data == IASECC_SDO_TEMPLATE_TAG) { size_size = iasecc_parse_size(data + 1, &size); LOG_TEST_RET(ctx, size_size, "parse error: invalid size data of IASECC_SDO_TEMPLATE"); data += size_size + 1; data_len = size; sc_log(ctx, "IASECC_SDO_TEMPLATE: size %"SC_FORMAT_LEN_SIZE_T"u, size_size %"SC_FORMAT_LEN_SIZE_T"u", size, size_size); } if (*data != IASECC_SDO_TAG_HEADER) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); if (sdo->sdo_class != (*(data + 1) & 0x7F)) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); if (sdo->sdo_ref != (*(data + 2) & 0x3F)) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); size_size = iasecc_parse_size(data + 3, &size); LOG_TEST_RET(ctx, size_size, "parse error: invalid size data"); if (data_len != size + size_size + 3) LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: invalid SDO data size"); sc_log(ctx, "sz %"SC_FORMAT_LEN_SIZE_T"u, sz_size %"SC_FORMAT_LEN_SIZE_T"u", size, size_size); offs = 3 + size_size; for (; offs < data_len;) { rv = iasecc_sdo_parse_data(card, data + offs, sdo); LOG_TEST_RET(ctx, rv, "parse error: invalid SDO data"); offs += rv; } if (offs != data_len) LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: not totally parsed"); sc_log(ctx, "docp.acls_contact.size %"SC_FORMAT_LEN_SIZE_T"u, docp.size.size %"SC_FORMAT_LEN_SIZE_T"u", sdo->docp.acls_contact.size, sdo->docp.size.size); LOG_FUNC_RETURN(ctx, SC_SUCCESS); }
static int iasecc_parse_get_tlv(struct sc_card *card, unsigned char *data, struct iasecc_extended_tlv *tlv) { struct sc_context *ctx = card->ctx; size_t size_len, tag_len; memset(tlv, 0, sizeof(*tlv)); sc_log(ctx, "iasecc_parse_get_tlv() called for tag 0x%X", *data); if ((*data == 0x7F) || (*data == 0x5F)) { tlv->tag = *data * 0x100 + *(data + 1); tag_len = 2; } else { tlv->tag = *data; tag_len = 1; } sc_log(ctx, "iasecc_parse_get_tlv() tlv->tag 0x%X", tlv->tag); size_len = iasecc_parse_size(data + tag_len, &tlv->size); LOG_TEST_RET(ctx, size_len, "parse error: invalid size data"); tlv->value = calloc(1, tlv->size); if (!tlv->value) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); memcpy(tlv->value, data + size_len + tag_len, tlv->size); tlv->on_card = 1; sc_log(ctx, "iasecc_parse_get_tlv() parsed %i bytes", tag_len + size_len + tlv->size); return tag_len + size_len + tlv->size; }
int iasecc_sdo_allocate_and_parse(struct sc_card *card, unsigned char *data, size_t data_len, struct iasecc_sdo **out) { struct sc_context *ctx = card->ctx; struct iasecc_sdo *sdo = NULL; size_t size, offs, size_size; int rv; LOG_FUNC_CALLED(ctx); if (*data != IASECC_SDO_TAG_HEADER) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); if (data_len < 3) LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA); sdo = calloc(1, sizeof(struct iasecc_sdo)); if (!sdo) return SC_ERROR_OUT_OF_MEMORY; *out = sdo; sdo->sdo_class = *(data + 1) & 0x7F; sdo->sdo_ref = *(data + 2) & 0x3F; sc_log(ctx, "sdo_class 0x%X, sdo_ref 0x%X", sdo->sdo_class, sdo->sdo_ref); if (data_len == 3) LOG_FUNC_RETURN(ctx, SC_SUCCESS); size_size = iasecc_parse_size(data + 3, &size); LOG_TEST_RET(ctx, size_size, "parse error: invalid size data"); if (data_len != size + size_size + 3) LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: invalid SDO data size"); sc_log(ctx, "sz %"SC_FORMAT_LEN_SIZE_T"u, sz_size %"SC_FORMAT_LEN_SIZE_T"u", size, size_size); offs = 3 + size_size; for (; offs < data_len;) { rv = iasecc_sdo_parse_data(card, data + offs, sdo); LOG_TEST_RET(ctx, rv, "parse error: invalid SDO data"); offs += rv; } if (offs != data_len) LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "parse error: not totally parsed"); sc_log(ctx, "docp.acls_contact.size %"SC_FORMAT_LEN_SIZE_T"u; docp.size.size %"SC_FORMAT_LEN_SIZE_T"u", sdo->docp.acls_contact.size, sdo->docp.size.size); LOG_FUNC_RETURN(ctx, SC_SUCCESS); }