diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/include/taler_exchange_service.h | 72 | ||||
| -rw-r--r-- | src/lib/exchange_api_transfers_get.c | 164 | ||||
| -rw-r--r-- | src/testing/testing_api_cmd_transfer_get.c | 33 | 
3 files changed, 140 insertions, 129 deletions
| diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index a57a2655..307a76de 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1581,31 +1581,67 @@ struct TALER_EXCHANGE_TransfersGetHandle;  /** + * Information the exchange returns per wire transfer. + */ +struct TALER_EXCHANGE_TransferData +{ + +  /** +   * exchange key used to sign +   */ +  struct TALER_ExchangePublicKeyP exchange_pub; + +  /** +   * exchange signature over the transfer data +   */ +  struct TALER_ExchangeSignatureP exchange_sig; + +  /** +   * hash of the wire transfer address the transfer went to +   */ +  struct GNUNET_HashCode h_wire; + +  /** +   * time when the exchange claims to have performed the wire transfer +   */ +  struct GNUNET_TIME_Absolute execution_time; + +  /** +   * amount of the wire transfer +   */ +  struct TALER_Amount total_amount; + +  /** +   * wire fee that was charged by the exchange +   */ +  struct TALER_Amount wire_fee; + +  /** +   * length of the @e details array +   */ +  unsigned int details_length; + +  /** +   * array with details about the combined transactions +   */ +  const struct TALER_TrackTransferDetails *details; + +}; + + +/**   * Function called with detailed wire transfer data, including all   * of the coin transactions that were combined into the wire transfer.   *   * @param cls closure   * @param hr HTTP response data - * @param sign_key exchange key used to sign @a json, or NULL - * @param h_wire hash of the wire transfer address the transfer went to, or NULL on error - * @param execution_time time when the exchange claims to have performed the wire transfer - * @param total_amount total amount of the wire transfer, or NULL if the exchange could - *             not provide any @a wtid (set only if @a http_status is #MHD_HTTP_OK) - * @param wire_fee wire fee that was charged by the exchange - * @param details_length length of the @a details array - * @param details array with details about the combined transactions + * @param ta transfer data, (set only if @a http_status is #MHD_HTTP_OK, otherwise NULL)   */  typedef void  (*TALER_EXCHANGE_TransfersGetCallback)(    void *cls,    const struct TALER_EXCHANGE_HttpResponse *hr, -  const struct TALER_ExchangePublicKeyP *sign_key, -  const struct GNUNET_HashCode *h_wire, -  struct GNUNET_TIME_Absolute execution_time, -  const struct TALER_Amount *total_amount, -  const struct TALER_Amount *wire_fee, -  unsigned int details_length, -  const struct TALER_TrackTransferDetails *details); +  const struct TALER_EXCHANGE_TransferData *ta);  /** @@ -1651,17 +1687,19 @@ struct TALER_EXCHANGE_DepositGetHandle;   *   * @param cls closure   * @param hr HTTP response data - * @param sign_key exchange key used to sign @a json, or NULL + * @param exchange_pub exchange key used to sign @a json, or NULL   * @param wtid wire transfer identifier used by the exchange, NULL if exchange did not   *                  yet execute the transaction   * @param execution_time actual or planned execution time for the wire transfer   * @param coin_contribution contribution to the total amount by this coin (can be NULL) + * // FIXME: also return the exchange signature + * // FIXME: combine all of the above (except cls,hr) into a 'struct'! => DepositData   */  typedef void  (*TALER_EXCHANGE_DepositGetCallback)(    void *cls,    const struct TALER_EXCHANGE_HttpResponse *hr, -  const struct TALER_ExchangePublicKeyP *sign_key, +  const struct TALER_ExchangePublicKeyP *exchange_pub,    const struct TALER_WireTransferIdentifierRawP *wtid,    struct GNUNET_TIME_Absolute execution_time,    const struct TALER_Amount *coin_contribution); diff --git a/src/lib/exchange_api_transfers_get.c b/src/lib/exchange_api_transfers_get.c index 55253695..dd9b6446 100644 --- a/src/lib/exchange_api_transfers_get.c +++ b/src/lib/exchange_api_transfers_get.c @@ -85,24 +85,18 @@ check_transfers_get_response_ok (    const json_t *json)  {    json_t *details_j; -  struct GNUNET_HashCode h_wire; -  struct GNUNET_TIME_Absolute exec_time; -  struct TALER_Amount total_amount; +  struct TALER_EXCHANGE_TransferData td;    struct TALER_Amount total_expected; -  struct TALER_Amount wire_fee;    struct TALER_MerchantPublicKeyP merchant_pub; -  unsigned int num_details; -  struct TALER_ExchangePublicKeyP exchange_pub; -  struct TALER_ExchangeSignatureP exchange_sig;    struct GNUNET_JSON_Specification spec[] = { -    TALER_JSON_spec_amount ("total", &total_amount), -    TALER_JSON_spec_amount ("wire_fee", &wire_fee), +    TALER_JSON_spec_amount ("total", &td.total_amount), +    TALER_JSON_spec_amount ("wire_fee", &td.wire_fee),      GNUNET_JSON_spec_fixed_auto ("merchant_pub", &merchant_pub), -    GNUNET_JSON_spec_fixed_auto ("h_wire", &h_wire), -    GNUNET_JSON_spec_absolute_time ("execution_time", &exec_time), +    GNUNET_JSON_spec_fixed_auto ("h_wire", &td.h_wire), +    GNUNET_JSON_spec_absolute_time ("execution_time", &td.execution_time),      GNUNET_JSON_spec_json ("deposits", &details_j), -    GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), -    GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), +    GNUNET_JSON_spec_fixed_auto ("exchange_sig", &td.exchange_sig), +    GNUNET_JSON_spec_fixed_auto ("exchange_pub", &td.exchange_pub),      GNUNET_JSON_spec_end ()    };    struct TALER_EXCHANGE_HttpResponse hr = { @@ -119,22 +113,32 @@ check_transfers_get_response_ok (      return GNUNET_SYSERR;    }    if (GNUNET_OK != -      TALER_amount_get_zero (total_amount.currency, +      TALER_amount_get_zero (td.total_amount.currency,                               &total_expected))    {      GNUNET_break_op (0); +    GNUNET_JSON_parse_free (spec);      return GNUNET_SYSERR;    } -  num_details = json_array_size (details_j); +  if (GNUNET_OK != +      TALER_EXCHANGE_test_signing_key ( +        TALER_EXCHANGE_get_keys (wdh->exchange), +        &td.exchange_pub)) +  { +    GNUNET_break_op (0); +    GNUNET_JSON_parse_free (spec); +    return GNUNET_SYSERR; +  } +  td.details_length = json_array_size (details_j);    { -    struct TALER_TrackTransferDetails details[num_details]; -    unsigned int i;      struct GNUNET_HashContext *hash_context; -    struct TALER_WireDepositDetailP dd; -    struct TALER_WireDepositDataPS wdp; +    struct TALER_TrackTransferDetails *details; +    details = GNUNET_new_array (td.details_length, +                                struct TALER_TrackTransferDetails); +    td.details = details;      hash_context = GNUNET_CRYPTO_hash_context_start (); -    for (i = 0; i<num_details; i++) +    for (unsigned int i = 0; i<td.details_length; i++)      {        struct TALER_TrackTransferDetails *detail = &details[i];        struct json_t *detail_j = json_array_get (details_j, i); @@ -147,25 +151,11 @@ check_transfers_get_response_ok (          GNUNET_JSON_spec_end ()        }; -      if (GNUNET_OK != -          GNUNET_JSON_parse (detail_j, -                             spec_detail, -                             NULL, NULL)) -      { -        GNUNET_break_op (0); -        GNUNET_CRYPTO_hash_context_abort (hash_context); -        GNUNET_JSON_parse_free (spec); -        return GNUNET_SYSERR; -      } -      /* build up big hash for signature checking later */ -      dd.h_contract_terms = detail->h_contract_terms; -      dd.execution_time = GNUNET_TIME_absolute_hton (exec_time); -      dd.coin_pub = detail->coin_pub; -      TALER_amount_hton (&dd.deposit_value, -                         &detail->coin_value); -      TALER_amount_hton (&dd.deposit_fee, -                         &detail->coin_fee); -      if ( (0 > +      if ( (GNUNET_OK != +            GNUNET_JSON_parse (detail_j, +                               spec_detail, +                               NULL, NULL)) || +           (0 >              TALER_amount_add (&total_expected,                                &total_expected,                                &detail->coin_value)) || @@ -177,71 +167,78 @@ check_transfers_get_response_ok (          GNUNET_break_op (0);          GNUNET_CRYPTO_hash_context_abort (hash_context);          GNUNET_JSON_parse_free (spec); +        GNUNET_free (details);          return GNUNET_SYSERR;        } -      GNUNET_CRYPTO_hash_context_read ( -        hash_context, -        &dd, -        sizeof (struct TALER_WireDepositDetailP)); +      /* build up big hash for signature checking later */ +      { +        struct TALER_WireDepositDetailP dd; + +        dd.h_contract_terms = detail->h_contract_terms; +        dd.execution_time = GNUNET_TIME_absolute_hton (td.execution_time); +        dd.coin_pub = detail->coin_pub; +        TALER_amount_hton (&dd.deposit_value, +                           &detail->coin_value); +        TALER_amount_hton (&dd.deposit_fee, +                           &detail->coin_fee); +        GNUNET_CRYPTO_hash_context_read (hash_context, +                                         &dd, +                                         sizeof (dd)); +      }      }      /* Check signature */ -    wdp.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT); -    wdp.purpose.size = htonl (sizeof (struct TALER_WireDepositDataPS)); -    TALER_amount_hton (&wdp.total, -                       &total_amount); -    TALER_amount_hton (&wdp.wire_fee, -                       &wire_fee); -    wdp.merchant_pub = merchant_pub; -    wdp.h_wire = h_wire; -    GNUNET_CRYPTO_hash_context_finish (hash_context, -                                       &wdp.h_details); -    if (GNUNET_OK != -        TALER_EXCHANGE_test_signing_key (TALER_EXCHANGE_get_keys ( -                                           wdh->exchange), -                                         &exchange_pub))      { -      GNUNET_break_op (0); -      GNUNET_JSON_parse_free (spec); -      return GNUNET_SYSERR; -    } -    if (GNUNET_OK != -        GNUNET_CRYPTO_eddsa_verify ( -          TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT, -          &wdp, -          &exchange_sig.eddsa_signature, -          &exchange_pub.eddsa_pub)) -    { -      GNUNET_break_op (0); -      GNUNET_JSON_parse_free (spec); -      return GNUNET_SYSERR; +      struct TALER_WireDepositDataPS wdp = { +        .purpose.purpose = htonl ( +          TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT), +        .purpose.size = htonl (sizeof (wdp)), +        .merchant_pub = merchant_pub, +        .h_wire = td.h_wire +      }; + +      TALER_amount_hton (&wdp.total, +                         &td.total_amount); +      TALER_amount_hton (&wdp.wire_fee, +                         &td.wire_fee); +      GNUNET_CRYPTO_hash_context_finish (hash_context, +                                         &wdp.h_details); +      if (GNUNET_OK != +          GNUNET_CRYPTO_eddsa_verify ( +            TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT, +            &wdp, +            &td.exchange_sig.eddsa_signature, +            &td.exchange_pub.eddsa_pub)) +      { +        GNUNET_break_op (0); +        GNUNET_JSON_parse_free (spec); +        GNUNET_free (details); +        return GNUNET_SYSERR; +      }      }      if (0 >          TALER_amount_subtract (&total_expected,                                 &total_expected, -                               &wire_fee)) +                               &td.wire_fee))      {        GNUNET_break_op (0);        GNUNET_JSON_parse_free (spec); +      GNUNET_free (details);        return GNUNET_SYSERR;      }      if (0 !=          TALER_amount_cmp (&total_expected, -                          &total_amount)) +                          &td.total_amount))      {        GNUNET_break_op (0);        GNUNET_JSON_parse_free (spec); +      GNUNET_free (details);        return GNUNET_SYSERR;      }      wdh->cb (wdh->cb_cls,               &hr, -             &exchange_pub, -             &h_wire, -             exec_time, -             &total_amount, -             &wire_fee, -             num_details, -             details); +             &td); +    GNUNET_free (details);    }    GNUNET_JSON_parse_free (spec);    TALER_EXCHANGE_transfers_get_cancel (wdh); @@ -322,12 +319,7 @@ handle_transfers_get_finished (void *cls,    }    wdh->cb (wdh->cb_cls,             &hr, -           NULL, -           NULL, -           GNUNET_TIME_UNIT_ZERO_ABS, -           NULL, -           NULL, -           0, NULL); +           NULL);    TALER_EXCHANGE_transfers_get_cancel (wdh);  } diff --git a/src/testing/testing_api_cmd_transfer_get.c b/src/testing/testing_api_cmd_transfer_get.c index 699313e5..3ca319cb 100644 --- a/src/testing/testing_api_cmd_transfer_get.c +++ b/src/testing/testing_api_cmd_transfer_get.c @@ -121,37 +121,18 @@ track_transfer_cleanup (void *cls,   *   * @param cls closure.   * @param hr HTTP response details - * @param exchange_pub public key the exchange used for signing - *        the response. - * @param h_wire hash of the wire transfer address the transfer - *        went to, or NULL on error. - * @param execution_time time when the exchange claims to have - *        performed the wire transfer. - * @param total_amount total amount of the wire transfer, or NULL - *        if the exchange could not provide any @a wtid (set only - *        if @a http_status is "200 OK"). - * @param wire_fee wire fee that was charged by the exchange. - * @param details_length length of the @a details array. - * @param details array with details about the combined - *        transactions. + * @param ta transfer data returned by the exchange   */  static void  track_transfer_cb (void *cls,                     const struct TALER_EXCHANGE_HttpResponse *hr, -                   const struct TALER_ExchangePublicKeyP *exchange_pub, -                   const struct GNUNET_HashCode *h_wire, -                   struct GNUNET_TIME_Absolute execution_time, -                   const struct TALER_Amount *total_amount, -                   const struct TALER_Amount *wire_fee, -                   unsigned int details_length, -                   const struct TALER_TrackTransferDetails *details) +                   const struct TALER_EXCHANGE_TransferData *ta)  {    struct TrackTransferState *tts = cls;    struct TALER_TESTING_Interpreter *is = tts->is;    struct TALER_TESTING_Command *cmd = &is->commands[is->ip];    struct TALER_Amount expected_amount; -  (void) exchange_pub;    tts->tth = NULL;    if (tts->expected_response_code != hr->http_status)    { @@ -193,14 +174,14 @@ track_transfer_cb (void *cls,        TALER_TESTING_interpreter_fail (is);        return;      } -    if (0 != TALER_amount_cmp (total_amount, +    if (0 != TALER_amount_cmp (&ta->total_amount,                                 &expected_amount))      {        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,                    "Total amount mismatch to command %s - "                    "%s vs %s\n",                    cmd->label, -                  TALER_amount_to_string (total_amount), +                  TALER_amount_to_string (&ta->total_amount),                    TALER_amount_to_string (&expected_amount));        json_dumpf (hr->reply,                    stderr, @@ -219,7 +200,7 @@ track_transfer_cb (void *cls,        return;      } -    if (0 != TALER_amount_cmp (wire_fee, +    if (0 != TALER_amount_cmp (&ta->wire_fee,                                 &expected_amount))      {        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -266,7 +247,7 @@ track_transfer_cb (void *cls,                       TALER_JSON_merchant_wire_signature_hash (wire_details,                                                                &h_wire_details));        if (0 != GNUNET_memcmp (&h_wire_details, -                              h_wire)) +                              &ta->h_wire))        {          GNUNET_log (GNUNET_ERROR_TYPE_ERROR,                      "Wire hash missmath to command %s\n", @@ -301,7 +282,7 @@ track_transfer_cb (void *cls,          TALER_TESTING_interpreter_fail (is);          return;        } -      if (0 != TALER_amount_cmp (total_amount, +      if (0 != TALER_amount_cmp (&ta->total_amount,                                   total_amount_from_reference))        {          GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 
