static int select_key_file(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_prkey_info *prkey, sc_security_env_t *senv) { sc_path_t path, file_id; int r; if (prkey->path.len < 2) return SC_ERROR_INVALID_ARGUMENTS; /* For pkcs15-emulated cards, the file_app may be NULL, in that case we allways assume an absolute path */ if (prkey->path.len == 2 && p15card->file_app != NULL) { /* Path is relative to app. DF */ path = p15card->file_app->path; file_id = prkey->path; sc_append_path(&path, &file_id); } else { path = prkey->path; memcpy(file_id.value, prkey->path.value + prkey->path.len - 2, 2); file_id.len = 2; file_id.type = SC_PATH_TYPE_FILE_ID; } senv->file_ref = file_id; senv->flags |= SC_SEC_ENV_FILE_REF_PRESENT; r = sc_select_file(p15card->card, &path, NULL); SC_TEST_RET(p15card->card->ctx, r, "sc_select_file() failed"); return 0; }
static int select_key_file(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_prkey_info *prkey, sc_security_env_t *senv) { sc_context_t *ctx = p15card->card->ctx; sc_path_t path, file_id; int r; LOG_FUNC_CALLED(ctx); memset(&path, 0, sizeof(sc_path_t)); memset(&file_id, 0, sizeof(sc_path_t)); /* TODO: Why file_app may be NULL -- at least 3F00 has to be present? * Check validity of the following assumption. */ /* For pkcs15-emulated cards, the file_app may be NULL, in that case we allways assume an absolute path */ if (!prkey->path.len && prkey->path.aid.len) { /* Private key is a SDO allocated in application DF */ path = prkey->path; } else if (prkey->path.len == 2 && p15card->file_app != NULL) { /* Path is relative to app. DF */ path = p15card->file_app->path; file_id = prkey->path; sc_append_path(&path, &file_id); senv->file_ref = file_id; senv->flags |= SC_SEC_ENV_FILE_REF_PRESENT; } else if (prkey->path.len > 2) { path = prkey->path; memcpy(file_id.value, prkey->path.value + prkey->path.len - 2, 2); file_id.len = 2; file_id.type = SC_PATH_TYPE_FILE_ID; senv->file_ref = file_id; senv->flags |= SC_SEC_ENV_FILE_REF_PRESENT; } else { LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "invalid private key path"); } r = sc_select_file(p15card->card, &path, NULL); LOG_TEST_RET(ctx, r, "sc_select_file() failed"); LOG_FUNC_RETURN(ctx, SC_SUCCESS); }
int card_sync_card_to_virtual_fs_filter_cert( sc_card_t *card, struct _virtual_file_t *virtual_file, virtual_fs_t *virtual_fs, sc_pkcs15_object_t *obj ) { int r = SC_SUCCESS; struct sc_pkcs15_cert_info *cert = NULL; unsigned char *card_data = NULL; virtual_file_t *certificate_virtual_file = NULL; virtual_file_t *certificate_virtual_file_weak_link = NULL; sc_path_t abs_cert_path, cert_card_path; SC_FUNC_CALLED(card->ctx, 1); /* we need to correct certificate length in path */ cert = (struct sc_pkcs15_cert_info *) obj->data; if(cert) { /* set asn1 to map */ r = map_id_to_der_set_item(DRVDATA(card)->cdf_card_ckaid_to_card_der_map, &cert->id, &obj->content); if(r != SC_SUCCESS) goto end; if(cert->path.len > 0) { certificate_virtual_file = virtual_file_new(); if(!certificate_virtual_file) { r = SC_ERROR_OUT_OF_MEMORY; goto end; } memset(&abs_cert_path, 0, sizeof(struct sc_path)); memset(&cert_card_path, 0, sizeof(struct sc_path)); if(cert->path.len==2) { sc_format_path("3F005015", &abs_cert_path); r = sc_append_path(&abs_cert_path, &cert->path); if(r!=SC_SUCCESS) goto end; sc_format_path("3F006061", &cert_card_path); r = sc_append_path(&cert_card_path, &cert->path); if(r!=SC_SUCCESS) goto end; } else if(cert->path.len==4) { sc_format_path("3F00", &abs_cert_path); r = sc_append_path(&abs_cert_path, &cert->path); if(r!=SC_SUCCESS) goto end; sc_format_path("3F00", &cert_card_path); r = sc_append_path(&cert_card_path, &cert->path); if(r!=SC_SUCCESS) goto end; memcpy(cert->path.value, cert_card_path.value, cert_card_path.len); cert->path.len = 6; } else { r = sc_append_path(&abs_cert_path, &cert->path); if(r!=SC_SUCCESS) goto end; if(abs_cert_path.len==6) { r = sc_append_path(&cert_card_path, &cert->path); if(r!=SC_SUCCESS) goto end; } } memcpy(&certificate_virtual_file->path, &abs_cert_path, sizeof(certificate_virtual_file->path)); r = map_path_to_path_set_item(DRVDATA(card)->virtual_fs_to_card_path_map, &certificate_virtual_file->path, &cert_card_path); if(r != SC_SUCCESS) goto end; certificate_virtual_file->is_ef = 1; certificate_virtual_file->card_to_virtual_fs.sync_state = virtual_file_sync_state_sync_pending; certificate_virtual_file->card_to_virtual_fs.sync_callback = card_sync_card_to_virtual_fs_certificate_file_callback; certificate_virtual_file->virtual_fs_to_card.sync_state = virtual_file_sync_state_unknown; certificate_virtual_file->virtual_fs_to_card.sync_callback = NULL; /* append file to virtual_fs */ r = virtual_fs_append(virtual_fs, certificate_virtual_file); if(r != SC_SUCCESS) goto end; /* we don't have ownership of virtual_file now, so we don't need to free it */ certificate_virtual_file_weak_link = certificate_virtual_file; certificate_virtual_file = NULL; /* we now synchronize file because this gets a correct size for it */ r = virtual_file_data_synchronize(certificate_virtual_file_weak_link, card, virtual_file_sync_type_card_to_virtual_fs, DRVDATA(card)->virtual_fs); if (r != SC_SUCCESS) { sc_debug(card->ctx,SC_LOG_DEBUG_NORMAL, "Synchronization failed\n"); goto end; } /* correct length in PKCS#15 */ cert->path.count = certificate_virtual_file_weak_link->data_size; } else { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"Path length is 0"); } } else { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"Pointer to cert info was empty"); } end: if(card_data) { free(card_data); card_data = NULL; } if(certificate_virtual_file) { virtual_file_free(certificate_virtual_file); certificate_virtual_file = NULL; } SC_FUNC_RETURN(card->ctx, 1, r); }
int card_sync_card_to_virtual_fs_filter_data_object( sc_card_t *card, struct _virtual_file_t *virtual_file, virtual_fs_t *virtual_fs, sc_pkcs15_object_t *obj ) { int r = SC_SUCCESS; struct sc_pkcs15_data_info *data = NULL; unsigned char *card_data = NULL; virtual_file_t *data_virtual_file = NULL; virtual_file_t *data_virtual_file_weak_link = NULL; sc_path_t abs_data_path, data_card_path, def_path; SC_FUNC_CALLED(card->ctx, 1); /* we need to correct certificate length in path */ data = (struct sc_pkcs15_data_info *) obj->data; if(data) { if(data->path.len > 0) { data_virtual_file = virtual_file_new(); if(!data_virtual_file) { r = SC_ERROR_OUT_OF_MEMORY; goto end; } memset(&abs_data_path, 0, sizeof(struct sc_path)); memset(&data_card_path, 0, sizeof(struct sc_path)); memset(&def_path, 0, sizeof(struct sc_path)); if(data->path.len == 4) { sc_format_path("3F00", &def_path); r = sc_append_path(&def_path, &data->path); if(r!=SC_SUCCESS) goto end; memcpy(data->path.value, def_path.value, def_path.len); data->path.len = 6; } else { memcpy(&def_path, &data->path, sizeof(data->path)); } r = sc_append_path(&abs_data_path, &def_path); if(r!=SC_SUCCESS) goto end; if(abs_data_path.len==6) { r = sc_append_path(&data_card_path, &def_path); if(r!=SC_SUCCESS) goto end; } memcpy(&data_virtual_file->path, &abs_data_path, sizeof(data_virtual_file->path)); r = map_path_to_path_set_item(DRVDATA(card)->virtual_fs_to_card_path_map, &data_virtual_file->path, &data_card_path); if(r != SC_SUCCESS) goto end; data_virtual_file->is_ef = 1; data_virtual_file->card_to_virtual_fs.sync_state = virtual_file_sync_state_sync_pending; data_virtual_file->card_to_virtual_fs.sync_callback = card_sync_card_to_virtual_fs_data_file_callback; data_virtual_file->virtual_fs_to_card.sync_state = virtual_file_sync_state_unknown; data_virtual_file->virtual_fs_to_card.sync_callback = NULL; /* append file to virtual_fs */ r = virtual_fs_append(virtual_fs, data_virtual_file); if(r != SC_SUCCESS) goto end; /* we don't have ownership of virtual_file now, so we don't need to free it */ data_virtual_file_weak_link = data_virtual_file; data_virtual_file = NULL; /* we now synchronize file because this gets a correct size for it */ r = virtual_file_data_synchronize(data_virtual_file_weak_link, card, virtual_file_sync_type_card_to_virtual_fs, DRVDATA(card)->virtual_fs); if (r != SC_SUCCESS) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Synchronization failed\n"); goto end; } /* correct length in PKCS#15 */ data->path.count = data_virtual_file_weak_link->data_size; obj->auth_id.value[0]=0x01; obj->auth_id.len=0x01; } else { sc_debug(card->ctx,SC_LOG_DEBUG_VERBOSE, "Path length is 0"); } } else { sc_debug(card->ctx,SC_LOG_DEBUG_VERBOSE, "Pointer to data info was empty"); } end: if(card_data) { free(card_data); card_data = NULL; } if(data_virtual_file) { virtual_file_free(data_virtual_file); data_virtual_file = NULL; } SC_FUNC_RETURN(card->ctx, 1, r); }
int card_sync_card_to_virtual_fs_filter_pukey( sc_card_t *card, struct _virtual_file_t *virtual_file, virtual_fs_t *virtual_fs, sc_pkcs15_object_t *obj ) { int r = SC_SUCCESS; struct sc_pkcs15_pubkey_info *pukey = NULL; sc_path_t def_path; /* This flag identifies the FIRMA public key */ u8 flag_id[1] = "F"; SC_FUNC_CALLED(card->ctx, 1); memset(&def_path, 0, sizeof(struct sc_path)); if(!card || !virtual_file) return SC_ERROR_INVALID_ARGUMENTS; pukey = (struct sc_pkcs15_pubkey_info *) obj->data; if(pukey) { /* set asn1 to map */ r = map_id_to_der_set_item(DRVDATA(card)->pukdf_card_ckaid_to_card_der_map, &pukey->id, &obj->content); if(r != SC_SUCCESS) goto end; if(pukey->path.len > 0) { if(pukey->path.len == 4) { sc_format_path("3F00", &def_path); r = sc_append_path(&def_path, &pukey->path); if(r!=SC_SUCCESS) goto end; memcpy(pukey->path.value, def_path.value, def_path.len); pukey->path.len = 6; } else { memcpy(&def_path, &pukey->path, sizeof(pukey->path)); } /* append empty file */ r = virtual_fs_append_new_virtual_file(virtual_fs, &def_path, obj->content.value, obj->content.len, obj->content.len, 1, virtual_file_sync_state_unknown, NULL, virtual_file_sync_state_unknown, NULL); if(r != SC_SUCCESS) goto end; /* correct length in PKCS#15 */ pukey->path.count = 0; /* Fixed key usage for FIRMA public key */ if(memcmp(pukey->id.value, flag_id, 1)==0) pukey->usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; } else { sc_debug(card->ctx,SC_LOG_DEBUG_VERBOSE, "Path length is 0"); } } else { sc_debug(card->ctx,SC_LOG_DEBUG_VERBOSE, "Pointer to pukey info was empty"); } end: SC_FUNC_RETURN(card->ctx, 1, r); }