/* This file is part of TALER Copyright (C) 2014-2021 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with TALER; see the file COPYING. If not, see */ /** * @file taler-exchange-httpd_csr.c * @brief Handle /csr requests * @author Lucien Heuzeveldt * @author Gian Demarmles */ #include "platform.h" #include #include #include "taler_json_lib.h" #include "taler_mhd_lib.h" #include "taler-exchange-httpd_csr.h" #include "taler-exchange-httpd_responses.h" #include "taler-exchange-httpd_keys.h" MHD_RESULT TEH_handler_csr (struct TEH_RequestContext *rc, const json_t *root, const char *const args[]) { // TODO: should we have something similar to struct WithdrawContext? // as far as I can tell this isn't necessary because we don't have // other functions that the context should be passed to // struct CsRContext csrc; struct TALER_WithdrawNonce nonce; struct TALER_DenominationHash denom_pub_hash; struct TALER_DenominationCsPublicR r_pub; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed ("nonce", &nonce, sizeof (struct TALER_WithdrawNonce)), GNUNET_JSON_spec_fixed ("denom_pub_hash", &denom_pub_hash, sizeof (struct TALER_DenominationHash)), GNUNET_JSON_spec_end () }; enum TALER_ErrorCode ec; struct TEH_DenominationKey *dk; (void) args; memset (&nonce, 0, sizeof (nonce)); memset (&denom_pub_hash, 0, sizeof (denom_pub_hash)); memset (&r_pub, 0, sizeof (r_pub)); // parse input { enum GNUNET_GenericReturnValue res; res = TALER_MHD_parse_json_data (rc->connection, root, spec); GNUNET_JSON_parse_free (spec); if (GNUNET_OK != res) return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; } // check denomination referenced by denom_pub_hash { MHD_RESULT mret; struct TEH_KeyStateHandle *ksh; ksh = TEH_keys_get_state (); if (NULL == ksh) { return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, NULL); return mret; } dk = TEH_keys_denomination_by_hash2 (ksh, &denom_pub_hash, NULL, NULL); if (NULL == dk) { return TEH_RESPONSE_reply_unknown_denom_pub_hash ( rc->connection, &denom_pub_hash); } if (GNUNET_TIME_absolute_is_past (dk->meta.expire_withdraw.abs_time)) { /* This denomination is past the expiration time for withdraws/refreshes*/ return TEH_RESPONSE_reply_expired_denom_pub_hash ( rc->connection, &denom_pub_hash, GNUNET_TIME_timestamp_get (), TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED, "CSR"); } if (GNUNET_TIME_absolute_is_future (dk->meta.start.abs_time)) { /* This denomination is not yet valid, no need to check for idempotency! */ return TEH_RESPONSE_reply_expired_denom_pub_hash ( rc->connection, &denom_pub_hash, GNUNET_TIME_timestamp_get (), TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE, "CSR"); } if (dk->recoup_possible) { /* This denomination has been revoked */ return TEH_RESPONSE_reply_expired_denom_pub_hash ( rc->connection, &denom_pub_hash, GNUNET_TIME_timestamp_get (), TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED, "CSR"); } if (TALER_DENOMINATION_CS != dk->denom_pub.cipher) { // denomination is valid but not CS return TEH_RESPONSE_reply_unknown_denom_pub_hash ( rc->connection, &denom_pub_hash); } } // derive r_pub ec = TALER_EC_NONE; r_pub = TEH_keys_denomination_cs_r_pub (&denom_pub_hash, &nonce, &ec); if (TALER_EC_NONE != ec) { GNUNET_break (0); return TALER_MHD_reply_with_ec (rc->connection, ec, NULL); } // send response { MHD_RESULT ret; ret = TALER_MHD_REPLY_JSON_PACK ( rc->connection, MHD_HTTP_OK, GNUNET_JSON_pack_data_varsize ("r_pub_0", &r_pub.r_pub[0], sizeof(struct GNUNET_CRYPTO_CsRPublic)), GNUNET_JSON_pack_data_varsize ("r_pub_1", &r_pub.r_pub[1], sizeof(struct GNUNET_CRYPTO_CsRPublic))); return ret; } } /* end of taler-exchange-httpd_csr.c */