aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mint-lib/mint_api_deposit.c105
-rw-r--r--src/mint-lib/mint_api_json.c38
-rw-r--r--src/mint-lib/mint_api_json.h35
3 files changed, 167 insertions, 11 deletions
diff --git a/src/mint-lib/mint_api_deposit.c b/src/mint-lib/mint_api_deposit.c
index c404676a5..c78680756 100644
--- a/src/mint-lib/mint_api_deposit.c
+++ b/src/mint-lib/mint_api_deposit.c
@@ -93,6 +93,16 @@ struct TALER_MINT_DepositHandle
struct TALER_DepositConfirmationPS depconf;
/**
+ * Value of the /deposit transaction, including fee.
+ */
+ struct TALER_Amount amount_with_fee;
+
+ /**
+ * Total value of the coin being transacted with.
+ */
+ struct TALER_Amount coin_value;
+
+ /**
* The size of the download buffer
*/
size_t buf_size;
@@ -160,19 +170,95 @@ static int
verify_deposit_signature_forbidden (const struct TALER_MINT_DepositHandle *dh,
json_t *json)
{
- struct MAJ_Specification spec[] = {
- MAJ_spec_end
- };
-
- if (GNUNET_OK !=
- MAJ_parse_json (json,
- spec))
+ json_t *history;
+ size_t len;
+ size_t off;
+ struct TALER_Amount total;
+
+ history = json_object_get (json,
+ "history");
+ 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 (dh->coin_value.currency,
+ &total);
+ for (off=0;off<len;off++)
+ {
+ json_t *transaction;
+ struct TALER_Amount amount;
+ struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
+ struct MAJ_Specification spec[] = {
+ MAJ_spec_amount ("amount",
+ &amount),
+ MAJ_spec_eddsa_signed_purpose ("signature",
+ &purpose,
+ &dh->depconf.coin_pub.eddsa_pub),
+ MAJ_spec_end
+ };
+
+ transaction = json_array_get (history,
+ off);
+ if (GNUNET_OK !=
+ MAJ_parse_json (transaction,
+ spec))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ switch (purpose->purpose)
+ {
+ case TALER_SIGNATURE_WALLET_COIN_DEPOSIT:
+ GNUNET_break (0);
+ /* FIXME: check amount! #3516 */
+ break;
+ case TALER_SIGNATURE_WALLET_COIN_MELT:
+ GNUNET_break (0);
+ /* FIXME: check amount! #3516 */
+ break;
+ default:
+ /* signature not supported, new version on server? */
+ GNUNET_break (0);
+ MAJ_parse_free (spec);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK !=
+ TALER_amount_add (&total,
+ &total,
+ &amount))
+ {
+ /* overflow in history already!? inconceivable! */
+ GNUNET_break_op (0);
+ MAJ_parse_free (spec);
+ return GNUNET_SYSERR;
+ }
+ MAJ_parse_free (spec);
+ }
+ if (GNUNET_OK !=
+ TALER_amount_add (&total,
+ &total,
+ &dh->amount_with_fee))
+ {
+ /* clearly not OK if our transaction would have caused
+ the overflow... */
+ return GNUNET_OK;
+ }
- GNUNET_break (0); // not implemented
+ if (0 >= TALER_amount_cmp (&total,
+ &dh->coin_value))
+ {
+ /* transaction should have still fit */
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ /* everything OK, proof of double-spending was provided */
return GNUNET_OK;
}
@@ -530,7 +616,8 @@ TALER_MINT_deposit (struct TALER_MINT_Handle *mint,
&amount_without_fee);
dh->depconf.coin_pub = *coin_pub;
dh->depconf.merchant = *merchant_pub;
-
+ dh->amount_with_fee = *amount;
+ dh->coin_value = dki->value;
eh = curl_easy_init ();
GNUNET_assert (NULL != (dh->json_enc =
diff --git a/src/mint-lib/mint_api_json.c b/src/mint-lib/mint_api_json.c
index b702ba0d9..81511c1c0 100644
--- a/src/mint-lib/mint_api_json.c
+++ b/src/mint-lib/mint_api_json.c
@@ -200,6 +200,17 @@ parse_json (json_t *root,
}
break;
+ case MAJ_CMD_EDDSA_SIGNATURE:
+ {
+ /* FIXME: parse the JSON signature
+ and the purpose, then check that the
+ signature is valid and the size field
+ is also correct; if all checks out,
+ return the purpose */
+ GNUNET_break (0); // FIXME: implement! #3516
+ }
+ break;
+
default:
GNUNET_break (0);
return i;
@@ -248,6 +259,9 @@ parse_free (struct MAJ_Specification *spec,
GNUNET_CRYPTO_rsa_signature_free (*spec[i].details.rsa_signature);
*spec[i].details.rsa_signature = NULL;
break;
+ case MAJ_CMD_EDDSA_SIGNATURE:
+ GNUNET_free (*spec[i].details.eddsa_signature.purpose_p);
+ *spec[i].details.eddsa_signature.purpose_p = NULL;
default:
GNUNET_break (0);
break;
@@ -378,4 +392,28 @@ MAJ_spec_rsa_signature (const char *name,
}
+/**
+ * Specification for parsing an EdDSA object signature with purpose.
+ * Also validates the signature (!).
+ *
+ * @param name name of the JSON field
+ * @param purpose_p where to store the purpose
+ * @param pub_key public key to use for validation
+ */
+struct MAJ_Specification
+MAJ_spec_eddsa_signed_purpose (const char *name,
+ struct GNUNET_CRYPTO_EccSignaturePurpose **purpose_p,
+ const struct GNUNET_CRYPTO_EddsaPublicKey *pub_key)
+{
+ struct MAJ_Specification ret =
+ {
+ .cmd = MAJ_CMD_EDDSA_SIGNATURE,
+ .field = name,
+ .details.eddsa_signature.purpose_p = purpose_p,
+ .details.eddsa_signature.pub_key = pub_key
+ };
+ return ret;
+}
+
+
/* end of mint_api_json.c */
diff --git a/src/mint-lib/mint_api_json.h b/src/mint-lib/mint_api_json.h
index 78107ed9e..91679831d 100644
--- a/src/mint-lib/mint_api_json.h
+++ b/src/mint-lib/mint_api_json.h
@@ -69,9 +69,9 @@ enum MAJ_Command
MAJ_CMD_RSA_SIGNATURE,
/**
- * Parse at current position.
+ * Parse object with EdDSA signature and purpose at current position.
*/
- MAJ_CMD_A,
+ MAJ_CMD_EDDSA_SIGNATURE,
/**
* Parse at current position.
@@ -159,6 +159,23 @@ struct MAJ_Specification
*/
struct GNUNET_CRYPTO_rsa_Signature **rsa_signature;
+ /**
+ * Details for #MAJ_CMD_EDDSA_SIGNATURE
+ */
+ struct {
+
+ /**
+ * Where to store the purpose.
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose **purpose_p;
+
+ /**
+ * Key to verify the signature against.
+ */
+ const struct GNUNET_CRYPTO_EddsaPublicKey *pub_key;
+
+ } eddsa_signature;
+
} details;
};
@@ -224,6 +241,20 @@ MAJ_spec_amount (const char *name,
/**
+ * Specification for parsing an EdDSA object signature with purpose.
+ * Also validates the signature (!).
+ *
+ * @param name name of the JSON field
+ * @param purpose_p where to store the purpose
+ * @param pub_key public key to use for validation
+ */
+struct MAJ_Specification
+MAJ_spec_eddsa_signed_purpose (const char *name,
+ struct GNUNET_CRYPTO_EccSignaturePurpose **purpose_p,
+ const struct GNUNET_CRYPTO_EddsaPublicKey *pub_key);
+
+
+/**
* Specification for parsing an RSA public key.
*
* @param name name of the JSON field