diff options
41 files changed, 605 insertions, 339 deletions
@@ -1,3 +1,12 @@ +Fri 03 May 2019 05:36:10 PM CEST +    Add support for compressing bodies during HTTP uploads to +    exchange and auditor. -CG + +Thu 02 May 2019 09:15:37 PM CEST +    Pass hash of denomination public key in operations from +    clients to exchange instead of the (larger) full public key. +    Breaks protocol compatibility, bumping protocol to v3. -CG +  Mon Mar 11 03:24:07 CET 2019  	Completed implementation of #5536 (delete private keys once we  	no longer need them). -CG diff --git a/configure.ac b/configure.ac index 842f24a5..3c1d9dd3 100644 --- a/configure.ac +++ b/configure.ac @@ -180,6 +180,10 @@ AS_IF([test $libgnunetjson != 1],  *** ]])]) +# Save before checking libgnurl/libcurl +CFLAGS_SAVE=$CFLAGS +LDFLAGS_SAVE=$LDFLAGS +LIBS_SAVE=$LIBS  # check for libgnurl  # libgnurl @@ -240,6 +244,10 @@ AS_IF([test $libgnunetcurl != 1],  *** ]])]) +# Restore after gnurl/curl checks messed up these values +CFLAGS=$CFLAGS_SAVE +LDFLAGS=$LDFLAGS_SAVE +LIBS=$LIBS_SAVE  # Check for GNUnet's libgnunetpq.  libgnunetpq=0 @@ -325,9 +333,9 @@ else  CFLAGS_SAVE=$CFLAGS  LDFLAGS_SAVE=$LDFLAGS +LIBS_SAVE=$LIBS  CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS"  LDFLAGS="$LDFLAGS $LIBGCRYPT_LDFLAGS" -LIBS_SAVE="$LIBS"  LIBS="-lgcrypt -lgpg-error $LIBS" diff --git a/src/auditor/taler-auditor-httpd_parsing.c b/src/auditor/taler-auditor-httpd_parsing.c index ebbe50ee..6c4bece9 100644 --- a/src/auditor/taler-auditor-httpd_parsing.c +++ b/src/auditor/taler-auditor-httpd_parsing.c @@ -70,6 +70,7 @@ TAH_PARSE_post_json (struct MHD_Connection *connection,    enum GNUNET_JSON_PostResult pr;    pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX, +                                connection,                                  con_cls,                                  upload_data,                                  upload_data_size, diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c index 9d629d1e..0cd84523 100644 --- a/src/auditor/taler-auditor.c +++ b/src/auditor/taler-auditor.c @@ -562,25 +562,18 @@ static struct GNUNET_CONTAINER_MultiHashMap *denominations;  /**   * Obtain information about a @a denom_pub.   * - * @param denom_pub key to look up + * @param dh hash of the denomination public key to look up   * @param[out] dki set to detailed information about @a denom_pub, NULL if not found, must   *                 NOT be freed by caller - * @param[out] dh set to the hash of @a denom_pub, may be NULL   * @return transaction status code   */  static enum GNUNET_DB_QueryStatus -get_denomination_info (const struct TALER_DenominationPublicKey *denom_pub, -                       const struct TALER_EXCHANGEDB_DenominationKeyInformationP **dki, -                       struct GNUNET_HashCode *dh) +get_denomination_info_by_hash (const struct GNUNET_HashCode *dh, +                       const struct TALER_EXCHANGEDB_DenominationKeyInformationP **dki)  { -  struct GNUNET_HashCode hc;    struct TALER_EXCHANGEDB_DenominationKeyInformationP *dkip;    enum GNUNET_DB_QueryStatus qs; -  if (NULL == dh) -    dh = &hc; -  GNUNET_CRYPTO_rsa_public_key_hash (denom_pub->rsa_public_key, -                                     dh);    if (NULL == denominations)      denominations = GNUNET_CONTAINER_multihashmap_create (256,                                                            GNUNET_NO); @@ -594,9 +587,9 @@ get_denomination_info (const struct TALER_DenominationPublicKey *denom_pub,    }    dkip = GNUNET_new (struct TALER_EXCHANGEDB_DenominationKeyInformationP);    qs = edb->get_denomination_info (edb->cls, -				   esession, -				   denom_pub, -				   dkip); +                                   esession, +                                   dh, +                                   dkip);    if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)    {      GNUNET_free (dkip); @@ -624,6 +617,31 @@ get_denomination_info (const struct TALER_DenominationPublicKey *denom_pub,  /** + * Obtain information about a @a denom_pub. + * + * @param denom_pub key to look up + * @param[out] dki set to detailed information about @a denom_pub, NULL if not found, must + *                 NOT be freed by caller + * @param[out] dh set to the hash of @a denom_pub, may be NULL + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +get_denomination_info (const struct TALER_DenominationPublicKey *denom_pub, +                       const struct TALER_EXCHANGEDB_DenominationKeyInformationP **dki, +                       struct GNUNET_HashCode *dh) +{ +  struct GNUNET_HashCode hc; + +  if (NULL == dh) +    dh = &hc; +  GNUNET_CRYPTO_rsa_public_key_hash (denom_pub->rsa_public_key, +                                     dh); +  return get_denomination_info_by_hash (dh, +                                        dki); +} + + +/**   * Free denomination key information.   *   * @param cls NULL @@ -1065,6 +1083,7 @@ handle_payback_by_reserve (void *cls,                             const struct TALER_Amount *amount,                             const struct TALER_ReservePublicKeyP *reserve_pub,                             const struct TALER_CoinPublicInfo *coin, +                           const struct TALER_DenominationPublicKey *denom_pub,                             const struct TALER_CoinSpendSignatureP *coin_sig,                             const struct TALER_DenominationBlindingKeyP *coin_blind)  { @@ -1081,11 +1100,12 @@ handle_payback_by_reserve (void *cls,    /* should be monotonically increasing */    GNUNET_assert (rowid >= ppr.last_reserve_payback_serial_id);    ppr.last_reserve_payback_serial_id = rowid + 1; -  GNUNET_CRYPTO_rsa_public_key_hash (coin->denom_pub.rsa_public_key, -                                     &pr.h_denom_pub); +  // FIXME: should probably check that denom_pub hashes to this hash code! +  pr.h_denom_pub = coin->denom_pub_hash;    if (GNUNET_OK != -      TALER_test_coin_valid (coin)) +      TALER_test_coin_valid (coin, +                             denom_pub))    {      report (report_bad_sig_losses,              json_pack ("{s:s, s:I, s:o, s:o}", @@ -2263,9 +2283,8 @@ wire_transfer_information_cb (void *cls,      break;    }    GNUNET_assert (NULL != coin); /* hard check that switch worked */ -  qs = get_denomination_info (&coin->denom_pub, -			      &dki, -			      NULL); +  qs = get_denomination_info_by_hash (&coin->denom_pub_hash, +                                      &dki);    if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)    {      GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); diff --git a/src/bank-lib/fakebank.c b/src/bank-lib/fakebank.c index 27cf6b8b..71dd8bac 100644 --- a/src/bank-lib/fakebank.c +++ b/src/bank-lib/fakebank.c @@ -397,6 +397,7 @@ handle_admin_add_incoming (struct TALER_FAKEBANK_Handle *h,    uint64_t row_id;    pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX, +                                connection,                                  con_cls,                                  upload_data,                                  upload_data_size, @@ -523,6 +524,7 @@ handle_reject (struct TALER_FAKEBANK_Handle *h,    int found;    pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX, +                                connection,                                  con_cls,                                  upload_data,                                  upload_data_size, @@ -604,7 +606,7 @@ handle_home_page (struct TALER_FAKEBANK_Handle *h,    int ret;    struct MHD_Response *resp;  #define HELLOMSG "Hello, Fakebank!" -   +    resp = MHD_create_response_from_buffer      (strlen (HELLOMSG),       HELLOMSG, @@ -721,8 +723,8 @@ handle_history_range (struct TALER_FAKEBANK_Handle *h,    struct HistoryRangeDates hrd;    const char *start;    const char *end; -  long long unsigned int start_stamp;  -  long long unsigned int end_stamp;  +  long long unsigned int start_stamp; +  long long unsigned int end_stamp;    struct Transaction *pos;    if (GNUNET_OK != TFH_parse_history_common_args (connection, @@ -760,7 +762,7 @@ handle_history_range (struct TALER_FAKEBANK_Handle *h,         pos = pos->next)    {      if (hrd.start.abs_value_us <= pos->date.abs_value_us) -      break;  +      break;    }    return TFH_build_history_response (connection,                                       pos, diff --git a/src/benchmark/taler-exchange-benchmark.c b/src/benchmark/taler-exchange-benchmark.c index 59fcc659..56928351 100644 --- a/src/benchmark/taler-exchange-benchmark.c +++ b/src/benchmark/taler-exchange-benchmark.c @@ -566,6 +566,7 @@ parallel_benchmark (TALER_TESTING_Main main_cb,    struct GNUNET_OS_Process *exchanged = NULL;    struct GNUNET_OS_Process *wirewatch = NULL;    struct GNUNET_OS_Process *exchange_slave = NULL; +  struct GNUNET_DISK_PipeHandle *exchange_slave_pipe;    if ( (MODE_CLIENT == mode) || (MODE_BOTH == mode) )    { @@ -650,9 +651,14 @@ parallel_benchmark (TALER_TESTING_Main main_cb,                  "remote command: %s\n",                  remote_cmd); +    GNUNET_assert (NULL != (exchange_slave_pipe = +                            GNUNET_DISK_pipe (GNUNET_YES, +                                              GNUNET_YES, +                                              0, 0))); +      exchange_slave = GNUNET_OS_start_process (GNUNET_NO, -                                              GNUNET_OS_INHERIT_STD_ALL, -                                              NULL, NULL, NULL, +                                              GNUNET_OS_INHERIT_STD_OUT_AND_ERR, +                                              exchange_slave_pipe, NULL, NULL,                                                "ssh",                                                "ssh",                                                /* Don't ask for pw/passphrase, rather fail */ @@ -758,8 +764,19 @@ parallel_benchmark (TALER_TESTING_Main main_cb,    if (MODE_CLIENT == mode)    { +    char c = 'q'; +      GNUNET_assert (NULL != exchange_slave); -    GNUNET_OS_process_kill (exchange_slave, SIGTERM); + +    /* Write a character to the pipe to end the exchange slave. +     * We can't send a signal here, as it would just kill SSH and +     * not necessarily the process on the other machine. */ +    GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle +                            (exchange_slave_pipe, GNUNET_DISK_PIPE_END_WRITE), +                            &c, sizeof (c)); + +    GNUNET_break (GNUNET_OK == +                  GNUNET_OS_process_wait (exchange_slave));      GNUNET_OS_process_destroy (exchange_slave);    } @@ -816,8 +833,8 @@ int  main (int argc,        char *const *argv)  { -  char *exchange_url; -  char *auditor_url; +  char *exchange_url = NULL; +  char *auditor_url = NULL;    struct GNUNET_CONFIGURATION_Handle *cfg;    struct GNUNET_GETOPT_CommandLineOption options[] = {      GNUNET_GETOPT_option_mandatory @@ -1031,8 +1048,14 @@ main (int argc,                                 NULL,                                 cfg_filename,                                 exchange_url); -  GNUNET_free (exchange_url); -  GNUNET_free (auditor_url); + +  GNUNET_free_non_null (exchange_url); +  GNUNET_free_non_null (auditor_url); + +  /* If we're the exchange worker, we're done now.  No need to print results */ +  if (MODE_EXCHANGE == mode) +    return (GNUNET_OK == result) ? 0 : result; +    duration = GNUNET_TIME_absolute_get_duration (start_time);    if (GNUNET_OK == result)    { diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 530cff77..5a1bf496 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -246,7 +246,7 @@ verify_and_execute_deposit (struct MHD_Connection *connection,    struct TALER_Amount amount_without_fee;    struct DepositContext dc;    struct TEH_KS_StateHandle *mks; -  struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; +  const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;    /* check signature */    dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT); @@ -282,9 +282,9 @@ verify_and_execute_deposit (struct MHD_Connection *connection,                                                TALER_EC_EXCHANGE_BAD_CONFIGURATION,                                                "no keys");    } -  dki = TEH_KS_denomination_key_lookup (mks, -                                        &deposit->coin.denom_pub, -                                        TEH_KS_DKU_DEPOSIT); +  dki = TEH_KS_denomination_key_lookup_by_hash (mks, +                                                &deposit->coin.denom_pub_hash, +                                                TEH_KS_DKU_DEPOSIT);    if (NULL == dki)    {      TEH_KS_release (mks); @@ -392,7 +392,7 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,    struct GNUNET_JSON_Specification spec[] = {      GNUNET_JSON_spec_json ("wire", &wire),      TALER_JSON_spec_amount ("contribution", &deposit.amount_with_fee), -    TALER_JSON_spec_denomination_public_key ("denom_pub", &deposit.coin.denom_pub), +    GNUNET_JSON_spec_fixed_auto ("denom_pub_hash", &deposit.coin.denom_pub_hash),      TALER_JSON_spec_denomination_signature ("ub_sig", &deposit.coin.denom_sig),      GNUNET_JSON_spec_fixed_auto ("coin_pub", &deposit.coin.coin_pub),      GNUNET_JSON_spec_fixed_auto ("merchant_pub", &deposit.merchant_pub), @@ -487,9 +487,9 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,                                                TALER_EC_EXCHANGE_BAD_CONFIGURATION,                                                "no keys");    } -  dki = TEH_KS_denomination_key_lookup (key_state, -                                        &deposit.coin.denom_pub, -					TEH_KS_DKU_DEPOSIT); +  dki = TEH_KS_denomination_key_lookup_by_hash (key_state, +                                                &deposit.coin.denom_pub_hash, +                                                TEH_KS_DKU_DEPOSIT);    if (NULL == dki)    {      /* FIXME: #3887: if DK was revoked, we might want to give a 403 and not a 404! */ @@ -504,7 +504,8 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,                       &dki->issue.properties.fee_deposit);    /* check coin signature */    if (GNUNET_YES != -      TALER_test_coin_valid (&deposit.coin)) +      TALER_test_coin_valid (&deposit.coin, +                             &dki->denom_pub))    {      TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");      TEH_KS_release (key_state); diff --git a/src/exchange/taler-exchange-httpd_keystate.c b/src/exchange/taler-exchange-httpd_keystate.c index 901ab6fa..a452a124 100644 --- a/src/exchange/taler-exchange-httpd_keystate.c +++ b/src/exchange/taler-exchange-httpd_keystate.c @@ -39,7 +39,7 @@   * release version, and the format is NOT the same that semantic   * versioning uses either.   */ -#define TALER_PROTOCOL_VERSION "2:0:0" +#define TALER_PROTOCOL_VERSION "3:0:0"  /** @@ -674,7 +674,7 @@ add_denomination_transaction (void *cls,    qs = TEH_plugin->get_denomination_info (TEH_plugin->cls,  					  session, -					  &dki->denom_pub, +					  &dki->issue.properties.denom_hash,  					  &issue_exists);    if (0 > qs)      return qs; @@ -789,7 +789,7 @@ revocations_iter (void *cls,    struct TEH_KS_StateHandle *key_state = rfc->key_state;    struct AddRevocationContext arc;    struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; -   +    dki = GNUNET_CONTAINER_multihashmap_get (key_state->denomkey_map,  					   denom_hash);    if (NULL == dki) @@ -1613,7 +1613,7 @@ make_fresh_key_state (struct GNUNET_TIME_Absolute now)      json_decref (rfc.sign_keys_array);      return NULL;    } -   +    /* Initialize `current_sign_key_issue` and `rfc.sign_keys_array` */    TALER_EXCHANGEDB_signing_keys_iterate (TEH_exchange_directory,                                           &reload_keys_sign_iter, diff --git a/src/exchange/taler-exchange-httpd_keystate.h b/src/exchange/taler-exchange-httpd_keystate.h index 62d69373..c9b98230 100644 --- a/src/exchange/taler-exchange-httpd_keystate.h +++ b/src/exchange/taler-exchange-httpd_keystate.h @@ -127,7 +127,7 @@ enum TEH_KS_DenominationKeyUse {  struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *  TEH_KS_denomination_key_lookup (const struct TEH_KS_StateHandle *key_state,                                  const struct TALER_DenominationPublicKey *denom_pub, -				enum TEH_KS_DenominationKeyUse use); +                                enum TEH_KS_DenominationKeyUse use);  /** diff --git a/src/exchange/taler-exchange-httpd_parsing.c b/src/exchange/taler-exchange-httpd_parsing.c index 4d7b5ab6..2a9f7a5a 100644 --- a/src/exchange/taler-exchange-httpd_parsing.c +++ b/src/exchange/taler-exchange-httpd_parsing.c @@ -70,6 +70,7 @@ TEH_PARSE_post_json (struct MHD_Connection *connection,    enum GNUNET_JSON_PostResult pr;    pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX, +                                connection,                                  con_cls,                                  upload_data,                                  upload_data_size, diff --git a/src/exchange/taler-exchange-httpd_payback.c b/src/exchange/taler-exchange-httpd_payback.c index 2164863e..06181519 100644 --- a/src/exchange/taler-exchange-httpd_payback.c +++ b/src/exchange/taler-exchange-httpd_payback.c @@ -326,9 +326,9 @@ verify_and_execute_payback (struct MHD_Connection *connection,                                                TALER_EC_EXCHANGE_BAD_CONFIGURATION,                                                "no keys");    } -  dki = TEH_KS_denomination_key_lookup (key_state, -                                        &coin->denom_pub, -					TEH_KS_DKU_PAYBACK); +  dki = TEH_KS_denomination_key_lookup_by_hash (key_state, +                                                &coin->denom_pub_hash, +                                                TEH_KS_DKU_PAYBACK);    if (NULL == dki)    {      TEH_KS_release (key_state); @@ -342,7 +342,8 @@ verify_and_execute_payback (struct MHD_Connection *connection,    /* check denomination signature */    if (GNUNET_YES != -      TALER_test_coin_valid (coin)) +      TALER_test_coin_valid (coin, +                             &dki->denom_pub))    {      TALER_LOG_WARNING ("Invalid coin passed for /payback\n");      TEH_KS_release (key_state); @@ -358,8 +359,6 @@ verify_and_execute_payback (struct MHD_Connection *connection,    pr.h_denom_pub = dki->issue.properties.denom_hash;    pr.coin_blind = *coin_bks; -  TEH_KS_release (key_state); -    if (GNUNET_OK !=        GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_PAYBACK,                                    &pr.purpose, @@ -367,6 +366,7 @@ verify_and_execute_payback (struct MHD_Connection *connection,                                    &coin->coin_pub.eddsa_pub))    {      TALER_LOG_WARNING ("Invalid signature on /payback request\n"); +    TEH_KS_release (key_state);      return TEH_RESPONSE_reply_signature_invalid (connection,  						 TALER_EC_PAYBACK_SIGNATURE_INVALID,                                                   "coin_sig"); @@ -378,15 +378,18 @@ verify_and_execute_payback (struct MHD_Connection *connection,    if (GNUNET_YES !=        GNUNET_CRYPTO_rsa_blind (&c_hash,                                 &coin_bks->bks, -                               coin->denom_pub.rsa_public_key, +                               dki->denom_pub.rsa_public_key,                                 &coin_ev,                                 &coin_ev_size))    {      GNUNET_break (0); +    TEH_KS_release (key_state); +      return TEH_RESPONSE_reply_internal_error (connection,                                                TALER_EC_PAYBACK_BLINDING_FAILED,                                                "coin_bks");    } +  TEH_KS_release (key_state);    GNUNET_CRYPTO_hash (coin_ev,                        coin_ev_size,                        &pc.h_blind); @@ -454,8 +457,8 @@ TEH_PAYBACK_handler_payback (struct TEH_RequestHandler *rh,    struct TALER_DenominationBlindingKeyP coin_bks;    struct TALER_CoinSpendSignatureP coin_sig;    struct GNUNET_JSON_Specification spec[] = { -    TALER_JSON_spec_denomination_public_key ("denom_pub", -                                             &coin.denom_pub), +    GNUNET_JSON_spec_fixed_auto ("denom_pub_hash", +                                 &coin.denom_pub_hash),      TALER_JSON_spec_denomination_signature ("denom_sig",                                              &coin.denom_sig),      GNUNET_JSON_spec_fixed_auto ("coin_pub", diff --git a/src/exchange/taler-exchange-httpd_refresh_melt.c b/src/exchange/taler-exchange-httpd_refresh_melt.c index 8e776c77..1b8e04a0 100644 --- a/src/exchange/taler-exchange-httpd_refresh_melt.c +++ b/src/exchange/taler-exchange-httpd_refresh_melt.c @@ -412,8 +412,8 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,                                   &rmc.refresh_session.coin.coin_pub),      TALER_JSON_spec_denomination_signature ("denom_sig",                                              &rmc.refresh_session.coin.denom_sig), -    TALER_JSON_spec_denomination_public_key ("denom_pub", -                                             &rmc.refresh_session.coin.denom_pub), +    GNUNET_JSON_spec_fixed_auto ("denom_pub_hash", +                                 &rmc.refresh_session.coin.denom_pub_hash),      GNUNET_JSON_spec_fixed_auto ("confirm_sig",                                   &rmc.refresh_session.coin_sig),      TALER_JSON_spec_amount ("value_with_fee", @@ -444,17 +444,6 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,    if (GNUNET_OK != res)      return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; -  if (GNUNET_OK != -      TALER_test_coin_valid (&rmc.refresh_session.coin)) -  { -    GNUNET_break_op (0); -    GNUNET_JSON_parse_free (spec); -    return TEH_RESPONSE_reply_signature_invalid (connection, -                                                 TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID, -                                                 "denom_sig"); -  } - -  /* run actual logic, now that the request was parsed */    key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());    if (NULL == key_state)    { @@ -464,9 +453,9 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,                                               "no keys");      goto cleanup;    } -  rmc.dki = TEH_KS_denomination_key_lookup (key_state, -                                            &rmc.refresh_session.coin.denom_pub, -                                            TEH_KS_DKU_DEPOSIT); +  rmc.dki = TEH_KS_denomination_key_lookup_by_hash (key_state, +                                                    &rmc.refresh_session.coin.denom_pub_hash, +                                                    TEH_KS_DKU_DEPOSIT);    if (NULL == rmc.dki)    {      TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n"); @@ -476,6 +465,20 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,      goto cleanup;    } +  if (GNUNET_OK != +      TALER_test_coin_valid (&rmc.refresh_session.coin, +                             &rmc.dki->denom_pub)) +  { +    GNUNET_break_op (0); +    GNUNET_JSON_parse_free (spec); +    TEH_KS_release (key_state); +    return TEH_RESPONSE_reply_signature_invalid (connection, +                                                 TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID, +                                                 "denom_sig"); +  } + +  /* run actual logic, now that the request was parsed */ +    /* make sure coin is 'known' in database */    {      struct TEH_DB_KnowCoinContext kcc; @@ -502,11 +505,6 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,      TEH_KS_release (key_state);      key_state = NULL;    } -  if (NULL != rmc.refresh_session.coin.denom_pub.rsa_public_key) -  { -    GNUNET_CRYPTO_rsa_public_key_free (rmc.refresh_session.coin.denom_pub.rsa_public_key); -    rmc.refresh_session.coin.denom_pub.rsa_public_key = NULL; -  }    if (NULL != rmc.refresh_session.coin.denom_sig.rsa_signature)    {      GNUNET_CRYPTO_rsa_signature_free (rmc.refresh_session.coin.denom_sig.rsa_signature); diff --git a/src/exchange/taler-exchange-httpd_refresh_reveal.c b/src/exchange/taler-exchange-httpd_refresh_reveal.c index bdf59c37..25de5f1f 100644 --- a/src/exchange/taler-exchange-httpd_refresh_reveal.c +++ b/src/exchange/taler-exchange-httpd_refresh_reveal.c @@ -265,7 +265,6 @@ static void  free_refresh_melt (struct TALER_EXCHANGEDB_RefreshMelt *refresh_melt)  {    GNUNET_CRYPTO_rsa_signature_free (refresh_melt->session.coin.denom_sig.rsa_signature); -  GNUNET_CRYPTO_rsa_public_key_free (refresh_melt->session.coin.denom_pub.rsa_public_key);  } diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c index 92dd54e9..ee6aac1b 100644 --- a/src/exchange/taler-exchange-httpd_refund.c +++ b/src/exchange/taler-exchange-httpd_refund.c @@ -342,9 +342,9 @@ refund_transaction (void *cls,                                                    "no keys");      return GNUNET_DB_STATUS_HARD_ERROR;    } -  dki = TEH_KS_denomination_key_lookup (mks, -                                        &dep->coin.denom_pub, -					TEH_KS_DKU_DEPOSIT); +  dki = TEH_KS_denomination_key_lookup_by_hash (mks, +                                                &dep->coin.denom_pub_hash, +                                                TEH_KS_DKU_DEPOSIT);    if (NULL == dki)    {      /* DKI not found, but we do have a coin with this DK in our database; diff --git a/src/exchange/taler-exchange-httpd_reserve_withdraw.c b/src/exchange/taler-exchange-httpd_reserve_withdraw.c index 370916b0..c988cde6 100644 --- a/src/exchange/taler-exchange-httpd_reserve_withdraw.c +++ b/src/exchange/taler-exchange-httpd_reserve_withdraw.c @@ -116,9 +116,9 @@ struct WithdrawContext    struct TALER_Amount amount_required;    /** -   * Denomination public key. +   * Hash of the denomination public key.     */ -  struct TALER_DenominationPublicKey denomination_pub; +  struct GNUNET_HashCode denom_pub_hash;    /**     * Signature over the request. @@ -229,7 +229,7 @@ withdraw_transaction (void *cls,     */    {  #define PUBSIZE 80 -    char pub_s[PUBSIZE];  +    char pub_s[PUBSIZE];      GNUNET_break        (NULL != GNUNET_STRINGS_data_to_string (&r.pub, @@ -312,7 +312,7 @@ withdraw_transaction (void *cls,  #endif    TALER_amount_ntoh (&fee_withdraw,                       &wc->dki->issue.properties.fee_withdraw); -  wc->collectable.denom_pub = wc->denomination_pub; +  wc->collectable.denom_pub_hash = wc->denom_pub_hash;    wc->collectable.amount_with_fee = wc->amount_required;    wc->collectable.withdraw_fee = fee_withdraw;    wc->collectable.reserve_pub = wc->wsrd.reserve_pub; @@ -370,8 +370,8 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,                                   &wc.wsrd.reserve_pub),      GNUNET_JSON_spec_fixed_auto ("reserve_sig",                                   &wc.signature), -    TALER_JSON_spec_denomination_public_key ("denom_pub", -                                             &wc.denomination_pub), +    GNUNET_JSON_spec_fixed_auto ("denom_pub_hash", +                                 &wc.denom_pub_hash),      GNUNET_JSON_spec_end ()    }; @@ -399,9 +399,9 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,                                                TALER_EC_EXCHANGE_BAD_CONFIGURATION,                                                "no keys");    } -  wc.dki = TEH_KS_denomination_key_lookup (wc.key_state, -					   &wc.denomination_pub, -					   TEH_KS_DKU_WITHDRAW); +  wc.dki = TEH_KS_denomination_key_lookup_by_hash (wc.key_state, +                                                   &wc.denom_pub_hash, +                                                   TEH_KS_DKU_WITHDRAW);    if (NULL == wc.dki)    {      GNUNET_JSON_parse_free (spec); @@ -435,8 +435,8 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,      = htonl (sizeof (struct TALER_WithdrawRequestPS));    wc.wsrd.purpose.purpose      = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW); -  GNUNET_CRYPTO_rsa_public_key_hash (wc.denomination_pub.rsa_public_key, -                                     &wc.wsrd.h_denomination_pub); +  wc.wsrd.h_denomination_pub +    = wc.denom_pub_hash;    GNUNET_CRYPTO_hash (wc.blinded_msg,                        wc.blinded_msg_len,                        &wc.wsrd.h_coin_envelope); diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 21046ef9..21394337 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -750,7 +750,6 @@ TEH_RESPONSE_compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHisto        break;      case TALER_EXCHANGEDB_RO_WITHDRAW_COIN:        { -	struct GNUNET_HashCode h_denom_pub;  	struct TALER_Amount value;  	value = pos->details.withdraw->amount_with_fee; @@ -771,15 +770,13 @@ TEH_RESPONSE_compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHisto  	  }  	}  	ret |= 2; -	GNUNET_CRYPTO_rsa_public_key_hash (pos->details.withdraw->denom_pub.rsa_public_key, -					   &h_denom_pub);  	GNUNET_assert (0 ==  		       json_array_append_new (json_history,  					      json_pack ("{s:s, s:o, s:o, s:o, s:o, s:o}",  							 "type", "WITHDRAW",  							 "reserve_sig", GNUNET_JSON_from_data_auto (&pos->details.withdraw->reserve_sig),  							 "h_coin_envelope", GNUNET_JSON_from_data_auto (&pos->details.withdraw->h_coin_envelope), -							 "h_denom_pub", GNUNET_JSON_from_data_auto (&h_denom_pub), +							 "h_denom_pub", GNUNET_JSON_from_data_auto (&pos->details.withdraw->denom_pub_hash),  							 "withdraw_fee", TALER_JSON_from_amount (&pos->details.withdraw->withdraw_fee),  							 "amount", TALER_JSON_from_amount (&value))));        } diff --git a/src/exchange/test_taler_exchange_aggregator.c b/src/exchange/test_taler_exchange_aggregator.c index 0ba8152d..c0d3d912 100644 --- a/src/exchange/test_taler_exchange_aggregator.c +++ b/src/exchange/test_taler_exchange_aggregator.c @@ -383,7 +383,8 @@ fake_coin (struct TALER_CoinPublicInfo *coin)  {    struct GNUNET_HashCode hc; -  coin->denom_pub.rsa_public_key = coin_pub; +  GNUNET_CRYPTO_rsa_public_key_hash (coin_pub, +                                     &coin->denom_pub_hash);    GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,                                      &hc);    coin->denom_sig.rsa_signature = GNUNET_CRYPTO_rsa_sign_fdh (coin_pk, diff --git a/src/exchangedb/perf_taler_exchangedb_init.c b/src/exchangedb/perf_taler_exchangedb_init.c index 789aaea0..089536a4 100644 --- a/src/exchangedb/perf_taler_exchangedb_init.c +++ b/src/exchangedb/perf_taler_exchangedb_init.c @@ -263,9 +263,7 @@ PERF_TALER_EXCHANGEDB_deposit_init (const struct PERF_TALER_EXCHANGEDB_Coin *coi                                           &deposit_fee));    {      deposit->coin.coin_pub = coin->public_info.coin_pub; -    deposit->coin.denom_pub.rsa_public_key = GNUNET_CRYPTO_rsa_public_key_dup ( -      coin->public_info.denom_pub.rsa_public_key); -    GNUNET_assert (NULL != coin->public_info.denom_pub.rsa_public_key); +    deposit->coin.denom_pub_hash = coin->public_info.denom_pub_hash;      deposit->coin.denom_sig.rsa_signature = GNUNET_CRYPTO_rsa_signature_dup (        coin->public_info.denom_sig.rsa_signature);      GNUNET_assert (NULL != coin->public_info.denom_sig.rsa_signature); @@ -298,8 +296,6 @@ PERF_TALER_EXCHANGEDB_deposit_copy (const struct TALER_EXCHANGEDB_Deposit *depos    copy = GNUNET_new (struct TALER_EXCHANGEDB_Deposit);    *copy = *deposit;    copy->receiver_wire_account = json_incref (deposit->receiver_wire_account); -  copy->coin.denom_pub.rsa_public_key = -    GNUNET_CRYPTO_rsa_public_key_dup (deposit->coin.denom_pub.rsa_public_key);    copy->coin.denom_sig.rsa_signature =      GNUNET_CRYPTO_rsa_signature_dup (deposit->coin.denom_sig.rsa_signature);    return copy; @@ -315,7 +311,6 @@ PERF_TALER_EXCHANGEDB_deposit_free (struct TALER_EXCHANGEDB_Deposit *deposit)  {    if (NULL == deposit)      return GNUNET_OK; -  GNUNET_CRYPTO_rsa_public_key_free (deposit->coin.denom_pub.rsa_public_key);    GNUNET_CRYPTO_rsa_signature_free (deposit->coin.denom_sig.rsa_signature);    json_decref (deposit->receiver_wire_account);    GNUNET_free (deposit); @@ -350,24 +345,21 @@ PERF_TALER_EXCHANGEDB_coin_init (    /* public_info */    GNUNET_CRYPTO_eddsa_key_get_public (&coin->priv,                                        &coin->public_info.coin_pub.eddsa_pub); -  coin->public_info.denom_pub.rsa_public_key = -    GNUNET_CRYPTO_rsa_public_key_dup (dki->denom_pub.rsa_public_key); +  GNUNET_CRYPTO_rsa_public_key_hash (dki->denom_pub.rsa_public_key, +                                     &coin->public_info.denom_pub_hash);    GNUNET_CRYPTO_hash (&coin->public_info.coin_pub,                        sizeof (struct TALER_CoinSpendPublicKeyP),                        &hc);    coin->public_info.denom_sig.rsa_signature =      GNUNET_CRYPTO_rsa_sign_fdh (dki->denom_priv.rsa_private_key,                                  &hc); -  GNUNET_assert (NULL != coin->public_info.denom_pub.rsa_public_key);    GNUNET_assert (NULL != coin->public_info.denom_sig.rsa_signature);    /* blind */    coin->blind.sig.rsa_signature =      GNUNET_CRYPTO_rsa_signature_dup (coin->public_info.denom_sig.rsa_signature); -  coin->blind.denom_pub.rsa_public_key = -    GNUNET_CRYPTO_rsa_public_key_dup (dki->denom_pub.rsa_public_key); +  coin->blind.denom_pub_hash = coin->public_info.denom_pub_hash;    GNUNET_assert (NULL != coin->blind.sig.rsa_signature); -  GNUNET_assert (NULL != coin->blind.denom_pub.rsa_public_key);    TALER_amount_ntoh (&coin->blind.amount_with_fee,                       &dki->issue.properties.value);    TALER_amount_ntoh (&coin->blind.withdraw_fee, @@ -396,16 +388,14 @@ PERF_TALER_EXCHANGEDB_coin_copy (const struct PERF_TALER_EXCHANGEDB_Coin *coin)    copy->priv = coin->priv;    /* public_info */    copy->public_info.coin_pub = coin->public_info.coin_pub; -  copy->public_info.denom_pub.rsa_public_key = -    GNUNET_CRYPTO_rsa_public_key_dup (coin->public_info.denom_pub.rsa_public_key); +  copy->public_info.denom_pub_hash = coin->public_info.denom_pub_hash;    copy->public_info.denom_sig.rsa_signature =      GNUNET_CRYPTO_rsa_signature_dup (coin->public_info.denom_sig.rsa_signature);    /* blind */    copy->blind.sig.rsa_signature =      GNUNET_CRYPTO_rsa_signature_dup (coin->blind.sig.rsa_signature); -  copy->blind.denom_pub.rsa_public_key = -    GNUNET_CRYPTO_rsa_public_key_dup (coin->blind.denom_pub.rsa_public_key); +  copy->blind.denom_pub_hash = coin->blind.denom_pub_hash;    copy->blind.amount_with_fee = coin->blind.amount_with_fee;    copy->blind.withdraw_fee = coin->blind.withdraw_fee;    copy->blind.reserve_pub = coin->blind.reserve_pub; @@ -426,10 +416,8 @@ PERF_TALER_EXCHANGEDB_coin_free (struct PERF_TALER_EXCHANGEDB_Coin *coin)  {    if (NULL == coin)      return GNUNET_OK; -  GNUNET_CRYPTO_rsa_public_key_free (coin->public_info.denom_pub.rsa_public_key);    GNUNET_CRYPTO_rsa_signature_free (coin->public_info.denom_sig.rsa_signature);    GNUNET_CRYPTO_rsa_signature_free (coin->blind.sig.rsa_signature); -  GNUNET_CRYPTO_rsa_public_key_free (coin->blind.denom_pub.rsa_public_key);    GNUNET_free (coin);    return GNUNET_OK;  } @@ -475,9 +463,7 @@ PERF_TALER_EXCHANGEDB_refresh_melt_init (struct TALER_RefreshCommitmentP *rc,    melt->session.coin.coin_pub = coin->public_info.coin_pub;    melt->session.coin.denom_sig.rsa_signature =      GNUNET_CRYPTO_rsa_signature_dup (coin->public_info.denom_sig.rsa_signature); -  melt->session.coin.denom_pub.rsa_public_key = -    GNUNET_CRYPTO_rsa_public_key_dup (coin->public_info.denom_pub.rsa_public_key); -  GNUNET_assert (NULL != melt->session.coin.denom_pub.rsa_public_key); +  melt->session.coin.denom_pub_hash = coin->public_info.denom_pub_hash;    GNUNET_assert (NULL != melt->session.coin.denom_sig.rsa_signature);    melt->session.coin_sig = coin_sig;    melt->session.rc = *rc; diff --git a/src/exchangedb/perf_taler_exchangedb_interpreter.c b/src/exchangedb/perf_taler_exchangedb_interpreter.c index cdd5a5fc..6c968410 100644 --- a/src/exchangedb/perf_taler_exchangedb_interpreter.c +++ b/src/exchangedb/perf_taler_exchangedb_interpreter.c @@ -1342,12 +1342,15 @@ interpret (struct PERF_TALER_EXCHANGEDB_interpreter_state *state)            unsigned int denom_index;            enum GNUNET_DB_QueryStatus qs;            struct PERF_TALER_EXCHANGEDB_Data *data; +          struct GNUNET_HashCode hc;            denom_index = state->cmd[state->i].details.get_denomination.index_denom;            data = &state->cmd[denom_index].exposed; +          GNUNET_CRYPTO_rsa_public_key_hash (data->data.dki->denom_pub.rsa_public_key, +                                             &hc);            qs = state->plugin->get_denomination_info (state->plugin->cls,  						     state->session, -						     &data->data.dki->denom_pub, +                                                     &hc,  						     &data->data.dki->issue);            GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs);          } diff --git a/src/exchangedb/plugin_exchangedb_common.c b/src/exchangedb/plugin_exchangedb_common.c index 26515670..fd2620c7 100644 --- a/src/exchangedb/plugin_exchangedb_common.c +++ b/src/exchangedb/plugin_exchangedb_common.c @@ -49,13 +49,11 @@ common_free_reserve_history (void *cls,      case TALER_EXCHANGEDB_RO_WITHDRAW_COIN:        cbc = rh->details.withdraw;        GNUNET_CRYPTO_rsa_signature_free (cbc->sig.rsa_signature); -      GNUNET_CRYPTO_rsa_public_key_free (cbc->denom_pub.rsa_public_key);        GNUNET_free (cbc);        break;      case TALER_EXCHANGEDB_RO_PAYBACK_COIN:        payback = rh->details.payback;        GNUNET_CRYPTO_rsa_signature_free (payback->coin.denom_sig.rsa_signature); -      GNUNET_CRYPTO_rsa_public_key_free (payback->coin.denom_pub.rsa_public_key);        GNUNET_free (payback);        break;      case TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK: @@ -92,29 +90,21 @@ common_free_coin_transaction_list (void *cls,      case TALER_EXCHANGEDB_TT_DEPOSIT:        if (NULL != list->details.deposit->receiver_wire_account)          json_decref (list->details.deposit->receiver_wire_account); -      if (NULL != list->details.deposit->coin.denom_pub.rsa_public_key) -        GNUNET_CRYPTO_rsa_public_key_free (list->details.deposit->coin.denom_pub.rsa_public_key);        if (NULL != list->details.deposit->coin.denom_sig.rsa_signature)          GNUNET_CRYPTO_rsa_signature_free (list->details.deposit->coin.denom_sig.rsa_signature);        GNUNET_free (list->details.deposit);        break;      case TALER_EXCHANGEDB_TT_REFRESH_MELT: -      if (NULL != list->details.melt->session.coin.denom_pub.rsa_public_key) -        GNUNET_CRYPTO_rsa_public_key_free (list->details.melt->session.coin.denom_pub.rsa_public_key);        if (NULL != list->details.melt->session.coin.denom_sig.rsa_signature)          GNUNET_CRYPTO_rsa_signature_free (list->details.melt->session.coin.denom_sig.rsa_signature);        GNUNET_free (list->details.melt);        break;      case TALER_EXCHANGEDB_TT_REFUND: -      if (NULL != list->details.refund->coin.denom_pub.rsa_public_key) -        GNUNET_CRYPTO_rsa_public_key_free (list->details.refund->coin.denom_pub.rsa_public_key);        if (NULL != list->details.refund->coin.denom_sig.rsa_signature)          GNUNET_CRYPTO_rsa_signature_free (list->details.refund->coin.denom_sig.rsa_signature);        GNUNET_free (list->details.refund);        break;      case TALER_EXCHANGEDB_TT_PAYBACK: -      if (NULL != list->details.payback->coin.denom_pub.rsa_public_key) -        GNUNET_CRYPTO_rsa_public_key_free (list->details.payback->coin.denom_pub.rsa_public_key);        if (NULL != list->details.payback->coin.denom_sig.rsa_signature)          GNUNET_CRYPTO_rsa_signature_free (list->details.payback->coin.denom_sig.rsa_signature);        GNUNET_free (list->details.payback); diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 82308ea8..9dc8eb2f 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -766,7 +766,7 @@ postgres_prepare (PGconn *db_conn)         make sure /reserve/withdraw requests are idempotent. */      GNUNET_PQ_make_prepare ("get_withdraw_info",                              "SELECT" -                            " denom.denom_pub" +                            " denom_pub_hash"                              ",denom_sig"                              ",reserve_sig"                              ",reserve_pub" @@ -790,7 +790,7 @@ postgres_prepare (PGconn *db_conn)      GNUNET_PQ_make_prepare ("get_reserves_out",                              "SELECT"                              " h_blind_ev" -                            ",denom.denom_pub" +                            ",denom_pub_hash"                              ",denom_sig"                              ",reserve_sig"                              ",execution_date" @@ -838,11 +838,9 @@ postgres_prepare (PGconn *db_conn)         a coin known to the exchange. */      GNUNET_PQ_make_prepare ("get_known_coin",                              "SELECT" -                            " denom.denom_pub" +                            " denom_pub_hash"                              ",denom_sig"                              " FROM known_coins" -                            "    JOIN denominations denom" -                            "      USING (denom_pub_hash)"                              " WHERE coin_pub=$1"                              " FOR UPDATE;",                              1), @@ -876,7 +874,7 @@ postgres_prepare (PGconn *db_conn)         high-level information about a melt operation */      GNUNET_PQ_make_prepare ("get_melt",                              "SELECT" -                            " denom.denom_pub" +                            " kc.denom_pub_hash"                              ",denom.fee_refresh_val"                              ",denom.fee_refresh_frac"                              ",denom.fee_refresh_curr" @@ -1518,6 +1516,7 @@ postgres_prepare (PGconn *db_conn)                              ",coin_sig"                              ",coin_blind"                              ",h_blind_ev" +                            ",coins.denom_pub_hash"                              ",denoms.denom_pub"                              ",coins.denom_sig"                              ",amount_val" @@ -1526,10 +1525,10 @@ postgres_prepare (PGconn *db_conn)                              " FROM payback"                              "    JOIN known_coins coins"                              "      USING (coin_pub)" -                            "    JOIN denominations denoms" -                            "      USING (denom_pub_hash)"                              "    JOIN reserves_out ro"                              "      USING (h_blind_ev)" +                            "    JOIN denominations denoms" +                            "      ON (coins.denom_pub_hash = denoms.denom_pub_hash)"                              " WHERE payback_uuid>=$1"                              " ORDER BY payback_uuid ASC;",                              1), @@ -1563,13 +1562,11 @@ postgres_prepare (PGconn *db_conn)                              ",amount_frac"                              ",amount_curr"                              ",timestamp" -                            ",denoms.denom_pub" +                            ",coins.denom_pub_hash"                              ",coins.denom_sig"                              " FROM payback"                              "    JOIN known_coins coins"                              "      USING (coin_pub)" -                            "    JOIN denominations denoms" -                            "      USING (denom_pub_hash)"                              "    JOIN reserves_out ro"                              "      USING (h_blind_ev)"                              " WHERE ro.reserve_pub=$1" @@ -1618,13 +1615,11 @@ postgres_prepare (PGconn *db_conn)                              ",amount_frac"                              ",amount_curr"                              ",timestamp" -                            ",denoms.denom_pub" +                            ",coins.denom_pub_hash"                              ",coins.denom_sig"                              " FROM payback"                              "    JOIN known_coins coins"                              "      USING (coin_pub)" -                            "    JOIN denominations denoms" -                            "      USING (denom_pub_hash)"                              "    JOIN reserves_out ro"                              "      USING (h_blind_ev)"                              " WHERE payback.coin_pub=$1;", @@ -1947,20 +1942,19 @@ postgres_insert_denomination_info (void *cls,   *   * @param cls the @e cls of this struct with the plugin-specific state   * @param session connection to use - * @param denom_pub the public key used for signing coins of this denomination + * @param denom_pub_hash hash of the public key used for signing coins of this denomination   * @param[out] issue set to issue information with value, fees and other info about the coin   * @return transaction status code   */  static enum GNUNET_DB_QueryStatus  postgres_get_denomination_info (void *cls,                                  struct TALER_EXCHANGEDB_Session *session, -                                const struct TALER_DenominationPublicKey *denom_pub, +                                const struct GNUNET_HashCode *denom_pub_hash,                                  struct TALER_EXCHANGEDB_DenominationKeyInformationP *issue)  {    enum GNUNET_DB_QueryStatus qs; -  struct GNUNET_HashCode dph;    struct GNUNET_PQ_QueryParam params[] = { -    GNUNET_PQ_query_param_auto_from_type (&dph), +    GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),      GNUNET_PQ_query_param_end    };    struct GNUNET_PQ_ResultSpec rs[] = { @@ -1989,8 +1983,6 @@ postgres_get_denomination_info (void *cls,      GNUNET_PQ_result_spec_end    }; -  GNUNET_CRYPTO_rsa_public_key_hash (denom_pub->rsa_public_key, -				     &dph);    qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,  						 "denomination_get",  						 params, @@ -1999,8 +1991,7 @@ postgres_get_denomination_info (void *cls,      return qs;    issue->properties.purpose.size = htonl (sizeof (struct TALER_DenominationKeyValidityPS));    issue->properties.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY); -  GNUNET_CRYPTO_rsa_public_key_hash (denom_pub->rsa_public_key, -                                     &issue->properties.denom_hash); +  issue->properties.denom_hash = *denom_pub_hash;    return qs;  } @@ -2394,10 +2385,10 @@ postgres_get_withdraw_info (void *cls,      GNUNET_PQ_query_param_end    };    struct GNUNET_PQ_ResultSpec rs[] = { -    GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", -					  &collectable->denom_pub.rsa_public_key), +    GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", +                                          &collectable->denom_pub_hash),      GNUNET_PQ_result_spec_rsa_signature ("denom_sig", -					 &collectable->sig.rsa_signature), +                                         &collectable->sig.rsa_signature),      GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",  					  &collectable->reserve_sig),      GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", @@ -2434,12 +2425,11 @@ postgres_insert_withdraw_info (void *cls,  {    struct PostgresClosure *pg = cls;    struct TALER_EXCHANGEDB_Reserve reserve; -  struct GNUNET_HashCode denom_pub_hash;    struct GNUNET_TIME_Absolute now;    struct GNUNET_TIME_Absolute expiry;    struct GNUNET_PQ_QueryParam params[] = {      GNUNET_PQ_query_param_auto_from_type (&collectable->h_coin_envelope), -    GNUNET_PQ_query_param_auto_from_type (&denom_pub_hash), +    GNUNET_PQ_query_param_auto_from_type (&collectable->denom_pub_hash),      GNUNET_PQ_query_param_rsa_signature (collectable->sig.rsa_signature),      GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_pub),      GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_sig), @@ -2451,8 +2441,6 @@ postgres_insert_withdraw_info (void *cls,    now = GNUNET_TIME_absolute_get ();    (void) GNUNET_TIME_round_abs (&now); -  GNUNET_CRYPTO_rsa_public_key_hash (collectable->denom_pub.rsa_public_key, -				     &denom_pub_hash);    qs = GNUNET_PQ_eval_prepared_non_select (session->conn,  					   "insert_withdraw_info",  					   params); @@ -2638,8 +2626,8 @@ add_withdraw_coin (void *cls,        struct GNUNET_PQ_ResultSpec rs[] = {  	GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",  					      &cbc->h_coin_envelope), -	GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", -					      &cbc->denom_pub.rsa_public_key), +	GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", +					      &cbc->denom_pub_hash),  	GNUNET_PQ_result_spec_rsa_signature ("denom_sig",  					     &cbc->sig.rsa_signature),  	GNUNET_PQ_result_spec_auto_from_type ("reserve_sig", @@ -2692,7 +2680,7 @@ add_payback (void *cls,      payback = GNUNET_new (struct TALER_EXCHANGEDB_Payback);      {        struct GNUNET_PQ_ResultSpec rs[] = { -	TALER_PQ_result_spec_amount ("amount", +    TALER_PQ_result_spec_amount ("amount",  				     &payback->value),  	GNUNET_PQ_result_spec_auto_from_type ("coin_pub",  					      &payback->coin.coin_pub), @@ -2702,10 +2690,10 @@ add_payback (void *cls,  					      &payback->coin_sig),  	TALER_PQ_result_spec_absolute_time ("timestamp",  					     &payback->timestamp), -	GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", -					      &payback->coin.denom_pub.rsa_public_key), +	GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", +                                          &payback->coin.denom_pub_hash),  	GNUNET_PQ_result_spec_rsa_signature ("denom_sig", -					     &payback->coin.denom_sig.rsa_signature), +                                         &payback->coin.denom_sig.rsa_signature),  	GNUNET_PQ_result_spec_end        }; @@ -3291,8 +3279,8 @@ get_known_coin (void *cls,      GNUNET_PQ_query_param_end    };    struct GNUNET_PQ_ResultSpec rs[] = { -    GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", -					  &coin_info->denom_pub.rsa_public_key), +    GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", +                                          &coin_info->denom_pub_hash),      GNUNET_PQ_result_spec_rsa_signature ("denom_sig",  					 &coin_info->denom_sig.rsa_signature),      GNUNET_PQ_result_spec_end @@ -3324,10 +3312,9 @@ insert_known_coin (void *cls,                     struct TALER_EXCHANGEDB_Session *session,                     const struct TALER_CoinPublicInfo *coin_info)  { -  struct GNUNET_HashCode denom_pub_hash;    struct GNUNET_PQ_QueryParam params[] = {      GNUNET_PQ_query_param_auto_from_type (&coin_info->coin_pub), -    GNUNET_PQ_query_param_auto_from_type (&denom_pub_hash), +    GNUNET_PQ_query_param_auto_from_type (&coin_info->denom_pub_hash),      GNUNET_PQ_query_param_rsa_signature (coin_info->denom_sig.rsa_signature),      GNUNET_PQ_query_param_end    }; @@ -3335,8 +3322,6 @@ insert_known_coin (void *cls,    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,                "Creating known coin %s\n",                TALER_B2S (&coin_info->coin_pub)); -  GNUNET_CRYPTO_rsa_public_key_hash (coin_info->denom_pub.rsa_public_key, -				     &denom_pub_hash);    return GNUNET_PQ_eval_prepared_non_select (session->conn,  					     "insert_known_coin",  					     params); @@ -3407,7 +3392,6 @@ postgres_ensure_coin_known (void *cls,    }    if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)    { -    GNUNET_CRYPTO_rsa_public_key_free (known_coin.denom_pub.rsa_public_key);      GNUNET_CRYPTO_rsa_signature_free (known_coin.denom_sig.rsa_signature);      return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; /* no change! */    } @@ -3647,8 +3631,8 @@ postgres_get_melt (void *cls,      GNUNET_PQ_query_param_end    };    struct GNUNET_PQ_ResultSpec rs[] = { -    GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", -                                          &refresh_melt->session.coin.denom_pub.rsa_public_key), +    GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", +                                          &refresh_melt->session.coin.denom_pub_hash),      TALER_PQ_result_spec_amount ("fee_refresh",                                   &refresh_melt->melt_fee),      GNUNET_PQ_result_spec_rsa_signature ("denom_sig", @@ -4470,8 +4454,8 @@ add_coin_payback (void *cls,  					      &payback->coin_sig),  	TALER_PQ_result_spec_absolute_time ("timestamp",  					     &payback->timestamp), -	GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", -					      &payback->coin.denom_pub.rsa_public_key), +	GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", +					      &payback->coin.denom_pub_hash),  	GNUNET_PQ_result_spec_rsa_signature ("denom_sig",  					     &payback->coin.denom_sig.rsa_signature),  	GNUNET_PQ_result_spec_end @@ -6356,6 +6340,7 @@ payback_serial_helper_cb (void *cls,      struct TALER_CoinPublicInfo coin;      struct TALER_CoinSpendSignatureP coin_sig;      struct TALER_DenominationBlindingKeyP coin_blind; +    struct TALER_DenominationPublicKey denom_pub;      struct TALER_Amount amount;      struct GNUNET_HashCode h_blind_ev;      struct GNUNET_TIME_Absolute timestamp; @@ -6374,8 +6359,10 @@ payback_serial_helper_cb (void *cls,                                              &coin_blind),        GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",                                              &h_blind_ev), +      GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", +                                            &coin.denom_pub_hash),        GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", -                                            &coin.denom_pub.rsa_public_key), +                                           &denom_pub.rsa_public_key),        GNUNET_PQ_result_spec_rsa_signature ("denom_sig",                                             &coin.denom_sig.rsa_signature),        TALER_PQ_result_spec_amount ("amount", @@ -6399,6 +6386,7 @@ payback_serial_helper_cb (void *cls,  		   &amount,  		   &reserve_pub,  		   &coin, +                   &denom_pub,  		   &coin_sig,  		   &coin_blind);      GNUNET_PQ_cleanup_result (rs); diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index c8d4fa04..66ccb4c7 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -271,7 +271,7 @@ create_denom_key_pair (unsigned int size,    if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=        plugin->get_denomination_info (plugin->cls,                                       session, -                                     &dki.denom_pub, +                                     &dki.issue.properties.denom_hash,                                       &issue2))    {      GNUNET_break(0); @@ -574,7 +574,8 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)          GNUNET_CRYPTO_rsa_sign_fdh (dkp->priv.rsa_private_key,                                      &hc);      GNUNET_assert (NULL != refresh_session.coin.denom_sig.rsa_signature); -    refresh_session.coin.denom_pub = dkp->pub; +    GNUNET_CRYPTO_rsa_public_key_hash (dkp->pub.rsa_public_key, +                                       &refresh_session.coin.denom_pub_hash);      refresh_session.amount_with_fee = amount_with_fee;    } @@ -616,10 +617,9 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)                         &ret_refresh_session.session.coin.coin_pub,                         sizeof (refresh_session.coin.coin_pub)));    FAILIF (0 != -          GNUNET_CRYPTO_rsa_public_key_cmp (refresh_session.coin.denom_pub.rsa_public_key, -                                            ret_refresh_session.session.coin.denom_pub.rsa_public_key)); +          GNUNET_memcmp (&refresh_session.coin.denom_pub_hash, +                         &ret_refresh_session.session.coin.denom_pub_hash));    GNUNET_CRYPTO_rsa_signature_free (ret_refresh_session.session.coin.denom_sig.rsa_signature); -  GNUNET_CRYPTO_rsa_public_key_free (ret_refresh_session.session.coin.denom_pub.rsa_public_key);    /* test 'select_refreshs_above_serial_id' */    auditor_row_cnt = 0; @@ -1057,6 +1057,7 @@ test_gc (struct TALER_EXCHANGEDB_Session *session)    struct GNUNET_TIME_Absolute now;    struct GNUNET_TIME_Absolute past;    struct TALER_EXCHANGEDB_DenominationKeyInformationP issue2; +  struct GNUNET_HashCode denom_hash;    now = GNUNET_TIME_absolute_get ();    GNUNET_TIME_round_abs (&now); @@ -1079,10 +1080,13 @@ test_gc (struct TALER_EXCHANGEDB_Session *session)      destroy_denom_key_pair (dkp);      return GNUNET_SYSERR;    } +    GNUNET_CRYPTO_rsa_public_key_hash (dkp->pub.rsa_public_key, +                                       &denom_hash); +    if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=        plugin->get_denomination_info (plugin->cls,                                       session, -                                     &dkp->pub, +                                     &denom_hash,                                       &issue2))    {      GNUNET_break(0); @@ -1376,6 +1380,7 @@ payback_cb (void *cls,              const struct TALER_Amount *amount,              const struct TALER_ReservePublicKeyP *reserve_pub,              const struct TALER_CoinPublicInfo *coin, +            const struct TALER_DenominationPublicKey *denom_pub,              const struct TALER_CoinSpendSignatureP *coin_sig,              const struct TALER_DenominationBlindingKeyP *coin_blind)  { @@ -1700,7 +1705,7 @@ run (void *cls)                                       &dkp_pub_hash);    RND_BLK(&cbc.h_coin_envelope);    RND_BLK(&cbc.reserve_sig); -  cbc.denom_pub = dkp->pub; +  cbc.denom_pub_hash = dkp_pub_hash;    cbc.sig.rsa_signature      = GNUNET_CRYPTO_rsa_sign_fdh (dkp->priv.rsa_private_key,                                    &cbc.h_coin_envelope); @@ -1732,7 +1737,6 @@ run (void *cls)                                       session,                                       &cbc.h_coin_envelope,                                       &cbc2)); -  FAILIF (NULL == cbc2.denom_pub.rsa_public_key);    FAILIF(0 != GNUNET_memcmp(&cbc2.reserve_sig, &cbc.reserve_sig));    FAILIF(0 != GNUNET_memcmp(&cbc2.reserve_pub, &cbc.reserve_pub));    result = 6; @@ -1745,7 +1749,8 @@ run (void *cls)    RND_BLK (&coin_sig);    RND_BLK (&coin_blind);    RND_BLK (&deposit.coin.coin_pub); -  deposit.coin.denom_pub = dkp->pub; +  GNUNET_CRYPTO_rsa_public_key_hash (dkp->pub.rsa_public_key, +                                     &deposit.coin.denom_pub_hash);    deposit.coin.denom_sig = cbc.sig;    deadline = GNUNET_TIME_absolute_get ();    (void) GNUNET_TIME_round_abs (&deadline); @@ -1885,7 +1890,8 @@ run (void *cls)            0,            sizeof (deposit));    RND_BLK (&deposit.coin.coin_pub); -  deposit.coin.denom_pub = dkp->pub; +  GNUNET_CRYPTO_rsa_public_key_hash (dkp->pub.rsa_public_key, +                                     &deposit.coin.denom_pub_hash);    deposit.coin.denom_sig = cbc.sig;    RND_BLK (&deposit.csig);    RND_BLK (&deposit.merchant_pub); @@ -2259,8 +2265,6 @@ run (void *cls)      destroy_denom_key_pair (dkp);    if (NULL != cbc.sig.rsa_signature)      GNUNET_CRYPTO_rsa_signature_free (cbc.sig.rsa_signature); -  if (NULL != cbc2.denom_pub.rsa_public_key) -    GNUNET_CRYPTO_rsa_public_key_free (cbc2.denom_pub.rsa_public_key);    if (NULL != cbc2.sig.rsa_signature)      GNUNET_CRYPTO_rsa_signature_free (cbc2.sig.rsa_signature);    dkp = NULL; diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index f1251617..18c214e1 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -354,10 +354,10 @@ struct TALER_CoinPublicInfo    struct TALER_CoinSpendPublicKeyP coin_pub;    /** -   * Public key representing the denomination of the coin -   * that is being deposited. +   * Hash of the public key representing the denomination of the coin that is +   * being deposited.     */ -  struct TALER_DenominationPublicKey denom_pub; +  struct GNUNET_HashCode denom_pub_hash;    /**     * (Unblinded) signature over @e coin_pub with @e denom_pub, @@ -401,12 +401,14 @@ struct TALER_TrackTransferDetails   * is not expired, and the signature is correct.   *   * @param coin_public_info the coin public info to check for validity + * @param denom_pub denomination key, must match @a coin_public_info's `denom_pub_hash`   * @return #GNUNET_YES if the coin is valid,   *         #GNUNET_NO if it is invalid   *         #GNUNET_SYSERR if an internal error occured   */  int -TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info); +TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info, +                       const struct TALER_DenominationPublicKey *denom_pub);  GNUNET_NETWORK_STRUCT_BEGIN diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 2d9f1420..0a46c726 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -147,9 +147,9 @@ struct TALER_EXCHANGEDB_CollectableBlindcoin    struct TALER_DenominationSignature sig;    /** -   * Denomination key (which coin was generated). +   * Hash of the denomination key (which coin was generated).     */ -  struct TALER_DenominationPublicKey denom_pub; +  struct GNUNET_HashCode denom_pub_hash;    /**     * Value of the coin being exchangeed (matching the denomination key) @@ -1045,6 +1045,7 @@ typedef int                                      const struct TALER_Amount *amount,                                      const struct TALER_ReservePublicKeyP *reserve_pub,                                      const struct TALER_CoinPublicInfo *coin, +                                    const struct TALER_DenominationPublicKey *denom_pub,                                      const struct TALER_CoinSpendSignatureP *coin_sig,                                      const struct TALER_DenominationBlindingKeyP *coin_blind); @@ -1274,14 +1275,14 @@ struct TALER_EXCHANGEDB_Plugin     *     * @param cls the @e cls of this struct with the plugin-specific state     * @param session connection to use -   * @param denom_pub the public key used for signing coins of this denomination +   * @param denom_pub_hash hash of the public key used for signing coins of this denomination     * @param[out] issue set to issue information with value, fees and other info about the coin     * @return transaction status code     */    enum GNUNET_DB_QueryStatus    (*get_denomination_info) (void *cls,                              struct TALER_EXCHANGEDB_Session *session, -                            const struct TALER_DenominationPublicKey *denom_pub, +                            const struct GNUNET_HashCode *denom_pub_hash,                              struct TALER_EXCHANGEDB_DenominationKeyInformationP *issue); diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 8b20860b..0aa78d7b 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -27,7 +27,8 @@ libtalerexchange_la_SOURCES = \    exchange_api_reserve.c \    exchange_api_track_transaction.c \    exchange_api_track_transfer.c \ -  exchange_api_wire.c +  exchange_api_wire.c \ +  teah_common.c teah_common.h  libtalerexchange_la_LIBADD = \    libtalerauditor.la \    $(top_builddir)/src/json/libtalerjson.la \ @@ -46,7 +47,8 @@ libtalerauditor_la_SOURCES = \    auditor_api_curl_defaults.c auditor_api_curl_defaults.h \    auditor_api_handle.c auditor_api_handle.h \    auditor_api_deposit_confirmation.c \ -  auditor_api_exchanges.c +  auditor_api_exchanges.c \ +  teah_common.c teah_common.h  libtalerauditor_la_LIBADD = \    $(top_builddir)/src/json/libtalerjson.la \    $(top_builddir)/src/util/libtalerutil.la \ diff --git a/src/lib/auditor_api_curl_defaults.c b/src/lib/auditor_api_curl_defaults.c index d5b92400..507ae0e5 100644 --- a/src/lib/auditor_api_curl_defaults.c +++ b/src/lib/auditor_api_curl_defaults.c @@ -44,12 +44,10 @@ TAL_curl_easy_get (const char *url)                   curl_easy_setopt (eh,                                     CURLOPT_ENCODING,                                     "deflate")); -#ifdef CURLOPT_TCP_FASTOPEN    GNUNET_assert (CURLE_OK ==                   curl_easy_setopt (eh,                                     CURLOPT_TCP_FASTOPEN,                                     1L)); -#endif    {      /* Unfortunately libcurl needs chunk to be alive until after      curl_easy_perform.  To avoid manual cleanup, we keep diff --git a/src/lib/auditor_api_deposit_confirmation.c b/src/lib/auditor_api_deposit_confirmation.c index c34890e6..bb637797 100644 --- a/src/lib/auditor_api_deposit_confirmation.c +++ b/src/lib/auditor_api_deposit_confirmation.c @@ -49,9 +49,10 @@ struct TALER_AUDITOR_DepositConfirmationHandle    char *url;    /** -   * JSON encoding of the request to POST. +   * Context for #TEH_curl_easy_post(). Keeps the data that must +   * persist for Curl to make the upload.     */ -  char *json_enc; +  struct TEAH_PostContext ctx;    /**     * Handle for the request. @@ -338,26 +339,26 @@ TALER_AUDITOR_deposit_confirmation (struct TALER_AUDITOR_Handle *auditor,    dh->url = MAH_path_to_url (auditor, "/deposit-confirmation");    eh = TAL_curl_easy_get (dh->url); -  GNUNET_assert (NULL != (dh->json_enc = -                          json_dumps (deposit_confirmation_obj, -                                      JSON_COMPACT))); -  json_decref (deposit_confirmation_obj); -  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, -              "URL for deposit-confirmation: `%s'\n", -              dh->url); -    GNUNET_assert (CURLE_OK ==                   curl_easy_setopt (eh,                                     CURLOPT_CUSTOMREQUEST,                                     "PUT")); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDS, -                                   dh->json_enc)); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDSIZE, -                                   strlen (dh->json_enc))); +  if (GNUNET_OK != +      TEAH_curl_easy_post (&dh->ctx, +                           eh, +                           deposit_confirmation_obj)) +  { +    GNUNET_break (0); +    curl_easy_cleanup (eh); +    json_decref (deposit_confirmation_obj); +    GNUNET_free (dh->url); +    GNUNET_free (dh); +    return NULL; +  } +  json_decref (deposit_confirmation_obj); +  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, +              "URL for deposit-confirmation: `%s'\n", +              dh->url);    ctx = MAH_handle_to_context (auditor);    dh->job = GNUNET_CURL_job_add (ctx,  				 eh, @@ -383,7 +384,7 @@ TALER_AUDITOR_deposit_confirmation_cancel (struct TALER_AUDITOR_DepositConfirmat      deposit_confirmation->job = NULL;    }    GNUNET_free (deposit_confirmation->url); -  GNUNET_free (deposit_confirmation->json_enc); +  TEAH_curl_easy_post_finished (&deposit_confirmation->ctx);    GNUNET_free (deposit_confirmation);  } diff --git a/src/lib/auditor_api_handle.c b/src/lib/auditor_api_handle.c index 70bf6f71..870eed83 100644 --- a/src/lib/auditor_api_handle.c +++ b/src/lib/auditor_api_handle.c @@ -15,7 +15,7 @@    <http://www.gnu.org/licenses/>  */  /** - * @file auditor-lib/auditor_api_handle.c + * @file lib/auditor_api_handle.c   * @brief Implementation of the "handle" component of the auditor's HTTP API   * @author Sree Harsha Totakura <sreeharsha@totakura.in>   * @author Christian Grothoff @@ -462,6 +462,16 @@ TALER_AUDITOR_connect (struct GNUNET_CURL_Context *ctx,    GNUNET_log (GNUNET_ERROR_TYPE_INFO,                "Connecting to auditor at URL `%s'.\n",                url); +  /* Disable 100 continue processing */ +  GNUNET_break (GNUNET_OK == +                GNUNET_CURL_append_header (ctx, +                                           "Expect:")); +#if COMPRESS_BODIES +  /* Tell auditor we compress bodies */ +  GNUNET_break (GNUNET_OK == +                GNUNET_CURL_append_header (ctx, +                                           "Content-encoding: deflate")); +#endif    auditor = GNUNET_new (struct TALER_AUDITOR_Handle);    auditor->ctx = ctx;    auditor->url = GNUNET_strdup (url); diff --git a/src/lib/auditor_api_handle.h b/src/lib/auditor_api_handle.h index c3c73f5c..c053cbbc 100644 --- a/src/lib/auditor_api_handle.h +++ b/src/lib/auditor_api_handle.h @@ -22,7 +22,7 @@  #include "platform.h"  #include <gnunet/gnunet_curl_lib.h>  #include "taler_auditor_service.h" - +#include "teah_common.h"  /**   * Get the context of a auditor. diff --git a/src/lib/exchange_api_curl_defaults.c b/src/lib/exchange_api_curl_defaults.c index 3ac1dfdb..57fae166 100644 --- a/src/lib/exchange_api_curl_defaults.c +++ b/src/lib/exchange_api_curl_defaults.c @@ -49,11 +49,9 @@ TEL_curl_easy_get (const char *url)                   curl_easy_setopt (eh,                                     CURLOPT_FOLLOWLOCATION,                                     1L)); -#ifdef CURLOPT_TCP_FASTOPEN    GNUNET_assert (CURLE_OK ==                   curl_easy_setopt (eh,                                     CURLOPT_TCP_FASTOPEN,                                     1L)); -#endif    return eh;  } diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index 3f72ad95..b99c7a93 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -60,9 +60,10 @@ struct TALER_EXCHANGE_DepositHandle    char *url;    /** -   * JSON encoding of the request to POST. +   * Context for #TEH_curl_easy_post(). Keeps the data that must +   * persist for Curl to make the upload.     */ -  char *json_enc; +  struct TEAH_PostContext ctx;    /**     * Handle for the request. @@ -359,6 +360,7 @@ handle_deposit_finished (void *cls,   * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange)   * @param coin_pub coin’s public key   * @param denom_pub denomination key with which the coin is signed + * @param denom_pub_hash hash of @a denom_pub   * @param denom_sig exchange’s unblinded signature of the coin   * @param timestamp timestamp when the deposit was finalized   * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests) @@ -374,6 +376,7 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki,                     const struct TALER_CoinSpendPublicKeyP *coin_pub,                     const struct TALER_DenominationSignature *denom_sig,                     const struct TALER_DenominationPublicKey *denom_pub, +                   const struct GNUNET_HashCode *denom_pub_hash,                     struct GNUNET_TIME_Absolute timestamp,                     const struct TALER_MerchantPublicKeyP *merchant_pub,                     struct GNUNET_TIME_Absolute refund_deadline, @@ -414,10 +417,11 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki,    /* check coin signature */    coin_info.coin_pub = *coin_pub; -  coin_info.denom_pub = *denom_pub; +  coin_info.denom_pub_hash = *denom_pub_hash;    coin_info.denom_sig = *denom_sig;    if (GNUNET_YES != -      TALER_test_coin_valid (&coin_info)) +      TALER_test_coin_valid (&coin_info, +                             denom_pub))    {      GNUNET_break_op (0);      TALER_LOG_WARNING ("Invalid coin passed for /deposit\n"); @@ -489,6 +493,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange,    json_t *deposit_obj;    CURL *eh;    struct GNUNET_HashCode h_wire; +  struct GNUNET_HashCode denom_pub_hash;    struct TALER_Amount amount_without_fee;    (void) GNUNET_TIME_round_abs (&wire_deadline); @@ -512,6 +517,8 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange,  		 TALER_amount_subtract (&amount_without_fee,  					amount,  					&dki->fee_deposit)); +  GNUNET_CRYPTO_rsa_public_key_hash (denom_pub->rsa_public_key, +                                     &denom_pub_hash);    if (GNUNET_OK !=        verify_signatures (dki,                           amount, @@ -520,6 +527,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange,                           coin_pub,                           denom_sig,                           denom_pub, +                         &denom_pub_hash,                           timestamp,                           merchant_pub,                           refund_deadline, @@ -541,7 +549,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange,                             "H_wire", GNUNET_JSON_from_data_auto (&h_wire),                             "h_contract_terms", GNUNET_JSON_from_data_auto (h_contract_terms),                             "coin_pub", GNUNET_JSON_from_data_auto (coin_pub), -                           "denom_pub", GNUNET_JSON_from_rsa_public_key (denom_pub->rsa_public_key), +                           "denom_pub_hash", GNUNET_JSON_from_data_auto (&denom_pub_hash),                             "ub_sig", GNUNET_JSON_from_rsa_signature (denom_sig->rsa_signature),                             "timestamp", GNUNET_JSON_from_time_abs (timestamp),                             "merchant_pub", GNUNET_JSON_from_data_auto (merchant_pub), @@ -574,21 +582,22 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange,    dh->coin_value = dki->value;    eh = TEL_curl_easy_get (dh->url); -  GNUNET_assert (NULL != (dh->json_enc = -                          json_dumps (deposit_obj, -                                      JSON_COMPACT))); +  if (GNUNET_OK != +      TEAH_curl_easy_post (&dh->ctx, +                           eh, +                           deposit_obj)) +  { +    GNUNET_break (0); +    curl_easy_cleanup (eh); +    json_decref (deposit_obj); +    GNUNET_free (dh->url); +    GNUNET_free (dh); +    return NULL; +  }    json_decref (deposit_obj);    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,                "URL for deposit: `%s'\n",                dh->url); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDS, -                                   dh->json_enc)); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDSIZE, -                                   strlen (dh->json_enc)));    ctx = TEAH_handle_to_context (exchange);    dh->job = GNUNET_CURL_job_add (ctx,  				 eh, @@ -614,7 +623,7 @@ TALER_EXCHANGE_deposit_cancel (struct TALER_EXCHANGE_DepositHandle *deposit)      deposit->job = NULL;    }    GNUNET_free (deposit->url); -  GNUNET_free (deposit->json_enc); +  TEAH_curl_easy_post_finished (&deposit->ctx);    GNUNET_free (deposit);  } diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index cbcde724..0f3cfe0a 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -33,6 +33,7 @@  #include "exchange_api_handle.h"  #include "exchange_api_curl_defaults.h"  #include "backoff.h" +#include "teah_common.h"  /**   * Which revision of the Taler protocol is implemented @@ -432,7 +433,7 @@ parse_json_signkey (struct TALER_EXCHANGE_SigningPublicKey *sign_key,   */  static int  parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key, -		     int check_sigs, +                     int check_sigs,                       json_t *denom_key_obj,                       struct TALER_MasterPublicKeyP *master_key,                       struct GNUNET_HashContext *hash_context) @@ -1783,6 +1784,12 @@ TALER_EXCHANGE_connect    GNUNET_break (GNUNET_OK ==  		GNUNET_CURL_append_header (ctx,  					   "Expect:")); +#if COMPRESS_BODIES +  /* Tell exchange we compress bodies */ +  GNUNET_break (GNUNET_OK == +		GNUNET_CURL_append_header (ctx, +                                   "Content-encoding: deflate")); +#endif    exchange = GNUNET_new (struct TALER_EXCHANGE_Handle);    exchange->ctx = ctx;    exchange->url = GNUNET_strdup (url); @@ -1816,6 +1823,7 @@ TALER_EXCHANGE_connect  } +  /**   * Initiate download of /keys from the exchange.   * diff --git a/src/lib/exchange_api_handle.h b/src/lib/exchange_api_handle.h index 2c01e319..6bb3fff2 100644 --- a/src/lib/exchange_api_handle.h +++ b/src/lib/exchange_api_handle.h @@ -24,7 +24,7 @@  #include "taler_auditor_service.h"  #include "taler_exchange_service.h"  #include "taler_crypto_lib.h" - +#include "teah_common.h"  /**   * Entry in DLL of auditors used by an exchange. diff --git a/src/lib/exchange_api_payback.c b/src/lib/exchange_api_payback.c index 6c1772af..325263d7 100644 --- a/src/lib/exchange_api_payback.c +++ b/src/lib/exchange_api_payback.c @@ -49,9 +49,10 @@ struct TALER_EXCHANGE_PaybackHandle    char *url;    /** -   * JSON encoding of the request to POST. +   * Context for #TEH_curl_easy_post(). Keeps the data that must +   * persist for Curl to make the upload.     */ -  char *json_enc; +  struct TEAH_PostContext ctx;    /**     * Denomination key of the coin. @@ -280,6 +281,7 @@ TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange,    struct GNUNET_CURL_Context *ctx;    struct TALER_PaybackRequestPS pr;    struct TALER_CoinSpendSignatureP coin_sig; +  struct GNUNET_HashCode h_denom_pub;    json_t *payback_obj;    CURL *eh; @@ -289,6 +291,8 @@ TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange,    pr.purpose.size = htonl (sizeof (struct TALER_PaybackRequestPS));    GNUNET_CRYPTO_eddsa_key_get_public (&ps->coin_priv.eddsa_priv,                                        &pr.coin_pub.eddsa_pub); +  GNUNET_CRYPTO_rsa_public_key_hash (pk->key.rsa_public_key, +                                     &h_denom_pub);    pr.h_denom_pub = pk->h_key;    pr.coin_blind = ps->blinding_key;    GNUNET_assert (GNUNET_OK == @@ -299,7 +303,7 @@ TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange,    payback_obj = json_pack ("{s:o, s:o," /* denom pub/sig */                             " s:o, s:o," /* coin pub/sig */                             " s:o}", /* coin_bks */ -                           "denom_pub", GNUNET_JSON_from_rsa_public_key (pk->key.rsa_public_key), +                           "denom_pub_hash", GNUNET_JSON_from_data_auto (&h_denom_pub),                             "denom_sig", GNUNET_JSON_from_rsa_signature (denom_sig->rsa_signature),                             "coin_pub", GNUNET_JSON_from_data_auto (&pr.coin_pub),                             "coin_sig", GNUNET_JSON_from_data_auto (&coin_sig), @@ -318,29 +322,23 @@ TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange,    ph->cb = payback_cb;    ph->cb_cls = payback_cb_cls;    ph->url = TEAH_path_to_url (exchange, "/payback"); - -  ph->json_enc = json_dumps (payback_obj, -                             JSON_COMPACT); -  json_decref (payback_obj); -  if (NULL == ph->json_enc) +  eh = TEL_curl_easy_get (ph->url); +  if (GNUNET_OK != +      TEAH_curl_easy_post (&ph->ctx, +                           eh, +                           payback_obj))    {      GNUNET_break (0); +    curl_easy_cleanup (eh); +    json_decref (payback_obj);      GNUNET_free (ph->url);      GNUNET_free (ph);      return NULL;    } -  eh = TEL_curl_easy_get (ph->url); +  json_decref (payback_obj);    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,                "URL for payback: `%s'\n",                ph->url); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDS, -                                   ph->json_enc)); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDSIZE, -                                   strlen (ph->json_enc)));    ctx = TEAH_handle_to_context (exchange);    ph->job = GNUNET_CURL_job_add (ctx,  				 eh, @@ -366,7 +364,7 @@ TALER_EXCHANGE_payback_cancel (struct TALER_EXCHANGE_PaybackHandle *ph)      ph->job = NULL;    }    GNUNET_free (ph->url); -  GNUNET_free (ph->json_enc); +  TEAH_curl_easy_post_finished (&ph->ctx);    GNUNET_free (ph);  } diff --git a/src/lib/exchange_api_refresh.c b/src/lib/exchange_api_refresh.c index 230f445e..30025d77 100644 --- a/src/lib/exchange_api_refresh.c +++ b/src/lib/exchange_api_refresh.c @@ -834,9 +834,10 @@ struct TALER_EXCHANGE_RefreshMeltHandle    char *url;    /** -   * JSON encoding of the request to POST. +   * Context for #TEH_curl_easy_post(). Keeps the data that must +   * persist for Curl to make the upload.     */ -  char *json_enc; +  struct TEAH_PostContext ctx;    /**     * Handle for the request. @@ -1151,6 +1152,7 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,    struct MeltData *md;    struct TALER_CoinSpendSignatureP confirm_sig;    struct TALER_RefreshMeltCoinAffirmationPS melt; +  struct GNUNET_HashCode h_denom_pub;    GNUNET_assert (GNUNET_YES ==  		 TEAH_handle_is_ready (exchange)); @@ -1174,11 +1176,13 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,    GNUNET_CRYPTO_eddsa_sign (&md->melted_coin.coin_priv.eddsa_priv,                              &melt.purpose,                              &confirm_sig.eddsa_signature); +  GNUNET_CRYPTO_rsa_public_key_hash (md->melted_coin.pub_key.rsa_public_key, +                                     &h_denom_pub);    melt_obj = json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o}",                          "coin_pub",                          GNUNET_JSON_from_data_auto (&melt.coin_pub), -                        "denom_pub", -                        GNUNET_JSON_from_rsa_public_key (md->melted_coin.pub_key.rsa_public_key), +                        "denom_pub_hash", +                        GNUNET_JSON_from_data_auto (&h_denom_pub),                          "denom_sig",                          GNUNET_JSON_from_rsa_signature (md->melted_coin.sig.rsa_signature),                          "confirm_sig", @@ -1203,18 +1207,19 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,    rmh->url = TEAH_path_to_url (exchange,                                "/refresh/melt");    eh = TEL_curl_easy_get (rmh->url); -  GNUNET_assert (NULL != (rmh->json_enc = -                          json_dumps (melt_obj, -                                      JSON_COMPACT))); +  if (GNUNET_OK != +      TEAH_curl_easy_post (&rmh->ctx, +                           eh, +                           melt_obj)) +  { +    GNUNET_break (0); +    curl_easy_cleanup (eh); +    json_decref (melt_obj); +    GNUNET_free (rmh->url); +    GNUNET_free (rmh); +    return NULL; +  }    json_decref (melt_obj); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDS, -                                   rmh->json_enc)); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDSIZE, -                                   strlen (rmh->json_enc)));    ctx = TEAH_handle_to_context (exchange);    rmh->job = GNUNET_CURL_job_add (ctx,                            eh, @@ -1242,7 +1247,7 @@ TALER_EXCHANGE_refresh_melt_cancel (struct TALER_EXCHANGE_RefreshMeltHandle *rmh    free_melt_data (rmh->md); /* does not free 'md' itself */    GNUNET_free (rmh->md);    GNUNET_free (rmh->url); -  GNUNET_free (rmh->json_enc); +  TEAH_curl_easy_post_finished (&rmh->ctx);    GNUNET_free (rmh);  } @@ -1267,9 +1272,10 @@ struct TALER_EXCHANGE_RefreshRevealHandle    char *url;    /** -   * JSON encoding of the request to POST. +   * Context for #TEH_curl_easy_post(). Keeps the data that must +   * persist for Curl to make the upload.     */ -  char *json_enc; +  struct TEAH_PostContext ctx;    /**     * Handle for the request. @@ -1631,18 +1637,19 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange,                                "/refresh/reveal");    eh = TEL_curl_easy_get (rrh->url); -  GNUNET_assert (NULL != (rrh->json_enc = -                          json_dumps (reveal_obj, -                                      JSON_COMPACT))); +  if (GNUNET_OK != +      TEAH_curl_easy_post (&rrh->ctx, +                           eh, +                           reveal_obj)) +  { +    GNUNET_break (0); +    curl_easy_cleanup (eh); +    json_decref (reveal_obj); +    GNUNET_free (rrh->url); +    GNUNET_free (rrh); +    return NULL; +  }    json_decref (reveal_obj); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDS, -                                   rrh->json_enc)); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDSIZE, -                                   strlen (rrh->json_enc)));    ctx = TEAH_handle_to_context (rrh->exchange);    rrh->job = GNUNET_CURL_job_add (ctx,                                    eh, @@ -1668,7 +1675,7 @@ TALER_EXCHANGE_refresh_reveal_cancel (struct TALER_EXCHANGE_RefreshRevealHandle      rrh->job = NULL;    }    GNUNET_free (rrh->url); -  GNUNET_free (rrh->json_enc); +  TEAH_curl_easy_post_finished (&rrh->ctx);    free_melt_data (rrh->md); /* does not free 'md' itself */    GNUNET_free (rrh->md);    GNUNET_free (rrh); diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index 75ebdc4e..14221317 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -49,9 +49,10 @@ struct TALER_EXCHANGE_RefundHandle    char *url;    /** -   * JSON encoding of the request to POST. +   * Context for #TEH_curl_easy_post(). Keeps the data that must +   * persist for Curl to make the upload.     */ -  char *json_enc; +  struct TEAH_PostContext ctx;    /**     * Handle for the request. @@ -368,21 +369,22 @@ refund_obj = json_pack ("{s:o, s:o," /* amount/fee */                       refund_fee);    eh = TEL_curl_easy_get (rh->url); -  GNUNET_assert (NULL != (rh->json_enc = -                          json_dumps (refund_obj, -                                      JSON_COMPACT))); +  if (GNUNET_OK != +      TEAH_curl_easy_post (&rh->ctx, +                           eh, +                           refund_obj)) +  { +    GNUNET_break (0); +    curl_easy_cleanup (eh); +    json_decref (refund_obj); +    GNUNET_free (rh->url); +    GNUNET_free (rh); +    return NULL; +  }    json_decref (refund_obj);    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,                "URL for refund: `%s'\n",                rh->url); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDS, -                                   rh->json_enc)); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDSIZE, -                                   strlen (rh->json_enc)));    ctx = TEAH_handle_to_context (exchange);    rh->job = GNUNET_CURL_job_add (ctx,  				 eh, @@ -408,7 +410,7 @@ TALER_EXCHANGE_refund_cancel (struct TALER_EXCHANGE_RefundHandle *refund)      refund->job = NULL;    }    GNUNET_free (refund->url); -  GNUNET_free (refund->json_enc); +  TEAH_curl_easy_post_finished (&refund->ctx);    GNUNET_free (refund);  } diff --git a/src/lib/exchange_api_reserve.c b/src/lib/exchange_api_reserve.c index 4aa5794f..ae0bd01d 100644 --- a/src/lib/exchange_api_reserve.c +++ b/src/lib/exchange_api_reserve.c @@ -187,8 +187,8 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange,        struct GNUNET_JSON_Specification withdraw_spec[] = {          GNUNET_JSON_spec_fixed_auto ("reserve_sig",                                       &sig), -	TALER_JSON_spec_amount_nbo ("withdraw_fee", -				    &withdraw_purpose.withdraw_fee), +        TALER_JSON_spec_amount_nbo ("withdraw_fee", +                                    &withdraw_purpose.withdraw_fee),          GNUNET_JSON_spec_fixed_auto ("h_denom_pub",                                       &withdraw_purpose.h_denomination_pub),          GNUNET_JSON_spec_fixed_auto ("h_coin_envelope", @@ -677,9 +677,10 @@ struct TALER_EXCHANGE_ReserveWithdrawHandle    char *url;    /** -   * JSON encoding of the request to POST. +   * Context for #TEH_curl_easy_post(). Keeps the data that must +   * persist for Curl to make the upload.     */ -  char *json_enc; +  struct TEAH_PostContext ctx;    /**     * Handle for the request. @@ -1001,6 +1002,7 @@ reserve_withdraw_internal (struct TALER_EXCHANGE_Handle *exchange,    struct GNUNET_CURL_Context *ctx;    json_t *withdraw_obj;    CURL *eh; +  struct GNUNET_HashCode h_denom_pub;    wsh = GNUNET_new (struct TALER_EXCHANGE_ReserveWithdrawHandle);    wsh->exchange = exchange; @@ -1009,9 +1011,11 @@ reserve_withdraw_internal (struct TALER_EXCHANGE_Handle *exchange,    wsh->pk = pk;    wsh->reserve_pub = *reserve_pub;    wsh->c_hash = pd->c_hash; -  withdraw_obj = json_pack ("{s:o, s:o," /* denom_pub and coin_ev */ +  GNUNET_CRYPTO_rsa_public_key_hash (pk->key.rsa_public_key, +                                     &h_denom_pub); +  withdraw_obj = json_pack ("{s:o, s:o," /* denom_pub_hash and coin_ev */                              " s:o, s:o}",/* reserve_pub and reserve_sig */ -                            "denom_pub", GNUNET_JSON_from_rsa_public_key (pk->key.rsa_public_key), +                            "denom_pub_hash", GNUNET_JSON_from_data_auto (&h_denom_pub),                              "coin_ev", GNUNET_JSON_from_data (pd->coin_ev,                                                                pd->coin_ev_size),                              "reserve_pub", GNUNET_JSON_from_data_auto (reserve_pub), @@ -1019,25 +1023,26 @@ reserve_withdraw_internal (struct TALER_EXCHANGE_Handle *exchange,    if (NULL == withdraw_obj)    {      GNUNET_break (0); +    GNUNET_free (wsh);      return NULL;    }    wsh->ps = *ps;    wsh->url = TEAH_path_to_url (exchange, "/reserve/withdraw"); -    eh = TEL_curl_easy_get (wsh->url); -  GNUNET_assert (NULL != (wsh->json_enc = -                          json_dumps (withdraw_obj, -                                      JSON_COMPACT))); +  if (GNUNET_OK != +      TEAH_curl_easy_post (&wsh->ctx, +                           eh, +                           withdraw_obj)) +  { +    GNUNET_break (0); +    curl_easy_cleanup (eh); +    json_decref (withdraw_obj); +    GNUNET_free (wsh->url); +    GNUNET_free (wsh); +    return NULL; +  }    json_decref (withdraw_obj); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDS, -                                   wsh->json_enc)); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDSIZE, -                                   strlen (wsh->json_enc)));    ctx = TEAH_handle_to_context (exchange);    wsh->job = GNUNET_CURL_job_add (ctx,                            eh, @@ -1196,7 +1201,7 @@ TALER_EXCHANGE_reserve_withdraw_cancel (struct TALER_EXCHANGE_ReserveWithdrawHan      sign->job = NULL;    }    GNUNET_free (sign->url); -  GNUNET_free (sign->json_enc); +  TEAH_curl_easy_post_finished (&sign->ctx);    GNUNET_free (sign);  } diff --git a/src/lib/exchange_api_track_transaction.c b/src/lib/exchange_api_track_transaction.c index 0942ce84..67efd77a 100644 --- a/src/lib/exchange_api_track_transaction.c +++ b/src/lib/exchange_api_track_transaction.c @@ -49,9 +49,10 @@ struct TALER_EXCHANGE_TrackTransactionHandle    char *url;    /** -   * JSON encoding of the request to POST. +   * Context for #TEH_curl_easy_post(). Keeps the data that must +   * persist for Curl to make the upload.     */ -  char *json_enc; +  struct TEAH_PostContext ctx;    /**     * Handle for the request. @@ -322,18 +323,19 @@ TALER_EXCHANGE_track_transaction (struct TALER_EXCHANGE_Handle *exchange,    dwh->depconf.coin_pub = *coin_pub;    eh = TEL_curl_easy_get (dwh->url); -  GNUNET_assert (NULL != (dwh->json_enc = -                          json_dumps (deposit_wtid_obj, -                                      JSON_COMPACT))); +  if (GNUNET_OK != +      TEAH_curl_easy_post (&dwh->ctx, +                           eh, +                           deposit_wtid_obj)) +  { +    GNUNET_break (0); +    curl_easy_cleanup (eh); +    json_decref (deposit_wtid_obj); +    GNUNET_free (dwh->url); +    GNUNET_free (dwh); +    return NULL; +  }    json_decref (deposit_wtid_obj); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDS, -                                   dwh->json_enc)); -  GNUNET_assert (CURLE_OK == -                 curl_easy_setopt (eh, -                                   CURLOPT_POSTFIELDSIZE, -                                   strlen (dwh->json_enc)));    ctx = TEAH_handle_to_context (exchange);    dwh->job = GNUNET_CURL_job_add (ctx,                            eh, @@ -359,9 +361,9 @@ TALER_EXCHANGE_track_transaction_cancel (struct TALER_EXCHANGE_TrackTransactionH      dwh->job = NULL;    }    GNUNET_free (dwh->url); -  GNUNET_free (dwh->json_enc); +  TEAH_curl_easy_post_finished (&dwh->ctx);    GNUNET_free (dwh);  } -/* end of exchange_api_deposit_wtid.c */ +/* end of exchange_api_track_transaction.c */ diff --git a/src/lib/teah_common.c b/src/lib/teah_common.c new file mode 100644 index 00000000..8f994ef3 --- /dev/null +++ b/src/lib/teah_common.c @@ -0,0 +1,105 @@ +/* +  This file is part of TALER +  Copyright (C) 2019 GNUnet e.V. + +  TALER is free software; you can redistribute it and/or modify it +  under the terms of the GNU General Public License as published +  by the Free Software Foundation; either version 3, or (at your +  option) any later version. + +  TALER is distributed in the hope that it will be useful, but +  WITHOUT ANY WARRANTY; without even the implied warranty of +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +  GNU General Public License for more details. + +  You should have received a copy of the GNU General Public +  License along with TALER; see the file COPYING.  If not, see +  <http://www.gnu.org/licenses/> +*/ + +/** + * @file lib/teah_common.c + * @brief Helper routines shared by libtalerexchange and libtalerauditor + * @author Christian Grothoff + */ +#include "platform.h" +#include "teah_common.h" + +#if COMPRESS_BODIES +#include <zlib.h> +#endif + + +/** + * Add the @a body as POST data to the easy handle in + * @a ctx. + * + * @param ctx[in,out] a request context (updated) + * @param eh easy handle to use + * @param body JSON body to add to @e ctx + * @return #GNUNET_OK on success #GNUNET_SYSERR on failure + */ +int +TEAH_curl_easy_post (struct TEAH_PostContext *ctx, +                     CURL *eh, +                     const json_t *body) +{ +  char *str; +  size_t slen; + +  str = json_dumps (body, +                    JSON_COMPACT); +  if (NULL == str) +  { +    GNUNET_break (0); +    return GNUNET_SYSERR; +  } +  slen = strlen (str); +#if COMPRESS_BODIES +  { +    Bytef *cbuf; +    uLongf cbuf_size; +    int ret; + +    cbuf_size = compressBound (slen); +    cbuf = GNUNET_malloc (cbuf_size); +    ret = compress (cbuf, +                    &cbuf_size, +                    (const Bytef *) str, +                    slen); +    if (Z_OK != ret) +    { +      /* compression failed!? */ +      GNUNET_break (0); +      GNUNET_free (cbuf); +      return GNUNET_SYSERR; +    } +    free (str); +    slen = (size_t) cbuf_size; +    ctx->json_enc = (char *) cbuf; +  } +#else +  ctx->json_enc = str; +#endif +  GNUNET_assert (CURLE_OK == +                 curl_easy_setopt (eh, +                                   CURLOPT_POSTFIELDS, +                                   ctx->json_enc)); +  GNUNET_assert (CURLE_OK == +                 curl_easy_setopt (eh, +                                   CURLOPT_POSTFIELDSIZE, +                                   slen)); +  return GNUNET_OK; +} + + +/** + * Free the data in @a ctx. + * + * @param ctx[in] a request context (updated) + */ +void +TEAH_curl_easy_post_finished (struct TEAH_PostContext *ctx) +{ +  GNUNET_free_non_null (ctx->json_enc); +} diff --git a/src/lib/teah_common.h b/src/lib/teah_common.h new file mode 100644 index 00000000..66937a26 --- /dev/null +++ b/src/lib/teah_common.h @@ -0,0 +1,74 @@ +/* +  This file is part of TALER +  Copyright (C) 2019 GNUnet e.V. + +  TALER is free software; you can redistribute it and/or modify it +  under the terms of the GNU General Public License as published +  by the Free Software Foundation; either version 3, or (at your +  option) any later version. + +  TALER is distributed in the hope that it will be useful, but +  WITHOUT ANY WARRANTY; without even the implied warranty of +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +  GNU General Public License for more details. + +  You should have received a copy of the GNU General Public +  License along with TALER; see the file COPYING.  If not, see +  <http://www.gnu.org/licenses/> +*/ +/** + * @file lib/teah_common.h + * @brief Helper routines shared by libtalerexchange and libtalerauditor + * @author Christian Grothoff + */ +#ifndef TEAH_COMMON_H +#define TEAH_COMMON_H + +#include <gnunet/gnunet_curl_lib.h> +#include "taler_json_lib.h" + +/** + * Should we compress PUT/POST bodies with 'deflate' encoding? + */ +#define COMPRESS_BODIES 0 + +/** + * State used for #TEAL_curl_easy_post() and + * #TEAL_curl_easy_post_finished(). + */ +struct TEAH_PostContext +{ +  /** +   * JSON encoding of the request to POST. +   */ +  char *json_enc; + +}; + + +/** + * Add the @a body as POST data to the easy handle in + * @a ctx. + * + * @param ctx[in,out] a request context (updated) + * @param eh easy handle to use + * @param body JSON body to add to @e ctx + * @return #GNUNET_OK on success #GNUNET_SYSERR on failure + */ +int +TEAH_curl_easy_post (struct TEAH_PostContext *ctx, +                     CURL *eh, +                     const json_t *body); + + +/** + * Free the data in @a ctx. + * + * @param ctx[in] a request context (updated) + */ +void +TEAH_curl_easy_post_finished (struct TEAH_PostContext *ctx); + + + +#endif diff --git a/src/util/crypto.c b/src/util/crypto.c index b44c31ff..95eb11eb 100644 --- a/src/util/crypto.c +++ b/src/util/crypto.c @@ -77,22 +77,33 @@ TALER_gcrypt_init ()   * is not expired, and the signature is correct.   *   * @param coin_public_info the coin public info to check for validity + * @param denom_pub denomination key, must match @a coin_public_info's `denom_pub_hash`   * @return #GNUNET_YES if the coin is valid,   *         #GNUNET_NO if it is invalid   *         #GNUNET_SYSERR if an internal error occured   */  int -TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info) +TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info, +                       const struct TALER_DenominationPublicKey *denom_pub)  {    struct GNUNET_HashCode c_hash; - +#if 1 /* sanity check of invariant, could probably be disabled in production +         for slightly more performance */ +  struct GNUNET_HashCode d_hash; + +  GNUNET_CRYPTO_rsa_public_key_hash (denom_pub->rsa_public_key, +                                     &d_hash); +  GNUNET_assert (0 == +                 GNUNET_memcmp (&d_hash, +                                &coin_public_info->denom_pub_hash)); +#endif    GNUNET_CRYPTO_hash (&coin_public_info->coin_pub,                        sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),                        &c_hash);    if (GNUNET_OK !=        GNUNET_CRYPTO_rsa_verify (&c_hash,                                  coin_public_info->denom_sig.rsa_signature, -                                coin_public_info->denom_pub.rsa_public_key)) +                                denom_pub->rsa_public_key))    {      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,                  "coin signature is invalid\n");  | 
