diff options
| author | Christian Grothoff <christian@grothoff.org> | 2017-04-18 21:05:27 +0200 | 
|---|---|---|
| committer | Christian Grothoff <christian@grothoff.org> | 2017-04-18 21:05:27 +0200 | 
| commit | 5e8ef386803c399c1b6d780181b0b8662c418db0 (patch) | |
| tree | e1e0e7433be54c9f1904e73d3257b00b82320847 /src/exchange-lib | |
| parent | 164c125528e4af078815c0156df54fa0120eed8a (diff) | |
fixing #4980
Diffstat (limited to 'src/exchange-lib')
| -rw-r--r-- | src/exchange-lib/exchange_api_common.c | 147 | ||||
| -rw-r--r-- | src/exchange-lib/exchange_api_reserve.c | 68 | 
2 files changed, 88 insertions, 127 deletions
| diff --git a/src/exchange-lib/exchange_api_common.c b/src/exchange-lib/exchange_api_common.c index 29d0f6d1..d9d0a6d5 100644 --- a/src/exchange-lib/exchange_api_common.c +++ b/src/exchange-lib/exchange_api_common.c @@ -89,13 +89,22 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,                           "DEPOSIT"))      {        struct TALER_DepositRequestPS dr; -      struct TALER_Amount dr_amount;        struct TALER_CoinSpendSignatureP sig;        struct GNUNET_JSON_Specification spec[] = { -        GNUNET_JSON_spec_fixed_auto ("signature", +        GNUNET_JSON_spec_fixed_auto ("coin_sig",                                       &sig), -        GNUNET_JSON_spec_fixed_auto ("details", -                                     &dr), +        GNUNET_JSON_spec_fixed_auto ("h_proposal_data", +                                     &dr.h_proposal_data), +        GNUNET_JSON_spec_fixed_auto ("h_wire", +                                     &dr.h_wire), +        GNUNET_JSON_spec_absolute_time_nbo ("timestamp", +					    &dr.timestamp), +        GNUNET_JSON_spec_absolute_time_nbo ("refund_deadline", +					    &dr.refund_deadline), +        TALER_JSON_spec_amount_nbo ("deposit_fee", +				    &dr.deposit_fee), +        GNUNET_JSON_spec_fixed_auto ("merchant_pub", +                                     &dr.merchant),          GNUNET_JSON_spec_end()        }; @@ -107,12 +116,11 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,          GNUNET_break_op (0);          return GNUNET_SYSERR;        } -      /* TODO #4980 */ -      if (sizeof (dr) != ntohl (dr.purpose.size)) -      { -        GNUNET_break_op (0); -        return GNUNET_SYSERR; -      } +      dr.purpose.size = htonl (sizeof (dr)); +      dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT); +      TALER_amount_hton (&dr.amount_with_fee, +			 &amount); +      dr.coin_pub = *coin_pub;        if (GNUNET_OK !=            GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,                                        &dr.purpose, @@ -122,28 +130,22 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,          GNUNET_break_op (0);          return GNUNET_SYSERR;        } -      TALER_amount_ntoh (&dr_amount, -                         &dr.amount_with_fee); -      /* TODO #4980 */ -      if (0 != TALER_amount_cmp (&dr_amount, -                                 &amount)) -      { -        GNUNET_break (0); -        return GNUNET_SYSERR; -      } +      /* TODO: check that deposit fee and coin value match +	 our expectations from /keys! */        add = GNUNET_YES;      }      else if (0 == strcasecmp (type,                                "MELT"))      {        struct TALER_RefreshMeltCoinAffirmationPS rm; -      struct TALER_Amount rm_amount;        struct TALER_CoinSpendSignatureP sig;        struct GNUNET_JSON_Specification spec[] = { -        GNUNET_JSON_spec_fixed_auto ("signature", +        GNUNET_JSON_spec_fixed_auto ("coin_sig",                                       &sig), -        GNUNET_JSON_spec_fixed_auto ("details", -                                     &rm), +        GNUNET_JSON_spec_fixed_auto ("session_hash", +                                     &rm.session_hash), +        TALER_JSON_spec_amount_nbo ("melt_fee", +				    &rm.melt_fee),          GNUNET_JSON_spec_end()        }; @@ -155,12 +157,11 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,          GNUNET_break_op (0);          return GNUNET_SYSERR;        } -      /* TODO #4980 */ -      if (sizeof (rm) != ntohl (rm.purpose.size)) -      { -        GNUNET_break_op (0); -        return GNUNET_SYSERR; -      } +      rm.purpose.size = htonl (sizeof (rm)); +      rm.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT); +      TALER_amount_hton (&rm.amount_with_fee, +			 &amount); +      rm.coin_pub = *coin_pub;        if (GNUNET_OK !=            GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT,                                        &rm.purpose, @@ -170,30 +171,26 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,          GNUNET_break_op (0);          return GNUNET_SYSERR;        } -      TALER_amount_ntoh (&rm_amount, -                         &rm.amount_with_fee); -      /* TODO #4980 */ -      if (0 != TALER_amount_cmp (&rm_amount, -                                 &amount)) -      { -        GNUNET_break_op (0); -        return GNUNET_SYSERR; -      } +      /* TODO: check that deposit fee and coin value match +	 our expectations from /keys! */        add = GNUNET_YES;      }      else if (0 == strcasecmp (type,                                "REFUND"))      {        struct TALER_RefundRequestPS rr; -      struct TALER_Amount rr_amount; -      struct TALER_Amount rr_fee; -      struct TALER_Amount rr_delta; -      struct TALER_CoinSpendSignatureP sig; +      struct TALER_MerchantSignatureP sig;        struct GNUNET_JSON_Specification spec[] = { -        GNUNET_JSON_spec_fixed_auto ("signature", +        GNUNET_JSON_spec_fixed_auto ("merchant_sig",                                       &sig), -        GNUNET_JSON_spec_fixed_auto ("details", -                                     &rr), +        GNUNET_JSON_spec_fixed_auto ("h_proposal_data", +                                     &rr.h_proposal_data), +        GNUNET_JSON_spec_fixed_auto ("merchant_pub", +                                     &rr.merchant), +        GNUNET_JSON_spec_uint64 ("rtransaction_id", +				 &rr.rtransaction_id), +        TALER_JSON_spec_amount_nbo ("refund_fee", +				    &rr.refund_fee),          GNUNET_JSON_spec_end()        }; @@ -205,38 +202,20 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,          GNUNET_break_op (0);          return GNUNET_SYSERR;        } -      /* TODO #4980 */ -      if (sizeof (rr) != ntohl (rr.purpose.size)) -      { -        GNUNET_break_op (0); -        return GNUNET_SYSERR; -      } +      rr.purpose.size = htonl (sizeof (rr)); +      rr.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND); +      rr.coin_pub = *coin_pub; +      TALER_amount_hton (&rr.refund_amount, +			 &amount);        if (GNUNET_OK !=            GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,                                        &rr.purpose, -                                      &sig.eddsa_signature, +                                      &sig.eddsa_sig,                                        &rr.merchant.eddsa_pub))        {          GNUNET_break_op (0);          return GNUNET_SYSERR;        } -      TALER_amount_ntoh (&rr_amount, -                         &rr.refund_amount); -      if (GNUNET_OK != -          TALER_amount_subtract (&rr_delta, -                                 &rr_amount, -                                 &rr_fee)) -      { -        GNUNET_break_op (0); -        return GNUNET_SYSERR; -      } -      /* TODO #4980 */ -      if (0 != TALER_amount_cmp (&rr_delta, -                                 &amount)) -      { -        GNUNET_break_op (0); -        return GNUNET_SYSERR; -      }        /* NOTE: theoretically, we could also check that the given           merchant_pub and h_proposal_data appear in the           history under deposits.  However, there is really no benefit @@ -244,13 +223,14 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,           (an auditor ought to check, though). Then again, we similarly           had no reason to check the merchant's signature (other than a           well-formendess check). */ +      /* TODO: check that deposit fee and coin value match +	 our expectations from /keys! */        add = GNUNET_NO;      }      else if (0 == strcasecmp (type,                                "PAYBACK"))      {        struct TALER_PaybackConfirmationPS pc; -      struct TALER_Amount pc_amount;        struct TALER_ExchangePublicKeyP exchange_pub;        struct TALER_ExchangeSignatureP exchange_sig;        struct GNUNET_JSON_Specification spec[] = { @@ -258,8 +238,10 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,                                       &exchange_sig),          GNUNET_JSON_spec_fixed_auto ("exchange_pub",                                       &exchange_pub), -        GNUNET_JSON_spec_fixed_auto ("details", -                                     &pc), +        GNUNET_JSON_spec_fixed_auto ("reserve_pub", +                                     &pc.reserve_pub), +	GNUNET_JSON_spec_absolute_time_nbo ("timestamp", +					    &pc.timestamp),          GNUNET_JSON_spec_end()        }; @@ -271,13 +253,11 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,          GNUNET_break_op (0);          return GNUNET_SYSERR;        } - -      /* TODO #4980 */ -      if (sizeof (pc) != ntohl (pc.purpose.size)) -      { -        GNUNET_break_op (0); -        return GNUNET_SYSERR; -      } +      pc.purpose.size = htonl (sizeof (pc)); +      pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK); +      pc.coin_pub = *coin_pub; +      TALER_amount_hton (&pc.payback_amount, +			 &amount);        if (GNUNET_OK !=            GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK,                                        &pc.purpose, @@ -287,15 +267,6 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,          GNUNET_break_op (0);          return GNUNET_SYSERR;        } -      TALER_amount_ntoh (&pc_amount, -                         &pc.payback_amount); -      /* TODO #4980 */ -      if (0 != TALER_amount_cmp (&pc_amount, -                                 &amount)) -      { -        GNUNET_break_op (0); -        return GNUNET_SYSERR; -      }        add = GNUNET_YES;      }      else diff --git a/src/exchange-lib/exchange_api_reserve.c b/src/exchange-lib/exchange_api_reserve.c index 0ed8cca0..98f15dcd 100644 --- a/src/exchange-lib/exchange_api_reserve.c +++ b/src/exchange-lib/exchange_api_reserve.c @@ -184,12 +184,15 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange,      {        struct TALER_ReserveSignatureP sig;        struct TALER_WithdrawRequestPS withdraw_purpose; -      struct TALER_Amount amount_from_purpose;        struct GNUNET_JSON_Specification withdraw_spec[] = { -        GNUNET_JSON_spec_fixed_auto ("signature", +        GNUNET_JSON_spec_fixed_auto ("reserve_sig",                                       &sig), -        GNUNET_JSON_spec_fixed_auto ("details", -                                     &withdraw_purpose), +	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", +                                     &withdraw_purpose.h_coin_envelope),          GNUNET_JSON_spec_end()        };        unsigned int i; @@ -203,6 +206,13 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange,          GNUNET_break_op (0);          return GNUNET_SYSERR;        } +      withdraw_purpose.purpose.size +	= htonl (sizeof (withdraw_purpose)); +      withdraw_purpose.purpose.purpose +	= htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW); +      withdraw_purpose.reserve_pub = *reserve_pub; +      TALER_amount_hton (&withdraw_purpose.amount_with_fee, +			 &amount);        /* Check that the signature is a valid withdraw request */        if (GNUNET_OK !=            GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW, @@ -214,18 +224,10 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange,          GNUNET_JSON_parse_free (withdraw_spec);          return GNUNET_SYSERR;        } -      TALER_amount_ntoh (&amount_from_purpose, -                         &withdraw_purpose.amount_with_fee); -      /* TODO #4980 */ -      if (0 != TALER_amount_cmp (&amount, -                                 &amount_from_purpose)) -      { -        GNUNET_break_op (0); -        GNUNET_JSON_parse_free (withdraw_spec); -        return GNUNET_SYSERR; -      } -      rhistory[off].details.out_authorization_sig = json_object_get (transaction, -                                                                     "signature"); +      /* TODO: check that withdraw fee matches expectations! */ +      rhistory[off].details.out_authorization_sig +	= json_object_get (transaction, +			   "signature");        /* Check check that the same withdraw transaction           isn't listed twice by the exchange. We use the           "uuid" array to remember the hashes of all @@ -263,25 +265,22 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange,                                "PAYBACK"))      {        struct TALER_PaybackConfirmationPS pc; -      struct TALER_Amount amount_from_purpose; -      struct GNUNET_TIME_Absolute timestamp_from_purpose;        struct GNUNET_TIME_Absolute timestamp;        const struct TALER_EXCHANGE_Keys *key_state;        struct GNUNET_JSON_Specification payback_spec[] = { -        GNUNET_JSON_spec_fixed_auto ("details", -                                     &pc), +        GNUNET_JSON_spec_fixed_auto ("coin_pub", +                                     &pc.coin_pub),          GNUNET_JSON_spec_fixed_auto ("exchange_sig",                                       &rhistory[off].details.payback_details.exchange_sig),          GNUNET_JSON_spec_fixed_auto ("exchange_pub",                                       &rhistory[off].details.payback_details.exchange_pub), -        GNUNET_JSON_spec_absolute_time ("timestamp", -                                        ×tamp), -        TALER_JSON_spec_amount ("amount", -                                &rhistory[off].amount), +        GNUNET_JSON_spec_absolute_time_nbo ("timestamp", +					    &pc.timestamp),          GNUNET_JSON_spec_end()        };        rhistory[off].type = TALER_EXCHANGE_RTT_PAYBACK; +      rhistory[off].amount = amount;        if (GNUNET_OK !=            GNUNET_JSON_parse (transaction,                               payback_spec, @@ -291,22 +290,13 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange,          return GNUNET_SYSERR;        }        rhistory[off].details.payback_details.coin_pub = pc.coin_pub; -      TALER_amount_ntoh (&amount_from_purpose, -                         &pc.payback_amount); +      TALER_amount_hton (&pc.payback_amount, +			 &amount); +      pc.purpose.size = htonl (sizeof (pc)); +      pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK); +      pc.reserve_pub = *reserve_pub; +      timestamp = GNUNET_TIME_absolute_ntoh (pc.timestamp);        rhistory[off].details.payback_details.timestamp = timestamp; -      timestamp_from_purpose = GNUNET_TIME_absolute_ntoh (pc.timestamp); -      /* TODO #4980 */ -      if ( (0 != memcmp (&pc.reserve_pub, -                         reserve_pub, -                         sizeof (*reserve_pub))) || -           (timestamp_from_purpose.abs_value_us != -            timestamp.abs_value_us) || -           (0 != TALER_amount_cmp (&amount_from_purpose, -                                   &rhistory[off].amount)) ) -      { -        GNUNET_break_op (0); -        return GNUNET_SYSERR; -      }        key_state = TALER_EXCHANGE_get_keys (exchange);        if (GNUNET_OK != | 
