int sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df) { sc_context_t *ctx = p15card->card->ctx; u8 *buf; const u8 *p; size_t bufsize; int r; struct sc_pkcs15_object *obj = NULL; int (* func)(struct sc_pkcs15_card *, struct sc_pkcs15_object *, const u8 **nbuf, size_t *nbufsize) = NULL; switch (df->type) { case SC_PKCS15_PRKDF: func = sc_pkcs15_decode_prkdf_entry; break; case SC_PKCS15_PUKDF: func = sc_pkcs15_decode_pukdf_entry; break; case SC_PKCS15_CDF: case SC_PKCS15_CDF_TRUSTED: case SC_PKCS15_CDF_USEFUL: func = sc_pkcs15_decode_cdf_entry; break; case SC_PKCS15_DODF: func = sc_pkcs15_decode_dodf_entry; break; case SC_PKCS15_AODF: func = sc_pkcs15_decode_aodf_entry; break; } if (func == NULL) { sc_error(ctx, "unknown DF type: %d\n", df->type); return SC_ERROR_INVALID_ARGUMENTS; } if (df->file != NULL) r = sc_pkcs15_read_file(p15card, &df->path, &buf, &bufsize, NULL); else r = sc_pkcs15_read_file(p15card, &df->path, &buf, &bufsize, &df->file); if (r < 0) return r; p = buf; while (bufsize && *p != 0x00) { const u8 *oldp; size_t obj_len; obj = (struct sc_pkcs15_object *) calloc(1, sizeof(struct sc_pkcs15_object)); if (obj == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto ret; } oldp = p; r = func(p15card, obj, &p, &bufsize); if (r) { free(obj); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) { r = 0; break; } sc_perror(ctx, r, "Error decoding DF entry"); goto ret; } obj_len = p - oldp; obj->der.value = (u8 *) malloc(obj_len); if (obj->der.value == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto ret; } memcpy(obj->der.value, oldp, obj_len); obj->der.len = obj_len; obj->df = df; r = sc_pkcs15_add_object(p15card, obj); if (r) { if (obj->data) free(obj->data); free(obj); sc_perror(ctx, r, "Error adding object"); goto ret; } }; ret: free(buf); return r; }
int sc_pkcs15_parse_card_df(struct sc_pkcs15_card *p15card, const unsigned int df_type, const u8 *buf, const size_t in_bufsize) { sc_context_t *ctx = p15card->card->ctx; int r = SC_SUCCESS; size_t bufsize = in_bufsize; struct sc_pkcs15_object *obj = NULL; int (* func)(struct sc_pkcs15_card *, struct sc_pkcs15_object *, const u8 **nbuf, size_t *nbufsize) = NULL; int (* func2)(struct sc_pkcs15_card *p15card, const u8 * buf, size_t buflen) = NULL; if ( ctx->debug ) sc_debug( ctx, "Entering function sc_pkcs15_parse_card_df\n" ); switch (df_type) { case SC_PKCS15_PRKDF: func = sc_pkcs15_decode_prkdf_entry; break; case SC_PKCS15_PUKDF: func = sc_pkcs15_decode_pukdf_entry; break; case SC_PKCS15_CDF: case SC_PKCS15_CDF_TRUSTED: case SC_PKCS15_CDF_USEFUL: func = sc_pkcs15_decode_cdf_entry; break; case SC_PKCS15_DODF: func = sc_pkcs15_decode_dodf_entry; break; case SC_PKCS15_AODF: func = sc_pkcs15_decode_aodf_entry; break; } if (func == NULL) { switch (df_type) { case SC_PKCS15_ODF: func2 = parse_card_odf; break; case SC_PKCS15_TOKENINFO: func2 = parse_card_tokeninfo; break; case SC_PKCS15_UNUSED: func2 = parse_card_unusedspace; break; } if (func2 == NULL) { sc_error(ctx, "unknown DF type: %d\n", df_type); r = SC_ERROR_INVALID_ARGUMENTS; goto ret; } r = func2(p15card, buf, bufsize); if (r!=SC_SUCCESS) { sc_perror(ctx, r, "Error decoding DF entry"); } goto ret; } do { const u8 *oldp; size_t obj_len; obj = (struct sc_pkcs15_object *) calloc(1, sizeof(struct sc_pkcs15_object)); if (obj == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto ret; } oldp = buf; r = func(p15card, obj, &buf, &bufsize); if (r) { free(obj); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) { r = 0; break; } sc_perror(ctx, r, "Error decoding DF entry"); goto ret; } obj_len = buf - oldp; obj->der.value = (u8 *) malloc(obj_len); if (obj->der.value == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto ret; } memcpy(obj->der.value, oldp, obj_len); obj->der.len = obj_len; /* These objects are independent one another*/ obj->df = NULL; r = sc_pkcs15_add_object(p15card, obj); if (r) { if (obj->data) free(obj->data); free(obj); sc_perror(ctx, r, "Error adding object"); goto ret; } } while (bufsize && *buf != 0x00); ret: if (ctx->debug) sc_debug(ctx, "Leaving function sc_pkcs15_parse_card_df\n"); return r; }