aboutsummaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
diff options
context:
space:
mode:
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.c66
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;