static int parse_odf(const u8 * buf, size_t buflen, struct sc_pkcs15_card *card) { const u8 *p = buf; size_t left = buflen; int r, i, type; sc_path_t path; struct sc_asn1_entry asn1_obj_or_path[] = { { "path", SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_SEQUENCE, 0, &path, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; struct sc_asn1_entry asn1_odf[10]; sc_copy_asn1_entry(c_asn1_odf, asn1_odf); for (i = 0; asn1_odf[i].name != NULL; i++) sc_format_asn1_entry(asn1_odf + i, asn1_obj_or_path, NULL, 0); while (left > 0) { r = sc_asn1_decode_choice(card->card->ctx, asn1_odf, p, left, &p, &left); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) break; if (r < 0) return r; type = r; r = sc_pkcs15_make_absolute_path(&card->file_app->path, &path); if (r < 0) return r; r = sc_pkcs15_add_df(card, odf_indexes[type], &path, NULL); if (r) return r; } return 0; }
static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card, unsigned int type) { sc_pkcs15_df_t *df; sc_file_t *file; int created = 0; while (1) { for (df = p15card->df_list; df; df = df->next) { if (df->type == type) { if (created) df->enumerated = 1; return df; } } assert(created == 0); file = sc_file_new(); if (!file) return NULL; sc_format_path("11001101", &file->path); sc_pkcs15_add_df(p15card, type, &file->path); sc_file_free(file); created++; } }
static int sc_oberthur_parse_privateinfo (struct sc_pkcs15_card *p15card, unsigned char *buff, size_t len, int postpone_allowed) { struct sc_context *ctx = p15card->card->ctx; size_t ii; int rv; int no_more_private_keys = 0, no_more_private_data = 0; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); for (ii=0; ii<len; ii+=5) { unsigned int file_id, size; if(*(buff+ii) != 0xFF) continue; file_id = 0x100 * *(buff+ii + 1) + *(buff+ii + 2); size = 0x100 * *(buff+ii + 3) + *(buff+ii + 4); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "add private object (file-id:%04X, size:%X)", file_id, size); switch (*(buff+ii + 1)) { case BASE_ID_PRV_RSA : if (no_more_private_keys) break; rv = sc_pkcs15emu_oberthur_add_prvkey(p15card, file_id, size); if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED && postpone_allowed) { struct sc_path path; sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "postpone adding of the private keys"); sc_format_path("5011A5A5", &path); rv = sc_pkcs15_add_df(p15card, SC_PKCS15_PRKDF, &path); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Add PrkDF error"); no_more_private_keys = 1; } SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot parse private key info"); break; case BASE_ID_PRV_DES : break; case BASE_ID_PRV_DATA : sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "*(buff+ii + 1):%X", *(buff+ii + 1)); if (no_more_private_data) break; rv = sc_pkcs15emu_oberthur_add_data(p15card, file_id, size, 1); if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED && postpone_allowed) { struct sc_path path; sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "postpone adding of the private data"); sc_format_path("5011A6A6", &path); rv = sc_pkcs15_add_df(p15card, SC_PKCS15_DODF, &path); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Add DODF error"); no_more_private_data = 1; } SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot parse private data info"); break; default: SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Private object parse error"); } } SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); }