diff options
| author | Christian Grothoff <christian@grothoff.org> | 2015-03-18 18:55:41 +0100 | 
|---|---|---|
| committer | Christian Grothoff <christian@grothoff.org> | 2015-03-18 18:55:41 +0100 | 
| commit | 23bf1eee74bed73cf98264c247ab44df8dadfcd9 (patch) | |
| tree | 3d7fcba4b6fb8a84b79585b4fa6ccdf0fff6ade4 /src/mint | |
| parent | 08958c73e8ba6ad30e98a30968077cdf55bc86e8 (diff) | |
fix #3716: make sure amount-API offers proper checks against overflow and other issues
Diffstat (limited to 'src/mint')
| -rw-r--r-- | src/mint/mint_db.c | 25 | ||||
| -rw-r--r-- | src/mint/mint_db.h | 2 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_db.c | 143 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_deposit.c | 3 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_keystate.c | 21 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_parsing.c | 14 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_refresh.c | 40 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_responses.c | 68 | ||||
| -rw-r--r-- | src/mint/taler-mint-keyup.c | 27 | ||||
| -rw-r--r-- | src/mint/taler-mint-reservemod.c | 8 | 
10 files changed, 237 insertions, 114 deletions
| diff --git a/src/mint/mint_db.c b/src/mint/mint_db.c index 6ed7193e..545a5252 100644 --- a/src/mint/mint_db.c +++ b/src/mint/mint_db.c @@ -807,7 +807,8 @@ reserves_update (PGconn *db,      TALER_DB_QUERY_PARAM_PTR (&expiry_nbo),      TALER_DB_QUERY_PARAM_END    }; -  balance_nbo = TALER_amount_hton (reserve->balance); +  TALER_amount_hton (&balance_nbo, +                     &reserve->balance);    expiry_nbo = GNUNET_TIME_absolute_hton (reserve->expiry);    result = TALER_DB_exec_prepared (db,                                     "update_reserve", @@ -837,7 +838,7 @@ reserves_update (PGconn *db,  int  TALER_MINT_DB_reserves_in_insert (PGconn *db,                                    struct Reserve *reserve, -                                  const struct TALER_Amount balance, +                                  const struct TALER_Amount *balance,                                    const struct GNUNET_TIME_Absolute expiry)  {    struct TALER_AmountNBO balance_nbo; @@ -862,7 +863,8 @@ TALER_MINT_DB_reserves_in_insert (PGconn *db,      TALER_MINT_DB_rollback (db);      return GNUNET_SYSERR;    } -  balance_nbo = TALER_amount_hton (balance); +  TALER_amount_hton (&balance_nbo, +                     balance);    expiry_nbo = GNUNET_TIME_absolute_hton (expiry);    if (GNUNET_NO == reserve_exists)    { @@ -907,19 +909,27 @@ TALER_MINT_DB_reserves_in_insert (PGconn *db,      QUERY_ERR (result);      goto rollback;    } -  PQclear (result); result = NULL; +  PQclear (result); +  result = NULL;    if (GNUNET_NO == reserve_exists)    {      if (GNUNET_OK != TALER_MINT_DB_commit (db))        return GNUNET_SYSERR; -    reserve->balance = balance; +    reserve->balance = *balance;      reserve->expiry = expiry;      return GNUNET_OK;    }    /* Update reserve */    struct Reserve updated_reserve;    updated_reserve.pub = reserve->pub; -  updated_reserve.balance = TALER_amount_add (reserve->balance, balance); + +  if (GNUNET_OK != +      TALER_amount_add (&updated_reserve.balance, +                        &reserve->balance, +                        balance)) +  { +    return GNUNET_SYSERR; +  }    updated_reserve.expiry = GNUNET_TIME_absolute_max (expiry, reserve->expiry);    if (GNUNET_OK != reserves_update (db, &updated_reserve))      goto rollback; @@ -1350,7 +1360,8 @@ TALER_MINT_DB_insert_deposit (PGconn *db_conn,        GNUNET_CRYPTO_rsa_signature_encode (deposit->coin.denom_sig,                                            &denom_sig_enc);    json_wire_enc = json_dumps (deposit->wire, JSON_COMPACT); -  amount_nbo = TALER_amount_hton (deposit->amount); +  TALER_amount_hton (&amount_nbo, +                     &deposit->amount);    struct TALER_DB_QueryParam params[]= {      TALER_DB_QUERY_PARAM_PTR (&deposit->coin.coin_pub),      TALER_DB_QUERY_PARAM_PTR_SIZED (denom_pub_enc, denom_pub_enc_size), diff --git a/src/mint/mint_db.h b/src/mint/mint_db.h index 4a9ec152..9312f548 100644 --- a/src/mint/mint_db.h +++ b/src/mint/mint_db.h @@ -224,7 +224,7 @@ TALER_MINT_DB_reserve_get (PGconn *db,  int  TALER_MINT_DB_reserves_in_insert (PGconn *db,                                    struct Reserve *reserve, -                                  const struct TALER_Amount balance, +                                  const struct TALER_Amount *balance,                                    const struct GNUNET_TIME_Absolute expiry); diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index df68b657..05c2a48a 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -35,26 +35,6 @@  /** - * Get an amount in the mint's currency that is zero. - * - * @return zero amount in the mint's currency - */ -static struct TALER_Amount -mint_amount_native_zero () -{ -  struct TALER_Amount amount; - -  memset (&amount, -          0, -          sizeof (amount)); -  memcpy (amount.currency, -          MINT_CURRENCY, -          strlen (MINT_CURRENCY) + 1); -  return amount; -} - - -/**   * Execute a deposit.  The validity of the coin and signature   * have already been checked.  The database must now check that   * the coin is not (double or over) spent, and execute the @@ -99,9 +79,12 @@ TALER_MINT_db_execute_deposit (struct MHD_Connection *connection,    mks = TALER_MINT_key_state_acquire ();    dki = TALER_MINT_get_denom_key (mks,                                    deposit->coin.denom_pub); -  value = TALER_amount_ntoh (dki->issue.value); -  fee_deposit = TALER_amount_ntoh (dki->issue.fee_deposit); -  fee_refresh = TALER_amount_ntoh (dki->issue.fee_refresh); +  TALER_amount_ntoh (&value, +                     &dki->issue.value); +  TALER_amount_ntoh (&fee_deposit, +                     &dki->issue.fee_deposit); +  TALER_amount_ntoh (&fee_refresh, +                     &dki->issue.fee_refresh);    TALER_MINT_key_state_release (mks);    if (GNUNET_OK != @@ -113,26 +96,49 @@ TALER_MINT_db_execute_deposit (struct MHD_Connection *connection,    tl = TALER_MINT_DB_get_coin_transactions (db_conn,                                              &deposit->coin.coin_pub);    spent = fee_deposit; /* fee for THIS transaction */ -  /* FIXME: need to deal better with integer overflows -     in the logic that follows! (change amount.c API! -- #3637) */ -  spent = TALER_amount_add (spent, -                            deposit->amount); +  if (GNUNET_OK != +      TALER_amount_add (&spent, +                        &spent, +                        &deposit->amount)) +  { +    GNUNET_break (0); +    TALER_MINT_DB_free_coin_transaction_list (tl); +    return TALER_MINT_reply_internal_db_error (connection); +  }    for (pos = tl; NULL != pos; pos = pos->next)    {      switch (pos->type)      {      case TALER_MINT_DB_TT_DEPOSIT: -      spent = TALER_amount_add (spent, -                                pos->details.deposit->amount); -      spent = TALER_amount_add (spent, -                                fee_deposit); +      if ( (GNUNET_OK != +            TALER_amount_add (&spent, +                              &spent, +                              &pos->details.deposit->amount)) || +           (GNUNET_OK != +            TALER_amount_add (&spent, +                              &spent, +                              &fee_deposit)) ) +      { +        GNUNET_break (0); +        TALER_MINT_DB_free_coin_transaction_list (tl); +        return TALER_MINT_reply_internal_db_error (connection); +      }        break;      case TALER_MINT_DB_TT_REFRESH_MELT: -      spent = TALER_amount_add (spent, -                                pos->details.melt->amount); -      spent = TALER_amount_add (spent, -                                fee_refresh); +      if ( (GNUNET_OK != +            TALER_amount_add (&spent, +                              &spent, +                              &pos->details.melt->amount)) || +           (GNUNET_OK != +            TALER_amount_add (&spent, +                              &spent, +                              &fee_refresh)) ) +      { +        GNUNET_break (0); +        TALER_MINT_DB_free_coin_transaction_list (tl); +        return TALER_MINT_reply_internal_db_error (connection); +      }        break;      case TALER_MINT_DB_TT_LOCK:        /* should check if lock is still active, @@ -146,11 +152,12 @@ TALER_MINT_db_execute_deposit (struct MHD_Connection *connection,      }    } -  if (0 < TALER_amount_cmp (spent, value)) +  if (0 < TALER_amount_cmp (&spent, +                            &value))    {      TALER_MINT_DB_rollback (db_conn);      ret = TALER_MINT_reply_deposit_insufficient_funds (connection, -                                               tl); +                                                       tl);      TALER_MINT_DB_free_coin_transaction_list (tl);      return ret;    } @@ -251,6 +258,7 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,    struct TALER_Amount withdraw_total;    struct TALER_Amount balance;    struct TALER_Amount value; +  struct TALER_Amount fee_withdraw;    struct GNUNET_HashCode h_blind;    int res; @@ -318,8 +326,20 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,    }    /* calculate amount required including fees */ -  amount_required = TALER_amount_add (TALER_amount_ntoh (dki->issue.value), -                                      TALER_amount_ntoh (dki->issue.fee_withdraw)); +  TALER_amount_ntoh (&value, +                     &dki->issue.value); +  TALER_amount_ntoh (&fee_withdraw, +                     &dki->issue.fee_withdraw); + +  if (GNUNET_OK != +      TALER_amount_add (&amount_required, +                        &value, +                        &fee_withdraw)) +  { +    TALER_MINT_DB_rollback (db_conn); +    TALER_MINT_key_state_release (key_state); +    return TALER_MINT_reply_internal_db_error (connection); +  }    /* calculate balance of the reserve */    res = 0; @@ -331,29 +351,45 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,        if (0 == (res & 1))          deposit_total = pos->details.bank->amount;        else -        deposit_total = TALER_amount_add (deposit_total, -                                          pos->details.bank->amount); +        if (GNUNET_OK != +            TALER_amount_add (&deposit_total, +                              &deposit_total, +                              &pos->details.bank->amount)) +        { +          TALER_MINT_DB_rollback (db_conn); +          TALER_MINT_key_state_release (key_state); +          return TALER_MINT_reply_internal_db_error (connection); +        }        res |= 1;        break;      case TALER_MINT_DB_RO_WITHDRAW_COIN:        tdki = TALER_MINT_get_denom_key (key_state,                                         pos->details.withdraw->denom_pub); -      value = TALER_amount_ntoh (tdki->issue.value); +      TALER_amount_ntoh (&value, +                         &tdki->issue.value);        if (0 == (res & 2))          withdraw_total = value;        else -        withdraw_total = TALER_amount_add (withdraw_total, -                                           value); +        if (GNUNET_OK != +            TALER_amount_add (&withdraw_total, +                              &withdraw_total, +                              &value)) +        { +          TALER_MINT_DB_rollback (db_conn); +          TALER_MINT_key_state_release (key_state); +          return TALER_MINT_reply_internal_db_error (connection); +        }        res |= 2;        break;      }    } -  GNUNET_break (0 > TALER_amount_cmp (withdraw_total, -                                      deposit_total)); -  balance = TALER_amount_subtract (deposit_total, -                                   withdraw_total); -  if (0 < TALER_amount_cmp (amount_required, -                            balance)) +  /* All reserve balances should be non-negative */ +  GNUNET_break (GNUNET_SYSERR != +                TALER_amount_subtract (&balance, +                                       &deposit_total, +                                       &withdraw_total)); +  if (0 < TALER_amount_cmp (&amount_required, +                            &balance))    {      TALER_MINT_key_state_release (key_state);      TALER_MINT_DB_rollback (db_conn); @@ -450,7 +486,8 @@ refresh_accept_melts (struct MHD_Connection *connection,                                          "denom not found"))        ? GNUNET_NO : GNUNET_SYSERR; -  coin_value = TALER_amount_ntoh (dki->value); +  TALER_amount_ntoh (&coin_value, +                     &dki->value);    tl = TALER_MINT_DB_get_coin_transactions (db_conn,                                              &coin_public_info->coin_pub);    /* FIXME: #3636: compute how much value is left with this coin and @@ -459,8 +496,8 @@ refresh_accept_melts (struct MHD_Connection *connection,    /* Refuse to refresh when the coin does not have enough money left to     * pay the refreshing fees of the coin. */ -  if (TALER_amount_cmp (coin_residual, -                        coin_details->melt_amount) < 0) +  if (TALER_amount_cmp (&coin_residual, +                        &coin_details->melt_amount) < 0)    {      res = (MHD_YES ==             TALER_MINT_reply_refresh_melt_insufficient_funds (connection, diff --git a/src/mint/taler-mint-httpd_deposit.c b/src/mint/taler-mint-httpd_deposit.c index d37e69e4..37d6d23d 100644 --- a/src/mint/taler-mint-httpd_deposit.c +++ b/src/mint/taler-mint-httpd_deposit.c @@ -65,7 +65,8 @@ verify_and_execute_deposit (struct MHD_Connection *connection,    dr.h_contract = deposit->h_contract;    dr.h_wire = deposit->h_wire;    dr.transaction_id = GNUNET_htonll (deposit->transaction_id); -  dr.amount = TALER_amount_hton (deposit->amount); +  TALER_amount_hton (&dr.amount, +                     &deposit->amount);    dr.coin_pub = deposit->coin.coin_pub;    if (GNUNET_OK !=        GNUNET_CRYPTO_ecdsa_verify (TALER_SIGNATURE_WALLET_DEPOSIT, diff --git a/src/mint/taler-mint-httpd_keystate.c b/src/mint/taler-mint-httpd_keystate.c index bf802f5b..ca802e2d 100644 --- a/src/mint/taler-mint-httpd_keystate.c +++ b/src/mint/taler-mint-httpd_keystate.c @@ -114,6 +114,19 @@ static json_t *  denom_key_issue_to_json (struct GNUNET_CRYPTO_rsa_PublicKey *pk,                           const struct TALER_MINT_DenomKeyIssue *dki)  { +  struct TALER_Amount value; +  struct TALER_Amount fee_withdraw; +  struct TALER_Amount fee_deposit; +  struct TALER_Amount fee_refresh; + +  TALER_amount_ntoh (&value, +                     &dki->value); +  TALER_amount_ntoh (&fee_withdraw, +                     &dki->fee_withdraw); +  TALER_amount_ntoh (&fee_deposit, +                     &dki->fee_deposit); +  TALER_amount_ntoh (&fee_refresh, +                     &dki->fee_refresh);    return      json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}",                 "master_sig", @@ -128,13 +141,13 @@ denom_key_issue_to_json (struct GNUNET_CRYPTO_rsa_PublicKey *pk,                 "denom_pub",                 TALER_JSON_from_rsa_public_key (pk),                 "value", -               TALER_JSON_from_amount (TALER_amount_ntoh (dki->value)), +               TALER_JSON_from_amount (&value),                 "fee_withdraw", -               TALER_JSON_from_amount (TALER_amount_ntoh (dki->fee_withdraw)), +               TALER_JSON_from_amount (&fee_withdraw),                 "fee_deposit", -               TALER_JSON_from_amount (TALER_amount_ntoh (dki->fee_deposit)), +               TALER_JSON_from_amount (&fee_deposit),                 "fee_refresh", -               TALER_JSON_from_amount (TALER_amount_ntoh (dki->fee_refresh))); +               TALER_JSON_from_amount (&fee_refresh));  } diff --git a/src/mint/taler-mint-httpd_parsing.c b/src/mint/taler-mint-httpd_parsing.c index 6c5f72b3..b8bc043e 100644 --- a/src/mint/taler-mint-httpd_parsing.c +++ b/src/mint/taler-mint-httpd_parsing.c @@ -878,8 +878,10 @@ TALER_MINT_parse_amount_json (struct MHD_Connection *connection,    json_int_t value;    json_int_t fraction;    const char *currency; -  struct TALER_Amount a; +  memset (amount, +          0, +          sizeof (struct TALER_Amount));    if (-1 == json_unpack (f,                           "{s:I, s:I, s:s}",                           "value", &value, @@ -897,7 +899,7 @@ TALER_MINT_parse_amount_json (struct MHD_Connection *connection,    }    if ( (value < 0) ||         (fraction < 0) || -       (value > UINT32_MAX) || +       (value > UINT64_MAX) ||         (fraction > UINT32_MAX) )    {      LOG_WARNING ("Amount specified not in allowed range\n"); @@ -922,11 +924,11 @@ TALER_MINT_parse_amount_json (struct MHD_Connection *connection,        return GNUNET_SYSERR;      return GNUNET_NO;    } -  a.value = (uint32_t) value; -  a.fraction = (uint32_t) fraction; +  amount->value = (uint64_t) value; +  amount->fraction = (uint32_t) fraction;    GNUNET_assert (strlen (MINT_CURRENCY) < TALER_CURRENCY_LEN); -  strcpy (a.currency, MINT_CURRENCY); -  *amount = TALER_amount_normalize (a); +  strcpy (amount->currency, MINT_CURRENCY); +  TALER_amount_normalize (amount);    return GNUNET_OK;  } diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c index c7bda5a7..e62521ef 100644 --- a/src/mint/taler-mint-httpd_refresh.c +++ b/src/mint/taler-mint-httpd_refresh.c @@ -82,6 +82,8 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,    struct TALER_Amount cost;    struct TALER_Amount total_cost;    struct TALER_Amount melt; +  struct TALER_Amount value; +  struct TALER_Amount fee_withdraw;    struct TALER_Amount total_melt;    /* check that signature from the session public key is ok */ @@ -107,7 +109,8 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,    body.purpose.purpose = htonl (TALER_SIGNATURE_REFRESH_MELT_SESSION);    body.purpose.size = htonl (sizeof (struct RefreshMeltSessionSignature));    body.melt_hash = melt_hash; -  body.amount = TALER_amount_hton (coin_melt_details->melt_amount); +  TALER_amount_hton (&body.amount, +                     &coin_melt_details->melt_amount);    if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_REFRESH_MELT_SESSION,                                                 &body.purpose, @@ -130,11 +133,22 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,    {      dki = &TALER_MINT_get_denom_key (key_state,                                       denom_pubs[i])->issue; -    cost = TALER_amount_add (TALER_amount_ntoh (dki->value), -                             TALER_amount_ntoh (dki->fee_withdraw)); +    TALER_amount_ntoh (&value, +                       &dki->value); +    TALER_amount_ntoh (&fee_withdraw, +                       &dki->fee_withdraw);      // FIXME: #3637 -    total_cost = TALER_amount_add (cost, -                                   total_cost); +    if ( (GNUNET_OK != +          TALER_amount_add (&cost, +                            &value, +                            &fee_withdraw)) || +         (GNUNET_OK != +          TALER_amount_add (&total_cost, +                            &cost, +                            &total_cost)) ) +    { +      // FIXME... +    }    }    // FIXME: badness, use proper way to set to zero... @@ -146,13 +160,18 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,      // melt = coin_values[i]; // FIXME: #3636!      // FIXME: #3637 -    total_melt = TALER_amount_add (melt, -                                   total_melt); +    if (GNUNET_OK != +        TALER_amount_add (&total_melt, +                          &melt, +                          &total_melt)) +    { +      // FIXME ... +    }    }    TALER_MINT_key_state_release (key_state);    if (0 != -      TALER_amount_cmp (total_cost, -                        total_melt) ) +      TALER_amount_cmp (&total_cost, +                        &total_melt) )    {      /* We require total value of coins being melted and         total value of coins being generated to match! */ @@ -269,7 +288,8 @@ verify_coin_public_info (struct MHD_Connection *connection,    body.purpose.size = htonl (sizeof (struct RefreshMeltCoinSignature));    body.purpose.purpose = htonl (TALER_SIGNATURE_REFRESH_MELT_COIN);    body.melt_hash = *melt_hash; -  body.amount = TALER_amount_hton (r_melt_detail->melt_amount); +  TALER_amount_hton (&body.amount, +                     &r_melt_detail->melt_amount);    body.coin_pub = r_public_info->coin_pub;    if (GNUNET_OK !=        GNUNET_CRYPTO_ecdsa_verify (TALER_SIGNATURE_REFRESH_MELT_COIN, diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c index 3d827b11..a4b44215 100644 --- a/src/mint/taler-mint-httpd_responses.c +++ b/src/mint/taler-mint-httpd_responses.c @@ -299,7 +299,8 @@ TALER_MINT_reply_deposit_success (struct MHD_Connection *connection,    dc.h_contract = *h_contract;    dc.h_wire = *h_wire;    dc.transaction_id = GNUNET_htonll (transaction_id); -  dc.amount = TALER_amount_hton (*amount); +  TALER_amount_hton (&dc.amount, +                     amount);    dc.coin_pub = *coin_pub;    dc.merchant = *merchant;    TALER_MINT_keys_sign (&dc.purpose, @@ -346,7 +347,8 @@ compile_transaction_history (const struct TALER_MINT_DB_TransactionList *tl)          dr.h_contract = deposit->h_contract;          dr.h_wire = deposit->h_wire;          dr.transaction_id = GNUNET_htonll (deposit->transaction_id); -        dr.amount = TALER_amount_hton (deposit->amount); +        TALER_amount_hton (&dr.amount, +                           &deposit->amount);          dr.coin_pub = deposit->coin.coin_pub;          transaction = TALER_JSON_from_ecdsa_sig (&dr.purpose,                                                   &deposit->csig); @@ -362,7 +364,8 @@ compile_transaction_history (const struct TALER_MINT_DB_TransactionList *tl)          ms.purpose.purpose = htonl (TALER_SIGNATURE_REFRESH_MELT_COIN);          ms.purpose.size = htonl (sizeof (struct RefreshMeltCoinSignature));          ms.melt_hash = melt->melt_hash; -        ms.amount = TALER_amount_hton (melt->amount); +        TALER_amount_hton (&ms.amount, +                           &melt->amount);          ms.coin_pub = melt->coin.coin_pub;          transaction = TALER_JSON_from_ecdsa_sig (&ms.purpose,                                                   &melt->coin_sig); @@ -382,7 +385,7 @@ compile_transaction_history (const struct TALER_MINT_DB_TransactionList *tl)      json_array_append_new (history,                             json_pack ("{s:s, s:o}",                                        "type", type, -                                      "amount", TALER_JSON_from_amount (value), +                                      "amount", TALER_JSON_from_amount (&value),                                        "signature", transaction));    }    return history; @@ -419,7 +422,7 @@ TALER_MINT_reply_deposit_insufficient_funds (struct MHD_Connection *connection,   *   * @param rh reserve history to JSON-ify   * @param balance[OUT] set to current reserve balance - * @return json representation of the @a rh + * @return json representation of the @a rh, NULL on error   */  static json_t *  compile_reserve_history (const struct ReserveHistory *rh, @@ -446,14 +449,20 @@ compile_reserve_history (const struct ReserveHistory *rh,        if (0 == ret)          deposit_total = pos->details.bank->amount;        else -        deposit_total = TALER_amount_add (deposit_total, -                                          pos->details.bank->amount); +        if (GNUNET_OK != +            TALER_amount_add (&deposit_total, +                              &deposit_total, +                              &pos->details.bank->amount)) +        { +          json_decref (json_history); +          return NULL; +        }        ret = 1;        json_array_append_new (json_history,                               json_pack ("{s:s, s:o, s:o}",                                          "type", "DEPOSIT",                                          "wire", pos->details.bank->wire, -                                        "amount", TALER_JSON_from_amount (pos->details.bank->amount))); +                                        "amount", TALER_JSON_from_amount (&pos->details.bank->amount)));        break;      case TALER_MINT_DB_RO_WITHDRAW_COIN:        break; @@ -472,12 +481,20 @@ compile_reserve_history (const struct ReserveHistory *rh,        dki = TALER_MINT_get_denom_key (key_state,                                        pos->details.withdraw->denom_pub); -      value = TALER_amount_ntoh (dki->issue.value); +      TALER_amount_ntoh (&value, +                         &dki->issue.value);        if (0 == ret)          withdraw_total = value;        else -        withdraw_total = TALER_amount_add (withdraw_total, -                                           value); +        if (GNUNET_OK != +            TALER_amount_add (&withdraw_total, +                              &withdraw_total, +                              &value)) +        { +          TALER_MINT_key_state_release (key_state); +          json_decref (json_history); +          return NULL; +        }        ret = 1;        wr.purpose.purpose = htonl (TALER_SIGNATURE_WITHDRAW);        wr.purpose.size = htonl (sizeof (struct TALER_WithdrawRequest)); @@ -493,15 +510,22 @@ compile_reserve_history (const struct ReserveHistory *rh,                               json_pack ("{s:s, s:o, s:o}",                                          "type", "WITHDRAW",                                          "signature", transaction, -                                        "amount", TALER_JSON_from_amount (value))); +                                        "amount", TALER_JSON_from_amount (&value)));        break;      }    }    TALER_MINT_key_state_release (key_state); -  *balance = TALER_amount_subtract (deposit_total, -                                    withdraw_total); +  if (GNUNET_SYSERR == +      TALER_amount_subtract (balance, +                             &deposit_total, +                             &withdraw_total)) +  { +    GNUNET_break (0); +    json_decref (json_history); +    return NULL; +  }    return json_history;  } @@ -524,7 +548,10 @@ TALER_MINT_reply_withdraw_status_success (struct MHD_Connection *connection,    json_history = compile_reserve_history (rh,                                            &balance); -  json_balance = TALER_JSON_from_amount (balance); +  if (NULL == json_history) +    return TALER_MINT_reply_internal_error (connection, +                                            "balance calculation failure"); +  json_balance = TALER_JSON_from_amount (&balance);    ret = TALER_MINT_reply_json_pack (connection,                                      MHD_HTTP_OK,                                      "{s:o, s:o}", @@ -556,7 +583,10 @@ TALER_MINT_reply_withdraw_sign_insufficient_funds (struct MHD_Connection *connec    json_history = compile_reserve_history (rh,                                            &balance); -  json_balance = TALER_JSON_from_amount (balance); +  if (NULL == json_history) +    return TALER_MINT_reply_internal_error (connection, +                                            "balance calculation failure"); +  json_balance = TALER_JSON_from_amount (&balance);    ret = TALER_MINT_reply_json_pack (connection,                                      MHD_HTTP_PAYMENT_REQUIRED,                                      "{s:s, s:o, s:o}", @@ -625,9 +655,9 @@ TALER_MINT_reply_refresh_melt_insufficient_funds (struct MHD_Connection *connect                                       "error", "insufficient funds",                                       "coin-pub", TALER_JSON_from_data (coin_pub,                                                                         sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)), -                                     "original-value", TALER_JSON_from_amount (coin_value), -                                     "residual-value", TALER_JSON_from_amount (residual), -                                     "requested-value", TALER_JSON_from_amount (requested), +                                     "original-value", TALER_JSON_from_amount (&coin_value), +                                     "residual-value", TALER_JSON_from_amount (&residual), +                                     "requested-value", TALER_JSON_from_amount (&requested),                                       "history", history);  } diff --git a/src/mint/taler-mint-keyup.c b/src/mint/taler-mint-keyup.c index 33bb8724..759e7c1b 100644 --- a/src/mint/taler-mint-keyup.c +++ b/src/mint/taler-mint-keyup.c @@ -233,10 +233,14 @@ hash_coin_type (const struct CoinTypeParams *p,            sizeof (struct CoinTypeNBO));    p_nbo.duration_spend = GNUNET_TIME_relative_hton (p->duration_spend);    p_nbo.duration_withdraw = GNUNET_TIME_relative_hton (p->duration_withdraw); -  p_nbo.value = TALER_amount_hton (p->value); -  p_nbo.fee_withdraw = TALER_amount_hton (p->fee_withdraw); -  p_nbo.fee_deposit = TALER_amount_hton (p->fee_deposit); -  p_nbo.fee_refresh = TALER_amount_hton (p->fee_refresh); +  TALER_amount_hton (&p_nbo.value, +                     &p->value); +  TALER_amount_hton (&p_nbo.fee_withdraw, +                     &p->fee_withdraw); +  TALER_amount_hton (&p_nbo.fee_deposit, +                     &p->fee_deposit); +  TALER_amount_hton (&p_nbo.fee_refresh, +                     &p->fee_refresh);    p_nbo.rsa_keysize = htonl (p->rsa_keysize);    GNUNET_CRYPTO_hash (&p_nbo,                        sizeof (struct CoinTypeNBO), @@ -273,7 +277,7 @@ get_cointype_dir (const struct CoinTypeParams *p)    GNUNET_assert (HASH_CUTOFF <= strlen (hash_str) + 1);    hash_str[HASH_CUTOFF] = 0; -  val_str = TALER_amount_to_string (p->value); +  val_str = TALER_amount_to_string (&p->value);    for (i = 0; i < strlen (val_str); i++)      if ( (':' == val_str[i]) ||           ('.' == val_str[i]) ) @@ -687,11 +691,14 @@ create_denomkey_issue (const struct CoinTypeParams *params,    dki->issue.expire_spend =      GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (params->anchor,                                                             params->duration_spend)); -  dki->issue.value = TALER_amount_hton (params->value); -  dki->issue.fee_withdraw = TALER_amount_hton (params->fee_withdraw); -  dki->issue.fee_deposit = TALER_amount_hton (params->fee_deposit); -  dki->issue.fee_refresh = TALER_amount_hton (params->fee_refresh); - +  TALER_amount_hton (&dki->issue.value, +                     ¶ms->value); +  TALER_amount_hton (&dki->issue.fee_withdraw, +                     ¶ms->fee_withdraw); +  TALER_amount_hton (&dki->issue.fee_deposit, +                     ¶ms->fee_deposit); +  TALER_amount_hton (&dki->issue.fee_refresh, +                     ¶ms->fee_refresh);    dki->issue.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DENOM);    dki->issue.purpose.size = htonl (sizeof (struct TALER_MINT_DenomKeyIssuePriv) -                                     offsetof (struct TALER_MINT_DenomKeyIssuePriv, diff --git a/src/mint/taler-mint-reservemod.c b/src/mint/taler-mint-reservemod.c index dea59d6e..df3f0cd5 100644 --- a/src/mint/taler-mint-reservemod.c +++ b/src/mint/taler-mint-reservemod.c @@ -161,9 +161,11 @@ reservemod_add (struct TALER_Amount denom)                                              "balance_fraction",                                              "balance_currency",                                              &old_denom)); -    new_denom = TALER_amount_add (old_denom, -                                  denom); -    new_denom_nbo = TALER_amount_hton (new_denom); +    TALER_amount_add (&new_denom, +                      &old_denom, +                      &denom); +    TALER_amount_hton (&new_denom_nbo, +                       &new_denom);      result = PQexecParams (db_conn,                             "UPDATE reserves"                             " SET balance_value = $1, balance_fraction = $2, status_sig = NULL, status_sign_pub = NULL" | 
