aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/taler_merchant_service.h64
-rw-r--r--src/lib/merchant_api_post_order_pay.c75
2 files changed, 138 insertions, 1 deletions
diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h
index 057c9eff..180df516 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -3201,6 +3201,38 @@ struct TALER_MERCHANT_PaidCoin
/**
+ * Information the frontend forwards to the backend to use a token for
+ * an order. Note that this does not include the token use private key,
+ * but only public keys and signatures.
+ */
+struct TALER_MERCHANT_UsedToken
+{
+
+ /**
+ * Signature on TALER_TokenUseRequestPS made with the token use private key.
+ */
+ struct TALER_TokenUseSignatureP token_sig;
+
+ /**
+ * Public key of the token. This was blindly signed by the merchant
+ * during the issuance and is now being revealed to the merchant.
+ */
+ struct TALER_TokenUsePublicKeyP token_pub;
+
+ /**
+ * Unblinded signature made by the token issue public key of the merchant.
+ */
+ struct TALER_TokenIssueSignatureP ub_sig;
+
+ /**
+ * Token issue public key associated with this token.
+ */
+ struct TALER_TokenIssuePublicKeyP issue_pub;
+
+};
+
+
+/**
* Pay a merchant. API for frontends talking to backends. Here,
* the frontend does not have the coin's private keys, but just
* the public keys and signatures.
@@ -3215,6 +3247,8 @@ struct TALER_MERCHANT_PaidCoin
* @param wallet_data inputs from the wallet for the contract, NULL for none
* @param num_coins length of the @a coins array
* @param coins array of coins to pay with
+ * @param num_tokens length of the @a tokens array
+ * @param tokens array of tokens used
* @param pay_cb the callback to call when a reply for this request is available
* @param pay_cb_cls closure for @a pay_cb
* @return a handle for this request
@@ -3228,6 +3262,8 @@ TALER_MERCHANT_order_pay_frontend (
const json_t *wallet_data,
unsigned int num_coins,
const struct TALER_MERCHANT_PaidCoin coins[static num_coins],
+ unsigned int num_tokens,
+ const struct TALER_MERCHANT_UsedToken tokens[static num_tokens],
TALER_MERCHANT_OrderPayCallback pay_cb,
void *pay_cb_cls);
@@ -3282,6 +3318,30 @@ struct TALER_MERCHANT_PayCoin
/**
+ * Information we need from the wallet to use a token for an order.
+ */
+struct TALER_MERCHANT_UseToken
+{
+
+ /**
+ * Token use private key. We will derive the public key from this.
+ */
+ struct TALER_TokenUsePrivateKeyP token_priv;
+
+ /**
+ * Unblinded signature made by the token issue public key of the merchant.
+ */
+ struct TALER_TokenIssueSignatureP ub_sig;
+
+ /**
+ * Token issue public key associated with this token.
+ */
+ struct TALER_TokenIssuePublicKeyP issue_pub;
+
+};
+
+
+/**
* Pay a merchant. API for wallets that have the coin's private keys.
*
* This is a PUBLIC API for wallets.
@@ -3302,6 +3362,8 @@ struct TALER_MERCHANT_PayCoin
* @param order_id order id
* @param num_coins number of coins used to pay
* @param coins array of coins we use to pay
+ * @param num_tokens number of tokens to used in this payment request
+ * @param tokens array of tokens we use in this payment request
* @param pay_cb the callback to call when a reply for this request is available
* @param pay_cb_cls closure for @a pay_cb
* @return a handle for this request
@@ -3324,6 +3386,8 @@ TALER_MERCHANT_order_pay (
const char *order_id,
unsigned int num_coins,
const struct TALER_MERCHANT_PayCoin coins[static num_coins],
+ unsigned int num_tokens,
+ const struct TALER_MERCHANT_UseToken tokens[static num_tokens],
TALER_MERCHANT_OrderPayCallback pay_cb,
void *pay_cb_cls);
diff --git a/src/lib/merchant_api_post_order_pay.c b/src/lib/merchant_api_post_order_pay.c
index 57c85565..e56bac60 100644
--- a/src/lib/merchant_api_post_order_pay.c
+++ b/src/lib/merchant_api_post_order_pay.c
@@ -80,6 +80,11 @@ struct TALER_MERCHANT_OrderPayHandle
struct TALER_MERCHANT_PaidCoin *coins;
/**
+ * The tokens we are using.
+ */
+ struct TALER_MERCHANT_UsedToken *tokens;
+
+ /**
* Hash of the contract we are paying, set
* if @e am_wallet is true.
*/
@@ -114,6 +119,11 @@ struct TALER_MERCHANT_OrderPayHandle
unsigned int num_coins;
/**
+ * Number of @e tokens we are using.
+ */
+ unsigned int num_tokens;
+
+ /**
* Set to true if this is the wallet API and we have
* initialized @e h_contract_terms and @e merchant_pub.
*/
@@ -308,12 +318,15 @@ TALER_MERCHANT_order_pay_frontend (
const json_t *wallet_data,
unsigned int num_coins,
const struct TALER_MERCHANT_PaidCoin coins[static num_coins],
+ unsigned int num_tokens,
+ const struct TALER_MERCHANT_UsedToken tokens[static num_tokens],
TALER_MERCHANT_OrderPayCallback pay_cb,
void *pay_cb_cls)
{
struct TALER_MERCHANT_OrderPayHandle *oph;
json_t *pay_obj;
json_t *j_coins;
+ json_t *j_tokens = NULL;
CURL *eh;
struct TALER_Amount total_fee;
struct TALER_Amount total_amount;
@@ -392,10 +405,43 @@ TALER_MERCHANT_order_pay_frontend (
}
}
+ if (0 < num_tokens)
+ {
+ j_tokens = json_array ();
+ GNUNET_assert (NULL != j_tokens);
+ for (unsigned int i = 0; i<num_tokens; i++)
+ {
+ json_t *j_token;
+ const struct TALER_MERCHANT_UsedToken *ut = &tokens[i];
+
+ j_token = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_data_auto ("token_sig",
+ &ut->token_sig),
+ GNUNET_JSON_pack_data_auto ("token_pub",
+ &ut->token_pub),
+ TALER_JSON_pack_token_issue_sig ("ub_sig",
+ &ut->ub_sig),
+ /* TODO: Check if we need a more specific hash, similar to TALER_denom_pub_hash () */
+ GNUNET_JSON_pack_data_auto ("h_issue",
+ &ut->issue_pub.public_key->pub_key_hash));
+ if (0 !=
+ json_array_append_new (j_tokens,
+ j_token))
+ {
+ GNUNET_break (0);
+ json_decref (j_tokens);
+ return NULL;
+ }
+ }
+ }
+
pay_obj = GNUNET_JSON_PACK (
GNUNET_JSON_pack_array_steal ("coins",
j_coins),
GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_array_steal ("tokens",
+ j_tokens)),
+ GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_object_incref ("wallet_data",
(json_t *) wallet_data)),
GNUNET_JSON_pack_allow_null (
@@ -473,11 +519,13 @@ TALER_MERCHANT_order_pay (
const char *order_id,
unsigned int num_coins,
const struct TALER_MERCHANT_PayCoin coins[static num_coins],
+ unsigned int num_tokens,
+ const struct TALER_MERCHANT_UseToken tokens[static num_tokens],
TALER_MERCHANT_OrderPayCallback pay_cb,
void *pay_cb_cls)
{
struct GNUNET_HashCode wallet_data_hash;
-
+
if (GNUNET_YES !=
TALER_amount_cmp_currency (amount,
max_fee))
@@ -485,11 +533,20 @@ TALER_MERCHANT_order_pay (
GNUNET_break (0);
return NULL;
}
+ if (0 < num_tokens && NULL == wallet_data)
+ {
+ /* Since the wallet has to sign over the wallet_data_hash
+ to use tokens, wallet data must not be NULL if input
+ tokens are provided */
+ GNUNET_break (0);
+ return NULL;
+ }
if (NULL != wallet_data)
TALER_json_hash (wallet_data,
&wallet_data_hash);
{
struct TALER_MERCHANT_PaidCoin pc[num_coins];
+ struct TALER_MERCHANT_UsedToken ut[num_tokens];
for (unsigned int i = 0; i<num_coins; i++)
{
@@ -534,6 +591,20 @@ TALER_MERCHANT_order_pay (
p->amount_without_fee = coin->amount_without_fee;
p->exchange_url = coin->exchange_url;
}
+ for (unsigned int i = 0; i<num_tokens; i++)
+ {
+ const struct TALER_MERCHANT_UseToken *token = &tokens[i];
+ struct TALER_MERCHANT_UsedToken *t = &ut[i];
+
+ TALER_wallet_token_use_sign (h_contract_terms,
+ &wallet_data_hash, // checked for != NULL above
+ &token->token_priv,
+ &t->token_sig);
+ t->ub_sig = token->ub_sig;
+ t->issue_pub = token->issue_pub;
+ GNUNET_CRYPTO_eddsa_key_get_public (&token->token_priv.private_key,
+ &t->token_pub.public_key);
+ }
{
struct TALER_MERCHANT_OrderPayHandle *oph;
@@ -544,6 +615,8 @@ TALER_MERCHANT_order_pay (
wallet_data,
num_coins,
pc,
+ num_tokens,
+ ut,
pay_cb,
pay_cb_cls);
if (NULL == oph)