diff options
Diffstat (limited to 'src/backend/taler-merchant-httpd_post-orders-ID-pay.c')
-rw-r--r-- | src/backend/taler-merchant-httpd_post-orders-ID-pay.c | 66 |
1 files changed, 29 insertions, 37 deletions
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c index 888ea0ba..08e4b6d8 100644 --- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c +++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c @@ -256,6 +256,7 @@ struct TokenUseConfirmation /** * Hash of the token issue public key associated with this token. + * Note this is set in the validate_tokens phase. */ struct TALER_TokenIssuePublicKeyHashP h_issue; @@ -278,11 +279,6 @@ struct TokenEnvelope */ struct TALER_TokenEnvelopeP blinded_token; - /** - * Hash of token issue public key. - */ - struct TALER_TokenIssuePublicKeyHashP h_issue; - }; @@ -1515,8 +1511,7 @@ build_token_sigs (struct PayContext *pc) for (unsigned int i = 0; i < pc->output_tokens_len; i++) { json_array_append_new (token_sigs, GNUNET_JSON_PACK ( - GNUNET_JSON_pack_blinded_sig ("blind_sig", pc->output_tokens[i].sig.signature), - GNUNET_JSON_pack_data_auto ("h_issue", &pc->output_tokens[i].h_issue) + GNUNET_JSON_pack_blinded_sig ("blind_sig", pc->output_tokens[i].sig.signature) )); } @@ -2308,20 +2303,16 @@ phase_execute_pay_transaction (struct PayContext *pc) static enum GNUNET_GenericReturnValue find_valid_input_tokens (struct PayContext *pc, struct TALER_MerchantContractTokenFamilyKey *key, + unsigned int index, unsigned int expected_num) { int num_validated = 0; struct TokenUseConfirmation *tuc = NULL; - for (size_t i = 0; i < pc->tokens_cnt; i++) + for (unsigned int j = 0; j < expected_num; j++) { - if (0 != GNUNET_CRYPTO_hash_cmp (&pc->tokens[i].h_issue.hash, - &key->pub.public_key->pub_key_hash)) - { - continue; - } + tuc = &pc->tokens[index + j]; - tuc = &pc->tokens[i]; if (NULL == tuc) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -2338,6 +2329,8 @@ find_valid_input_tokens (struct PayContext *pc, return GNUNET_NO; } + tuc->h_issue.hash = key->pub.public_key->pub_key_hash; + if (GNUNET_OK != TALER_token_issue_verify (&tuc->pub, &key->pub, &tuc->unblinded_sig)) @@ -2399,26 +2392,37 @@ find_valid_input_tokens (struct PayContext *pc, static enum GNUNET_GenericReturnValue sign_token_envelopes (struct PayContext *pc, - const char *token_family_slug, struct TALER_MerchantContractTokenFamilyKey *key, struct TALER_TokenIssuePrivateKeyP *priv, + unsigned int index, unsigned int expected_num) { int num_signed = 0; - for (unsigned int i = 0; i<pc->token_envelopes_cnt; i++) + for (unsigned int j = 0; j<expected_num; j++) { - if (0 != GNUNET_CRYPTO_hash_cmp (&pc->token_envelopes[i].h_issue.hash, - &key->pub.public_key->pub_key_hash)) - { - continue; + unsigned int pos = index + j; + + /* TODO: Handle missing envelopes for non-critical output tokens. */ + if (pos > pc->token_envelopes_cnt || pos > pc->output_tokens_len) { + GNUNET_break (0); + pay_end (pc, + TALER_MHD_reply_with_error (pc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "Token envelope array is missing " + "required token envelope")); + return GNUNET_NO; } + struct TokenEnvelope *env = &pc->token_envelopes[index + j]; + struct SignedOutputToken *output = &pc->output_tokens[index + j]; + TALER_token_issue_sign (priv, - &pc->token_envelopes[i].blinded_token, - &pc->output_tokens[i].sig); + &env->blinded_token, + &output->sig); - pc->output_tokens[i].h_issue.hash = pc->token_envelopes[i].h_issue.hash; + output->h_issue.hash = key->pub.public_key->pub_key_hash; num_signed++; } @@ -2498,12 +2502,6 @@ phase_validate_tokens (struct PayContext *pc) selected = pc->choices[pc->choice_index]; - /* 1. Iterate over inputs of selected choice: - 1.1. Get key for each input. - 1.2. Check if token signed by this key are valid at the current time. - 1.3. Iterate over provided tokens and check if required number with matching h_issue are present. - 1.4. Validate ub_sig with the issue public key, validate token_sig using the token_pub key of the request. - 1.5. Sum up validated tokens and check if validated_len == tokens_cnt after loop. */ for (unsigned int i = 0; i<selected.inputs_len; i++) { struct TALER_MerchantContractInput input = selected.inputs[i]; @@ -2557,6 +2555,7 @@ phase_validate_tokens (struct PayContext *pc) if (GNUNET_NO == find_valid_input_tokens (pc, &key, + i, input.details.token.count)) { /* Error is already scheduled from find_valid_input_token. */ @@ -2621,9 +2620,9 @@ phase_validate_tokens (struct PayContext *pc) GNUNET_assert (NULL != details.priv.private_key); if (GNUNET_OK != sign_token_envelopes (pc, - family.slug, &key, &details.priv, + i, output.details.token.count)) { /* Error is already scheduled from sign_token_envelopes. */ @@ -2704,9 +2703,6 @@ input_tokens_paid_check ( struct TokenUseConfirmation *tuc = &pc->tokens[i]; if ( (0 == - GNUNET_CRYPTO_hash_cmp (&tuc->h_issue.hash, - &h_issue_pub->hash)) && - (0 == GNUNET_memcmp (&tuc->pub, use_pub)) && (0 == GNUNET_memcmp (&tuc->sig, use_sig)) && @@ -3375,8 +3371,6 @@ phase_parse_pay (struct PayContext *pc) &tuc->pub), TALER_JSON_spec_token_issue_sig ("ub_sig", &tuc->unblinded_sig), - GNUNET_JSON_spec_fixed_auto ("h_issue", - &tuc->h_issue), GNUNET_JSON_spec_end () }; enum GNUNET_GenericReturnValue res; @@ -3445,8 +3439,6 @@ phase_parse_pay (struct PayContext *pc) struct GNUNET_JSON_Specification ispec[] = { TALER_JSON_spec_token_envelope ("token_ev", &ev->blinded_token), - GNUNET_JSON_spec_fixed_auto ("h_issue", - &ev->h_issue.hash), GNUNET_JSON_spec_end () }; enum GNUNET_GenericReturnValue res; |