diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_melt.c')
| -rw-r--r-- | src/exchange/taler-exchange-httpd_melt.c | 206 | 
1 files changed, 92 insertions, 114 deletions
diff --git a/src/exchange/taler-exchange-httpd_melt.c b/src/exchange/taler-exchange-httpd_melt.c index 76cf52eb..143e3f3a 100644 --- a/src/exchange/taler-exchange-httpd_melt.c +++ b/src/exchange/taler-exchange-httpd_melt.c @@ -29,8 +29,8 @@  #include "taler-exchange-httpd_mhd.h"  #include "taler-exchange-httpd_melt.h"  #include "taler-exchange-httpd_responses.h" -#include "taler-exchange-httpd_keystate.h"  #include "taler-exchange-httpd_keys.h" +#include "taler_exchangedb_lib.h"  /** @@ -463,136 +463,114 @@ static MHD_RESULT  check_for_denomination_key (struct MHD_Connection *connection,                              struct MeltContext *rmc)  { -  struct TEH_KS_StateHandle *key_state; +  /* Baseline: check if deposits/refreshs are generally +     simply still allowed for this denomination */ +  struct TEH_DenominationKey *dk; +  unsigned int hc; +  enum TALER_ErrorCode ec; +  struct GNUNET_TIME_Absolute now; -  key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ()); -  if (NULL == key_state) +  dk = TEH_keys_denomination_by_hash ( +    &rmc->refresh_session.coin.denom_pub_hash, +    &ec, +    &hc); +  if (NULL == dk)    { -    TALER_LOG_ERROR ("Lacking keys to operate\n"); -    return TALER_MHD_reply_with_error (connection, -                                       MHD_HTTP_INTERNAL_SERVER_ERROR, -                                       TALER_EC_EXCHANGE_GENERIC_BAD_CONFIGURATION, -                                       "no keys"); +    return TALER_MHD_reply_with_error ( +      connection, +      MHD_HTTP_NOT_FOUND, +      TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN, +      NULL);    } - +  now = GNUNET_TIME_absolute_get (); +  if (now.abs_value_us >= dk->meta.expire_legal.abs_value_us)    { -    /* Baseline: check if deposits/refreshs are generally -       simply still allowed for this denomination */ -    struct TEH_DenominationKey *dk; -    unsigned int hc; -    enum TALER_ErrorCode ec; -    struct GNUNET_TIME_Absolute now; - -    dk = TEH_keys_denomination_by_hash ( -      &rmc->refresh_session.coin.denom_pub_hash, -      &ec, -      &hc); -    if (NULL == dk) +    /* Way too late now, even zombies have expired */ +    return TALER_MHD_reply_with_error ( +      connection, +      MHD_HTTP_GONE, +      TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED, +      NULL); +  } +  if (now.abs_value_us < dk->meta.start.abs_value_us) +  { +    /* This denomination is not yet valid */ +    return TALER_MHD_reply_with_error ( +      connection, +      MHD_HTTP_PRECONDITION_FAILED, +      TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE, +      NULL); +  } +  if (now.abs_value_us >= dk->meta.expire_deposit.abs_value_us) +  { +    /* We are past deposit expiration time, but maybe this is a zombie? */ +    struct GNUNET_HashCode denom_hash; +    enum GNUNET_DB_QueryStatus qs; + +    /* Check that the coin is dirty (we have seen it before), as we will +       not just allow melting of a *fresh* coin where the denomination was +       revoked (those must be recouped) */ +    qs = TEH_plugin->get_coin_denomination ( +      TEH_plugin->cls, +      NULL, +      &rmc->refresh_session.coin.coin_pub, +      &denom_hash); +    if (0 > qs)      { -      TEH_KS_release (key_state); -      return TALER_MHD_reply_with_error ( -        connection, -        MHD_HTTP_NOT_FOUND, -        TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN, -        NULL); +      /* There is no good reason for a serialization failure here: */ +      GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); +      return TALER_MHD_reply_with_error (connection, +                                         MHD_HTTP_INTERNAL_SERVER_ERROR, +                                         TALER_EC_GENERIC_DB_FETCH_FAILED, +                                         "coin denomination");      } -    now = GNUNET_TIME_absolute_get (); -    if (now.abs_value_us >= dk->meta.expire_legal.abs_value_us) +    /* sanity check */ +    GNUNET_break (0 == +                  GNUNET_memcmp (&denom_hash, +                                 &rmc->refresh_session.coin.denom_pub_hash)); +    if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)      { -      /* Way too late now, even zombies have expired */ -      TEH_KS_release (key_state); +      /* We never saw this coin before, so _this_ justification is not OK */        return TALER_MHD_reply_with_error (          connection,          MHD_HTTP_GONE,          TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED,          NULL);      } -    if (now.abs_value_us < dk->meta.start.abs_value_us) -    { -      /* This denomination is not yet valid */ -      TEH_KS_release (key_state); -      return TALER_MHD_reply_with_error ( -        connection, -        MHD_HTTP_PRECONDITION_FAILED, -        TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE, -        NULL); -    } -    if (now.abs_value_us >= dk->meta.expire_deposit.abs_value_us) +    else      { -      /* We are past deposit expiration time, but maybe this is a zombie? */ -      struct GNUNET_HashCode denom_hash; -      enum GNUNET_DB_QueryStatus qs; - -      /* Check that the coin is dirty (we have seen it before), as we will -         not just allow melting of a *fresh* coin where the denomination was -         revoked (those must be recouped) */ -      qs = TEH_plugin->get_coin_denomination ( -        TEH_plugin->cls, -        NULL, -        &rmc->refresh_session.coin.coin_pub, -        &denom_hash); -      if (0 > qs) -      { -        TEH_KS_release (key_state); -        /* There is no good reason for a serialization failure here: */ -        GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); -        return TALER_MHD_reply_with_error (connection, -                                           MHD_HTTP_INTERNAL_SERVER_ERROR, -                                           TALER_EC_GENERIC_DB_FETCH_FAILED, -                                           "coin denomination"); -      } -      /* sanity check */ -      GNUNET_break (0 == -                    GNUNET_memcmp (&denom_hash, -                                   &rmc->refresh_session.coin.denom_pub_hash)); -      if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) -      { -        /* We never saw this coin before, so _this_ justification is not OK */ -        TEH_KS_release (key_state); -        return TALER_MHD_reply_with_error ( -          connection, -          MHD_HTTP_GONE, -          TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED, -          NULL); -      } -      else -      { -        /* Minor optimization: no need to run the -           "ensure_coin_known" part of the transaction */ -        rmc->coin_is_dirty = true; -      } -      rmc->zombie_required = true; /* check later that zombie is satisfied */ +      /* Minor optimization: no need to run the +         "ensure_coin_known" part of the transaction */ +      rmc->coin_is_dirty = true;      } +    rmc->zombie_required = true;   /* check later that zombie is satisfied */ +  } -    rmc->coin_refresh_fee = dk->meta.fee_refresh; -    rmc->coin_value = dk->meta.value; -    /* check client used sane currency */ -    if (GNUNET_YES != -        TALER_amount_cmp_currency (&rmc->refresh_session.amount_with_fee, -                                   &rmc->coin_value) ) -    { -      GNUNET_break_op (0); -      TEH_KS_release (key_state); -      return TALER_MHD_reply_with_error ( -        connection, -        MHD_HTTP_BAD_REQUEST, -        TALER_EC_GENERIC_CURRENCY_MISMATCH, -        rmc->refresh_session.amount_with_fee.currency); -    } -    /* check coin is actually properly signed */ -    if (GNUNET_OK != -        TALER_test_coin_valid (&rmc->refresh_session.coin, -                               &dk->denom_pub)) -    { -      GNUNET_break_op (0); -      TEH_KS_release (key_state); -      return TALER_MHD_reply_with_error (connection, -                                         MHD_HTTP_FORBIDDEN, -                                         TALER_EC_EXCHANGE_DENOMINATION_SIGNATURE_INVALID, -                                         NULL); -    } +  rmc->coin_refresh_fee = dk->meta.fee_refresh; +  rmc->coin_value = dk->meta.value; +  /* check client used sane currency */ +  if (GNUNET_YES != +      TALER_amount_cmp_currency (&rmc->refresh_session.amount_with_fee, +                                 &rmc->coin_value) ) +  { +    GNUNET_break_op (0); +    return TALER_MHD_reply_with_error ( +      connection, +      MHD_HTTP_BAD_REQUEST, +      TALER_EC_GENERIC_CURRENCY_MISMATCH, +      rmc->refresh_session.amount_with_fee.currency); +  } +  /* check coin is actually properly signed */ +  if (GNUNET_OK != +      TALER_test_coin_valid (&rmc->refresh_session.coin, +                             &dk->denom_pub)) +  { +    GNUNET_break_op (0); +    return TALER_MHD_reply_with_error (connection, +                                       MHD_HTTP_FORBIDDEN, +                                       TALER_EC_EXCHANGE_DENOMINATION_SIGNATURE_INVALID, +                                       NULL);    } -  TEH_KS_release (key_state);    /* sanity-check that "total melt amount > melt fee" */    if (0 <  | 
