StringPtr WebInterface::generate_status_page() { StringPtr page(new std::string()); ctemplate::TemplateDictionary dict("status"); LOG_DBG("Generating status page!"); std::stringstream content; content << "<div id=\"status\">" << std::endl; content << "<h1>Status</h1>" << std::endl; content << "<table id=\"status-table\">" << std::endl; content << "<tr>" << std::endl; content << "<th>Parameter</th>" << std::endl; content << "<th>Value</th>" << std::endl; content << "</tr>" << std::endl; content << "<tr>" << std::endl; content << "<td>Title</td>" << std::endl; content << "<td>" << page_title_ << "</td>" << std::endl; content << "</tr>" << std::endl; content << "<tr>" << std::endl; content << "<td>Home folder</td>" << std::endl; content << "<td>" << home_folder_ << "</td>" << std::endl; content << "</tr>" << std::endl; content << "<tr>" << std::endl; content << "<td>Template</td>" << std::endl; content << "<td>" << template_name_ << "</td>" << std::endl; content << "</tr>" << std::endl; content << "<tr>" << std::endl; content << "<td>Application running</td>" << std::endl; content << "<td>" << ((application_interface_->is_running())?"Yes":"No"); content << "</td>" << std::endl; content << "</tr>" << std::endl; content << "</table>" << std::endl; content << "</div>\n" << std::endl; dict[KW_TITLE] = page_title_ + " - Status page"; dict[KW_HEAD] = (format_head("", "", "")->str()); dict[KW_CONTENT] = content.str(); dict[KW_MENU] = (format_menu(URI_PAGE_STATUS)->str()); ctemplate::ExpandTemplate(get_home_folder_path(template_name_), ctemplate::DO_NOT_STRIP, &dict, page.get()); LOG_DBG("Status page size: %lu", page->size()); return page; }
StringPtr WebInterface::generate_log_page() { StringPtr page(new std::string()); ctemplate::TemplateDictionary dict("log"); LOG_DBG("Generating log page!"); dict[KW_TITLE] = page_title_ + " - Logging output"; dict[KW_HEAD] = (format_head("", "", "")->str()); dict[KW_CONTENT] = ("Log page content"); dict[KW_MENU] = (format_menu(URI_PAGE_LOG)->str()); ctemplate::ExpandTemplate(get_home_folder_path(template_name_), ctemplate::DO_NOT_STRIP, &dict, page.get()); LOG_DBG("Log page size: %lu", page->size()); return page; }
StringPtr WebInterface::generate_error_page() { StringPtr page(new std::string()); ctemplate::TemplateDictionary dict("error"); LOG_DBG("Generating error page!"); dict[KW_TITLE] = page_title_ + " - Error"; dict[KW_HEAD] = (format_head("", "", "")->str()); dict[KW_CONTENT] = "Error page content!"; dict[KW_MENU] = (format_menu(URI_PAGE_MAIN)->str()); dict.ShowSection(KW_SECTION_INPUT); ctemplate::ExpandTemplate(get_home_folder_path(template_name_), ctemplate::DO_NOT_STRIP, &dict, page.get()); LOG_DBG("Error page size: %lu", page->size()); return page; }
StringPtr WebInterface::generate_main_page() { StringPtr page(new std::string); ctemplate::TemplateDictionary dict("main"); LOG_DBG("Generating main page!"); ConsoleLinePtrDequePtr lines = application_interface_->get_output_message(); dict[KW_TITLE] = page_title_ + " - Console interface"; dict[KW_HEAD] = (format_head(lines->front()->get_time(), lines->back()->get_time(), URI_PAGE_CL)->str()); dict[KW_CONTENT] = (format_line(lines)->str()); dict[KW_MENU] = (format_menu(URI_PAGE_MAIN)->str()); dict.ShowSection(KW_SECTION_INPUT); LOG_DBG("Expanding template: %s", get_home_folder_path(template_name_).c_str()); ctemplate::ExpandTemplate(get_home_folder_path(template_name_), ctemplate::DO_NOT_STRIP, &dict, page.get()); LOG_DBG("Main page size: %lu", page->size()); return page; }
static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card, const sc_apdu_t *apdu, sc_apdu_t **psm_apdu) { struct sc_asn1_entry sm_capdu[4]; u8 *p, *le = NULL, *sm_data = NULL, *fdata = NULL, *mac_data = NULL, *asn1 = NULL, *mac = NULL, *resp_data = NULL; size_t sm_data_len, fdata_len, mac_data_len, asn1_len, mac_len, le_len; int r, cse; sc_apdu_t *sm_apdu = NULL; if (!apdu || !ctx || !card || !card->reader || !psm_apdu) { r = SC_ERROR_INVALID_ARGUMENTS; goto err; } if ((apdu->cla & 0x0C) == 0x0C) { r = SC_ERROR_INVALID_ARGUMENTS; sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Given APDU is already protected with some secure messaging"); goto err; } sc_copy_asn1_entry(c_sm_capdu, sm_capdu); sm_apdu = malloc(sizeof(sc_apdu_t)); if (!sm_apdu) { r = SC_ERROR_OUT_OF_MEMORY; goto err; } sm_apdu->control = apdu->control; sm_apdu->flags = apdu->flags; sm_apdu->cla = apdu->cla|0x0C; sm_apdu->ins = apdu->ins; sm_apdu->p1 = apdu->p1; sm_apdu->p2 = apdu->p2; r = format_head(ctx, sm_apdu, &mac_data); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format header of SM apdu"); goto err; } mac_data_len = r; /* get le and data depending on the case of the insecure command */ cse = apdu->cse; if ((apdu->le/ctx->block_length + 1)*ctx->block_length + 18 > 0xff+1) /* for encrypted APDUs we usually get authenticated status bytes (4B), * a MAC (11B) and a cryptogram with padding indicator (3B without * data). The cryptogram is always padded to the block size. */ cse |= SC_APDU_EXT; switch (cse) { case SC_APDU_CASE_1: break; case SC_APDU_CASE_2_SHORT: le_len = 1; r = format_le(apdu->le, sm_capdu + 1, &le, &le_len); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu"); goto err; } bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Protected Le (plain)", le, le_len); break; case SC_APDU_CASE_2_EXT: if (card->reader->active_protocol == SC_PROTO_T0) { /* T0 extended APDUs look just like short APDUs */ le_len = 1; r = format_le(apdu->le, sm_capdu + 1, &le, &le_len); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu"); goto err; } } else { /* in case of T1 always use 2 bytes for length */ le_len = 2; r = format_le(apdu->le, sm_capdu + 1, &le, &le_len); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu"); goto err; } } bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Protected Le (plain)", le, le_len); break; case SC_APDU_CASE_3_SHORT: case SC_APDU_CASE_3_EXT: r = format_data(card, ctx, apdu->data, apdu->datalen, sm_capdu + 0, &fdata, &fdata_len); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format data of SM apdu"); goto err; } bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Padding-content indicator followed by cryptogram (plain)", fdata, fdata_len); break; case SC_APDU_CASE_4_SHORT: /* in case of T0 no Le byte is added */ if (card->reader->active_protocol != SC_PROTO_T0) { le_len = 1; r = format_le(apdu->le, sm_capdu + 1, &le, &le_len); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu"); goto err; } bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Protected Le (plain)", le, le_len); } r = format_data(card, ctx, apdu->data, apdu->datalen, sm_capdu + 0, &fdata, &fdata_len); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format data of SM apdu"); goto err; } bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Padding-content indicator followed by cryptogram (plain)", fdata, fdata_len); break; case SC_APDU_CASE_4_EXT: if (card->reader->active_protocol == SC_PROTO_T0) { /* again a T0 extended case 4 APDU looks just * like a short APDU, the additional data is * transferred using ENVELOPE and GET RESPONSE */ } else { /* only 2 bytes are use to specify the length of the * expected data */ le_len = 2; r = format_le(apdu->le, sm_capdu + 1, &le, &le_len); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu"); goto err; } bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Protected Le (plain)", le, le_len); } r = format_data(card, ctx, apdu->data, apdu->datalen, sm_capdu + 0, &fdata, &fdata_len); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format data of SM apdu"); goto err; } bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Padding-content indicator followed by cryptogram (plain)", fdata, fdata_len); break; default: sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Unhandled apdu case"); r = SC_ERROR_INVALID_DATA; goto err; } r = sc_asn1_encode(card->ctx, sm_capdu, (u8 **) &asn1, &asn1_len); if (r < 0) { goto err; } if (asn1_len) { p = realloc(mac_data, mac_data_len + asn1_len); if (!p) { r = SC_ERROR_OUT_OF_MEMORY; goto err; } mac_data = p; /* Flawfinder: ignore */ memcpy(mac_data + mac_data_len, asn1, asn1_len); mac_data_len += asn1_len; r = add_padding(ctx, mac_data, mac_data_len, &mac_data); if (r < 0) { goto err; } mac_data_len = r; } bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Data to authenticate", mac_data, mac_data_len); r = ctx->authenticate(card, ctx, mac_data, mac_data_len, &mac); if (r < 0) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not get authentication code"); goto err; } mac_len = r; bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "Cryptographic Checksum (plain)", mac, mac_len); /* format SM apdu */ sc_format_asn1_entry(sm_capdu + 2, mac, &mac_len, SC_ASN1_PRESENT); r = sc_asn1_encode(card->ctx, sm_capdu, (u8 **) &sm_data, &sm_data_len); if (r < 0) goto err; sm_apdu->data = sm_data; sm_apdu->datalen = sm_data_len; sm_apdu->lc = sm_data_len; sm_apdu->le = 0; if (cse & SC_APDU_EXT) { sm_apdu->cse = SC_APDU_CASE_4_EXT; #if OPENSC_NOT_BOGUS_ANYMORE sm_apdu->resplen = 0xffff+1; #else sm_apdu->resplen = SC_MAX_EXT_APDU_BUFFER_SIZE; #endif } else { sm_apdu->cse = SC_APDU_CASE_4_SHORT; #if OPENSC_NOT_BOGUS_ANYMORE sm_apdu->resplen = 0xff+1; #else sm_apdu->resplen = SC_MAX_APDU_BUFFER_SIZE; #endif } resp_data = malloc(sm_apdu->resplen); if (!resp_data) { r = SC_ERROR_OUT_OF_MEMORY; goto err; } sm_apdu->resp = resp_data; bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "ASN.1 encoded encrypted APDU data", sm_apdu->data, sm_apdu->datalen); *psm_apdu = sm_apdu; err: free(fdata); free(asn1); free(mac_data); free(mac); free(le); if (r < 0) { free(resp_data); free(sm_apdu); free(sm_data); } return r; }