/* This file is part of TALER Copyright (C) 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU General Public License along with TALER; see the file COPYING. If not, If not, see */ /** * @file mint-lib/mint_api_common.c * @brief common functions for the mint API * @author Christian Grothoff */ #include "platform.h" #include "mint_api_common.h" #include "mint_api_json.h" #include "mint_api_context.h" #include "mint_api_handle.h" #include "taler_signatures.h" /** * Verify a coins transaction history as returned by the mint. * * @param currency expected currency for the coin * @param coin_pub public key of the coin * @param history history of the coin in json encoding * @param[out] total how much of the coin has been spent according to @a history * @return #GNUNET_OK if @a history is valid, #GNUNET_SYSERR if not */ int TALER_MINT_verify_coin_history_ (const char *currency, const struct TALER_CoinSpendPublicKeyP *coin_pub, json_t *history, struct TALER_Amount *total) { size_t len; size_t off; if (NULL == history) { GNUNET_break_op (0); return GNUNET_SYSERR; } len = json_array_size (history); if (0 == len) { GNUNET_break_op (0); return GNUNET_SYSERR; } TALER_amount_get_zero (currency, total); for (off=0;offpurpose.size)) { GNUNET_break_op (0); MAJ_parse_free (spec); return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT, &dr->purpose, &sig.eddsa_signature, &coin_pub->eddsa_pub)) { GNUNET_break_op (0); MAJ_parse_free (spec); return GNUNET_SYSERR; } // FIXME: check sig! TALER_amount_ntoh (&dr_amount, &dr->amount_with_fee); if (0 != TALER_amount_cmp (&dr_amount, &amount)) { GNUNET_break (0); MAJ_parse_free (spec); return GNUNET_SYSERR; } } else if (0 == strcasecmp (type, "MELT")) { const struct TALER_RefreshMeltCoinAffirmationPS *rm; struct TALER_Amount rm_amount; if (details_size != sizeof (struct TALER_RefreshMeltCoinAffirmationPS)) { GNUNET_break_op (0); MAJ_parse_free (spec); return GNUNET_SYSERR; } rm = (const struct TALER_RefreshMeltCoinAffirmationPS *) details; if (details_size != ntohl (rm->purpose.size)) { GNUNET_break_op (0); MAJ_parse_free (spec); return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT, &rm->purpose, &sig.eddsa_signature, &coin_pub->eddsa_pub)) { GNUNET_break_op (0); MAJ_parse_free (spec); return GNUNET_SYSERR; } TALER_amount_ntoh (&rm_amount, &rm->amount_with_fee); if (0 != TALER_amount_cmp (&rm_amount, &amount)) { GNUNET_break_op (0); MAJ_parse_free (spec); return GNUNET_SYSERR; } } else { /* signature not supported, new version on server? */ GNUNET_break_op (0); MAJ_parse_free (spec); return GNUNET_SYSERR; } if (GNUNET_OK != TALER_amount_add (total, total, &amount)) { /* overflow in history already!? inconceivable! Bad mint! */ GNUNET_break_op (0); MAJ_parse_free (spec); return GNUNET_SYSERR; } MAJ_parse_free (spec); } return GNUNET_OK; } /* end of mint_api_common.c */