diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_purses_create.c')
-rw-r--r-- | src/exchange/taler-exchange-httpd_purses_create.c | 78 |
1 files changed, 67 insertions, 11 deletions
diff --git a/src/exchange/taler-exchange-httpd_purses_create.c b/src/exchange/taler-exchange-httpd_purses_create.c index 75cb448a..326dad5c 100644 --- a/src/exchange/taler-exchange-httpd_purses_create.c +++ b/src/exchange/taler-exchange-httpd_purses_create.c @@ -112,6 +112,11 @@ struct PurseCreateContext struct TALER_PurseContractSignatureP purse_sig; /** + * Signature of the client affiming this encrypted contract. + */ + struct TALER_PurseContractSignatureP econtract_sig; + + /** * Hash of the contract terms of the purse. */ struct TALER_PrivateContractHashP h_contract_terms; @@ -260,7 +265,7 @@ create_transaction (void *cls, return GNUNET_DB_STATUS_HARD_ERROR; } *mhd_ret - = return TALER_MHD_REPLY_JSON_PACK ( + = TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_CONFLICT, TALER_JSON_pack_ec ( @@ -319,6 +324,7 @@ create_transaction (void *cls, &pcc->contract_pub, pcc->econtract_size, pcc->econtract, + &pcc->econtract_sig, &in_conflict); if (qs < 0) { @@ -333,16 +339,45 @@ create_transaction (void *cls, } if (in_conflict) { - /* FIXME-DESIGN: we have no proof that the - client is at fault here! - => need 2nd client signature over the encrypted - contract (and ECDHE public key)!!! */ + struct TALER_ContractDiffiePublicP pub_ckey; + struct TALER_PurseContractSignatureP econtract_sig; + size_t econtract_size; + void *econtract; + struct GNUNET_HashCode h_econtract; + + qs = select_contract (cls, + &pcc->purse_pub, + &pub_ckey, + &econtract_sig, + &econtract_size, + &econtract); + if (qs <= 0) + { + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) + return qs; + TALER_LOG_WARNING ( + "Failed to store fetch contract information from database\n"); + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "select contract"); + return qs; + } + GNUNET_CRYPTO_hash (econtract, + econtract_size, + &h_econtract); *mhd_ret - = TEH_RESPONSE_reply_with_error ( + = TALER_MHD_REPLY_JSON_PACK ( connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_EXCHANGE_PURSE_CREATE_CONFLICTING_CONTRACT_STORED, - NULL); + MHD_HTTP_CONFLICT, + TALER_JSON_pack_ec ( + TALER_EC_EXCHANGE_PURSE_ECONTRACT_CONFLICTING_META_DATA), + GNUNET_JSON_pack_data_auto ("h_econtract", + &h_econtract), + GNUNET_JSON_pack_data_auto ("econtract_sig", + &econtract_sig), + GNUNET_JSON_pack_data_auto ("pub_ckey", + &pub_ckey)); return GNUNET_DB_STATUS_HARD_ERROR; } return qs; @@ -591,8 +626,12 @@ TEH_handler_purses_create ( GNUNET_JSON_spec_var_size ("econtract", &pcc.econtract, &pcc.ecotract_size)), - GNUNET_JSON_spec_fixed_auto ("contract_pub", - &pcc.contract_pub), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_fixed_auto ("econtract_sig", + &pcc.econtract_sig)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_fixed_auto ("contract_pub", + &pcc.contract_pub)), GNUNET_JSON_spec_fixed_auto ("merge_pub", &pcc.merge_pub), GNUNET_JSON_spec_fixed_auto ("purse_sig", @@ -719,6 +758,23 @@ TEH_handler_purses_create ( TALER_EC_EXCHANGE_PURSE_CREATE_SIGNATURE_INVALID, NULL); } + if ( (NULL != pcc.econtract) && + (GNUNET_OK != + TALER_wallet_econtract_upload_verify (pcc.econtract, + pcc.econtract_size, + &pcc.contract_pub, + purse_pub, + &pcc.econtract_sig)) ) + { + TALER_LOG_WARNING ("Invalid signature on /purses/$PID/create request\n"); + GNUNET_JSON_parse_free (spec); + GNUNET_free (pcc.coins); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_UNAUTHORIZED, + TALER_EC_EXCHANGE_PURSE_ECONTRACT_SIGNATURE_INVALID, + NULL); + } + if (GNUNET_SYSERR == TEH_plugin->preflight (TEH_plugin->cls)) |