Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2021-2025 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file exchange_signatures.c
18 : * @brief Utility functions for Taler security module signatures
19 : * @author Christian Grothoff
20 : */
21 : #include "taler/taler_util.h"
22 : #include "taler/taler_signatures.h"
23 :
24 :
25 : GNUNET_NETWORK_STRUCT_BEGIN
26 :
27 : /**
28 : * @brief Format used to generate the signature on a confirmation
29 : * from the exchange that a deposit request succeeded.
30 : */
31 : struct TALER_DepositConfirmationPS
32 : {
33 : /**
34 : * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT. Signed
35 : * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
36 : */
37 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
38 :
39 : /**
40 : * Hash over the contract for which this deposit is made.
41 : */
42 : struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
43 :
44 : /**
45 : * Hash over the wiring information of the merchant.
46 : */
47 : struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
48 :
49 : /**
50 : * Hash over the optional policy extension of the deposit, 0 if there
51 : * was no policy.
52 : */
53 : struct TALER_ExtensionPolicyHashP h_policy GNUNET_PACKED;
54 :
55 : /**
56 : * Time when this confirmation was generated / when the exchange received
57 : * the deposit request.
58 : */
59 : struct GNUNET_TIME_TimestampNBO exchange_timestamp;
60 :
61 : /**
62 : * By when does the exchange expect to pay the merchant
63 : * (as per the merchant's request).
64 : */
65 : struct GNUNET_TIME_TimestampNBO wire_deadline;
66 :
67 : /**
68 : * How much time does the @e merchant have to issue a refund
69 : * request? Zero if refunds are not allowed. After this time, the
70 : * coin cannot be refunded. Note that the wire transfer will not be
71 : * performed by the exchange until the refund deadline. This value
72 : * is taken from the original deposit request.
73 : */
74 : struct GNUNET_TIME_TimestampNBO refund_deadline;
75 :
76 : /**
77 : * Amount to be deposited, excluding fee. Calculated from the
78 : * amount with fee and the fee from the deposit request.
79 : */
80 : struct TALER_AmountNBO total_without_fee;
81 :
82 : /**
83 : * Hash over all of the coin signatures.
84 : */
85 : struct GNUNET_HashCode h_coin_sigs;
86 :
87 : /**
88 : * The Merchant's public key. Allows the merchant to later refund
89 : * the transaction or to inquire about the wire transfer identifier.
90 : */
91 : struct TALER_MerchantPublicKeyP merchant_pub;
92 :
93 : };
94 :
95 : GNUNET_NETWORK_STRUCT_END
96 :
97 :
98 : enum TALER_ErrorCode
99 94 : TALER_exchange_online_deposit_confirmation_sign (
100 : TALER_ExchangeSignCallback scb,
101 : const struct TALER_PrivateContractHashP *h_contract_terms,
102 : const struct TALER_MerchantWireHashP *h_wire,
103 : const struct TALER_ExtensionPolicyHashP *h_policy,
104 : struct GNUNET_TIME_Timestamp exchange_timestamp,
105 : struct GNUNET_TIME_Timestamp wire_deadline,
106 : struct GNUNET_TIME_Timestamp refund_deadline,
107 : const struct TALER_Amount *total_without_fee,
108 : unsigned int num_coins,
109 : const struct TALER_CoinSpendSignatureP *coin_sigs[static num_coins],
110 : const struct TALER_MerchantPublicKeyP *merchant_pub,
111 : struct TALER_ExchangePublicKeyP *pub,
112 : struct TALER_ExchangeSignatureP *sig)
113 94 : {
114 188 : struct TALER_DepositConfirmationPS dcs = {
115 94 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
116 94 : .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
117 : .h_contract_terms = *h_contract_terms,
118 : .h_wire = *h_wire,
119 94 : .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
120 94 : .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
121 94 : .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
122 : .merchant_pub = *merchant_pub,
123 : .h_policy = {{{0}}}
124 : };
125 : struct GNUNET_HashContext *hc;
126 :
127 94 : hc = GNUNET_CRYPTO_hash_context_start ();
128 190 : for (unsigned int i = 0; i<num_coins; i++)
129 96 : GNUNET_CRYPTO_hash_context_read (hc,
130 96 : coin_sigs[i],
131 : sizeof (*coin_sigs[i]));
132 94 : GNUNET_CRYPTO_hash_context_finish (hc,
133 : &dcs.h_coin_sigs);
134 94 : if (NULL != h_policy)
135 0 : dcs.h_policy = *h_policy;
136 94 : TALER_amount_hton (&dcs.total_without_fee,
137 : total_without_fee);
138 94 : return scb (&dcs.purpose,
139 : pub,
140 : sig);
141 : }
142 :
143 :
144 : enum GNUNET_GenericReturnValue
145 102 : TALER_exchange_online_deposit_confirmation_verify (
146 : const struct TALER_PrivateContractHashP *h_contract_terms,
147 : const struct TALER_MerchantWireHashP *h_wire,
148 : const struct TALER_ExtensionPolicyHashP *h_policy,
149 : struct GNUNET_TIME_Timestamp exchange_timestamp,
150 : struct GNUNET_TIME_Timestamp wire_deadline,
151 : struct GNUNET_TIME_Timestamp refund_deadline,
152 : const struct TALER_Amount *total_without_fee,
153 : unsigned int num_coins,
154 : const struct TALER_CoinSpendSignatureP *coin_sigs[static num_coins],
155 : const struct TALER_MerchantPublicKeyP *merchant_pub,
156 : const struct TALER_ExchangePublicKeyP *exchange_pub,
157 : const struct TALER_ExchangeSignatureP *exchange_sig)
158 102 : {
159 204 : struct TALER_DepositConfirmationPS dcs = {
160 102 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
161 102 : .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
162 : .h_contract_terms = *h_contract_terms,
163 : .h_wire = *h_wire,
164 102 : .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
165 102 : .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
166 102 : .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
167 : .merchant_pub = *merchant_pub
168 : };
169 : struct GNUNET_HashContext *hc;
170 :
171 102 : hc = GNUNET_CRYPTO_hash_context_start ();
172 206 : for (unsigned int i = 0; i<num_coins; i++)
173 104 : GNUNET_CRYPTO_hash_context_read (hc,
174 104 : coin_sigs[i],
175 : sizeof (*coin_sigs[i]));
176 102 : GNUNET_CRYPTO_hash_context_finish (hc,
177 : &dcs.h_coin_sigs);
178 102 : if (NULL != h_policy)
179 102 : dcs.h_policy = *h_policy;
180 102 : TALER_amount_hton (&dcs.total_without_fee,
181 : total_without_fee);
182 102 : if (GNUNET_OK !=
183 102 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT,
184 : &dcs,
185 : &exchange_sig->eddsa_signature,
186 : &exchange_pub->eddsa_pub))
187 : {
188 0 : GNUNET_break_op (0);
189 0 : return GNUNET_SYSERR;
190 : }
191 102 : return GNUNET_OK;
192 : }
193 :
194 :
195 : GNUNET_NETWORK_STRUCT_BEGIN
196 :
197 : /**
198 : * @brief Format used to generate the signature on a request to refund
199 : * a coin into the account of the customer.
200 : */
201 : struct TALER_RefundConfirmationPS
202 : {
203 : /**
204 : * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND.
205 : */
206 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
207 :
208 : /**
209 : * Hash over the proposal data to identify the contract
210 : * which is being refunded.
211 : */
212 : struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
213 :
214 : /**
215 : * The coin's public key. This is the value that must have been
216 : * signed (blindly) by the Exchange.
217 : */
218 : struct TALER_CoinSpendPublicKeyP coin_pub;
219 :
220 : /**
221 : * The Merchant's public key. Allows the merchant to later refund
222 : * the transaction or to inquire about the wire transfer identifier.
223 : */
224 : struct TALER_MerchantPublicKeyP merchant;
225 :
226 : /**
227 : * Merchant-generated transaction ID for the refund.
228 : */
229 : uint64_t rtransaction_id GNUNET_PACKED;
230 :
231 : /**
232 : * Amount to be refunded, including refund fee charged by the
233 : * exchange to the customer.
234 : */
235 : struct TALER_AmountNBO refund_amount;
236 : };
237 :
238 : GNUNET_NETWORK_STRUCT_END
239 :
240 :
241 : enum TALER_ErrorCode
242 10 : TALER_exchange_online_refund_confirmation_sign (
243 : TALER_ExchangeSignCallback scb,
244 : const struct TALER_PrivateContractHashP *h_contract_terms,
245 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
246 : const struct TALER_MerchantPublicKeyP *merchant,
247 : uint64_t rtransaction_id,
248 : const struct TALER_Amount *refund_amount,
249 : struct TALER_ExchangePublicKeyP *pub,
250 : struct TALER_ExchangeSignatureP *sig)
251 : {
252 20 : struct TALER_RefundConfirmationPS rc = {
253 10 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND),
254 10 : .purpose.size = htonl (sizeof (rc)),
255 : .h_contract_terms = *h_contract_terms,
256 : .coin_pub = *coin_pub,
257 : .merchant = *merchant,
258 10 : .rtransaction_id = GNUNET_htonll (rtransaction_id)
259 : };
260 :
261 10 : TALER_amount_hton (&rc.refund_amount,
262 : refund_amount);
263 10 : return scb (&rc.purpose,
264 : pub,
265 : sig);
266 : }
267 :
268 :
269 : enum GNUNET_GenericReturnValue
270 10 : TALER_exchange_online_refund_confirmation_verify (
271 : const struct TALER_PrivateContractHashP *h_contract_terms,
272 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
273 : const struct TALER_MerchantPublicKeyP *merchant,
274 : uint64_t rtransaction_id,
275 : const struct TALER_Amount *refund_amount,
276 : const struct TALER_ExchangePublicKeyP *pub,
277 : const struct TALER_ExchangeSignatureP *sig)
278 : {
279 20 : struct TALER_RefundConfirmationPS rc = {
280 10 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND),
281 10 : .purpose.size = htonl (sizeof (rc)),
282 : .h_contract_terms = *h_contract_terms,
283 : .coin_pub = *coin_pub,
284 : .merchant = *merchant,
285 10 : .rtransaction_id = GNUNET_htonll (rtransaction_id)
286 : };
287 :
288 10 : TALER_amount_hton (&rc.refund_amount,
289 : refund_amount);
290 10 : if (GNUNET_OK !=
291 10 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND,
292 : &rc,
293 : &sig->eddsa_signature,
294 : &pub->eddsa_pub))
295 : {
296 0 : GNUNET_break_op (0);
297 0 : return GNUNET_SYSERR;
298 : }
299 10 : return GNUNET_OK;
300 : }
301 :
302 :
303 : GNUNET_NETWORK_STRUCT_BEGIN
304 :
305 : /**
306 : * @brief Format of the block signed by the Exchange in response to a successful
307 : * "/refresh/melt" request. Hereby the exchange affirms that all of the
308 : * coins were successfully melted. This also commits the exchange to a
309 : * particular index to not be revealed during the refresh.
310 : */
311 : struct TALER_RefreshMeltConfirmationPS
312 : {
313 : /**
314 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT. Signed
315 : * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
316 : */
317 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
318 :
319 : /**
320 : * Commitment made in the /refresh/melt.
321 : */
322 : struct TALER_RefreshCommitmentP rc GNUNET_PACKED;
323 :
324 : /**
325 : * Index that the client will not have to reveal, in NBO.
326 : * Must be smaller than #TALER_CNC_KAPPA.
327 : */
328 : uint32_t noreveal_index GNUNET_PACKED;
329 :
330 : };
331 :
332 : GNUNET_NETWORK_STRUCT_END
333 :
334 :
335 : enum TALER_ErrorCode
336 40 : TALER_exchange_online_melt_confirmation_sign (
337 : TALER_ExchangeSignCallback scb,
338 : const struct TALER_RefreshCommitmentP *rc,
339 : uint32_t noreveal_index,
340 : struct TALER_ExchangePublicKeyP *pub,
341 : struct TALER_ExchangeSignatureP *sig)
342 : {
343 40 : struct TALER_RefreshMeltConfirmationPS confirm = {
344 40 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
345 40 : .purpose.size = htonl (sizeof (confirm)),
346 : .rc = *rc,
347 40 : .noreveal_index = htonl (noreveal_index)
348 : };
349 :
350 40 : return scb (&confirm.purpose,
351 : pub,
352 : sig);
353 : }
354 :
355 :
356 : enum GNUNET_GenericReturnValue
357 40 : TALER_exchange_online_melt_confirmation_verify (
358 : const struct TALER_RefreshCommitmentP *rc,
359 : uint32_t noreveal_index,
360 : const struct TALER_ExchangePublicKeyP *exchange_pub,
361 : const struct TALER_ExchangeSignatureP *exchange_sig)
362 : {
363 40 : struct TALER_RefreshMeltConfirmationPS confirm = {
364 40 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
365 40 : .purpose.size = htonl (sizeof (confirm)),
366 : .rc = *rc,
367 40 : .noreveal_index = htonl (noreveal_index)
368 : };
369 :
370 : return
371 40 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT,
372 : &confirm,
373 : &exchange_sig->eddsa_signature,
374 : &exchange_pub->eddsa_pub);
375 : }
376 :
377 :
378 : GNUNET_NETWORK_STRUCT_BEGIN
379 :
380 : /**
381 : * @brief Format of the block signed by the Exchange in response to a
382 : * successful "/withdraw" request.
383 : * If age restriction is set, the exchange hereby also
384 : * affirms that the commitment along with the maximum age group and
385 : * the amount were accepted. This also commits the exchange to a particular
386 : * index to not be revealed during the reveal.
387 : */
388 : struct TALER_WithdrawConfirmationPS
389 : {
390 : /**
391 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW. Signed by a
392 : * `struct TALER_ExchangePublicKeyP` using EdDSA.
393 : */
394 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
395 :
396 : /**
397 : * Commitment made in the /withdraw call.
398 : */
399 : struct TALER_HashBlindedPlanchetsP h_planchets GNUNET_PACKED;
400 :
401 : /**
402 : * If age restriction does not apply to this withdrawal,
403 : * (i.e. max_age was not set during the request)
404 : * MUST be 0xFFFFFFFF.
405 : * Otherwise (i.e. age restriction applies):
406 : * index that the client will not have to reveal, in NBO,
407 : * MUST be smaller than #TALER_CNC_KAPPA.
408 : */
409 : uint32_t noreveal_index GNUNET_PACKED;
410 :
411 : };
412 :
413 : GNUNET_NETWORK_STRUCT_END
414 :
415 : enum TALER_ErrorCode
416 3 : TALER_exchange_online_withdraw_age_confirmation_sign (
417 : TALER_ExchangeSignCallback scb,
418 : const struct TALER_HashBlindedPlanchetsP *h_planchets,
419 : uint32_t noreveal_index,
420 : struct TALER_ExchangePublicKeyP *pub,
421 : struct TALER_ExchangeSignatureP *sig)
422 : {
423 :
424 3 : struct TALER_WithdrawConfirmationPS confirm = {
425 3 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW),
426 3 : .purpose.size = htonl (sizeof (confirm)),
427 : .h_planchets = *h_planchets,
428 3 : .noreveal_index = htonl (noreveal_index)
429 : };
430 :
431 3 : return scb (&confirm.purpose,
432 : pub,
433 : sig);
434 : }
435 :
436 :
437 : enum TALER_ErrorCode
438 0 : TALER_exchange_online_withdraw_confirmation_sign (
439 : TALER_ExchangeSignCallback scb,
440 : const struct TALER_HashBlindedPlanchetsP *h_planchets,
441 : struct TALER_ExchangePublicKeyP *pub,
442 : struct TALER_ExchangeSignatureP *sig)
443 : {
444 :
445 0 : struct TALER_WithdrawConfirmationPS confirm = {
446 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW),
447 0 : .purpose.size = htonl (sizeof (confirm)),
448 : .h_planchets = *h_planchets,
449 0 : .noreveal_index = htonl (0xFFFFFFFF)
450 : };
451 :
452 0 : return scb (&confirm.purpose,
453 : pub,
454 : sig);
455 : }
456 :
457 :
458 : enum GNUNET_GenericReturnValue
459 3 : TALER_exchange_online_withdraw_age_confirmation_verify (
460 : const struct TALER_HashBlindedPlanchetsP *h_planchets,
461 : uint32_t noreveal_index,
462 : const struct TALER_ExchangePublicKeyP *exchange_pub,
463 : const struct TALER_ExchangeSignatureP *exchange_sig)
464 : {
465 3 : struct TALER_WithdrawConfirmationPS confirm = {
466 3 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW),
467 3 : .purpose.size = htonl (sizeof (confirm)),
468 : .h_planchets = *h_planchets,
469 3 : .noreveal_index = htonl (noreveal_index)
470 : };
471 :
472 3 : if (GNUNET_OK !=
473 3 : GNUNET_CRYPTO_eddsa_verify (
474 : TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW,
475 : &confirm,
476 : &exchange_sig->eddsa_signature,
477 : &exchange_pub->eddsa_pub))
478 : {
479 0 : GNUNET_break_op (0);
480 0 : return GNUNET_SYSERR;
481 : }
482 3 : return GNUNET_OK;
483 : }
484 :
485 :
486 : enum GNUNET_GenericReturnValue
487 0 : TALER_exchange_online_withdraw_confirmation_verify (
488 : const struct TALER_HashBlindedPlanchetsP *h_planchets,
489 : const struct TALER_ExchangePublicKeyP *exchange_pub,
490 : const struct TALER_ExchangeSignatureP *exchange_sig)
491 : {
492 0 : struct TALER_WithdrawConfirmationPS confirm = {
493 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW),
494 0 : .purpose.size = htonl (sizeof (confirm)),
495 : .h_planchets = *h_planchets,
496 0 : .noreveal_index = htonl (0xFFFFFFFF)
497 : };
498 :
499 0 : if (GNUNET_OK !=
500 0 : GNUNET_CRYPTO_eddsa_verify (
501 : TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW,
502 : &confirm,
503 : &exchange_sig->eddsa_signature,
504 : &exchange_pub->eddsa_pub))
505 : {
506 0 : GNUNET_break_op (0);
507 0 : return GNUNET_SYSERR;
508 : }
509 0 : return GNUNET_OK;
510 : }
511 :
512 :
513 : GNUNET_NETWORK_STRUCT_BEGIN
514 :
515 : /**
516 : * @brief Signature made by the exchange over the full set of keys, used
517 : * to detect cheating exchanges that give out different sets to
518 : * different users.
519 : */
520 : struct TALER_ExchangeKeySetPS
521 : {
522 :
523 : /**
524 : * Purpose is #TALER_SIGNATURE_EXCHANGE_KEY_SET. Signed
525 : * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
526 : */
527 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
528 :
529 : /**
530 : * Time of the key set issue.
531 : */
532 : struct GNUNET_TIME_TimestampNBO list_issue_date;
533 :
534 : /**
535 : * Hash over the various denomination signing keys returned.
536 : */
537 : struct GNUNET_HashCode hc GNUNET_PACKED;
538 : };
539 :
540 : GNUNET_NETWORK_STRUCT_END
541 :
542 :
543 : enum TALER_ErrorCode
544 242 : TALER_exchange_online_key_set_sign (
545 : TALER_ExchangeSignCallback2 scb,
546 : void *cls,
547 : struct GNUNET_TIME_Timestamp timestamp,
548 : const struct GNUNET_HashCode *hc,
549 : struct TALER_ExchangePublicKeyP *pub,
550 : struct TALER_ExchangeSignatureP *sig)
551 : {
552 484 : struct TALER_ExchangeKeySetPS ks = {
553 242 : .purpose.size = htonl (sizeof (ks)),
554 242 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
555 242 : .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp),
556 : .hc = *hc
557 : };
558 :
559 242 : return scb (cls,
560 : &ks.purpose,
561 : pub,
562 : sig);
563 : }
564 :
565 :
566 : enum GNUNET_GenericReturnValue
567 42 : TALER_exchange_online_key_set_verify (
568 : struct GNUNET_TIME_Timestamp timestamp,
569 : const struct GNUNET_HashCode *hc,
570 : const struct TALER_ExchangePublicKeyP *pub,
571 : const struct TALER_ExchangeSignatureP *sig)
572 : {
573 84 : struct TALER_ExchangeKeySetPS ks = {
574 42 : .purpose.size = htonl (sizeof (ks)),
575 42 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
576 42 : .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp),
577 : .hc = *hc
578 : };
579 :
580 : return
581 42 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_KEY_SET,
582 : &ks,
583 : &sig->eddsa_signature,
584 : &pub->eddsa_pub);
585 : }
586 :
587 :
588 : GNUNET_NETWORK_STRUCT_BEGIN
589 :
590 : /**
591 : * @brief Format internally used for packing the detailed information
592 : * to generate the signature for /track/transfer signatures.
593 : */
594 : struct TALER_WireDepositDetailP
595 : {
596 :
597 : /**
598 : * Hash of the contract
599 : */
600 : struct TALER_PrivateContractHashP h_contract_terms;
601 :
602 : /**
603 : * Time when the wire transfer was performed by the exchange.
604 : */
605 : struct GNUNET_TIME_TimestampNBO execution_time;
606 :
607 : /**
608 : * Coin's public key.
609 : */
610 : struct TALER_CoinSpendPublicKeyP coin_pub;
611 :
612 : /**
613 : * Total value of the coin.
614 : */
615 : struct TALER_AmountNBO deposit_value;
616 :
617 : /**
618 : * Fees charged by the exchange for the deposit.
619 : */
620 : struct TALER_AmountNBO deposit_fee;
621 :
622 : };
623 :
624 : GNUNET_NETWORK_STRUCT_END
625 :
626 :
627 : void
628 34 : TALER_exchange_online_wire_deposit_append (
629 : struct GNUNET_HashContext *hash_context,
630 : const struct TALER_PrivateContractHashP *h_contract_terms,
631 : struct GNUNET_TIME_Timestamp execution_time,
632 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
633 : const struct TALER_Amount *deposit_value,
634 : const struct TALER_Amount *deposit_fee)
635 : {
636 68 : struct TALER_WireDepositDetailP dd = {
637 : .h_contract_terms = *h_contract_terms,
638 34 : .execution_time = GNUNET_TIME_timestamp_hton (execution_time),
639 : .coin_pub = *coin_pub
640 : };
641 34 : TALER_amount_hton (&dd.deposit_value,
642 : deposit_value);
643 34 : TALER_amount_hton (&dd.deposit_fee,
644 : deposit_fee);
645 34 : GNUNET_CRYPTO_hash_context_read (hash_context,
646 : &dd,
647 : sizeof (dd));
648 34 : }
649 :
650 :
651 : GNUNET_NETWORK_STRUCT_BEGIN
652 :
653 : /**
654 : * @brief Format used to generate the signature for /wire/deposit
655 : * replies.
656 : */
657 : struct TALER_WireDepositDataPS
658 : {
659 : /**
660 : * Purpose header for the signature over the contract with
661 : * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT.
662 : */
663 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
664 :
665 : /**
666 : * Total amount that was transferred.
667 : */
668 : struct TALER_AmountNBO total;
669 :
670 : /**
671 : * Wire fee that was charged.
672 : */
673 : struct TALER_AmountNBO wire_fee;
674 :
675 : /**
676 : * Public key of the merchant (for all aggregated transactions).
677 : */
678 : struct TALER_MerchantPublicKeyP merchant_pub;
679 :
680 : /**
681 : * Hash of bank account of the merchant.
682 : */
683 : struct TALER_FullPaytoHashP h_payto;
684 :
685 : /**
686 : * Hash of the individual deposits that were aggregated,
687 : * each in the format of a `struct TALER_WireDepositDetailP`.
688 : */
689 : struct GNUNET_HashCode h_details;
690 :
691 : };
692 :
693 : GNUNET_NETWORK_STRUCT_END
694 :
695 :
696 : enum TALER_ErrorCode
697 4 : TALER_exchange_online_wire_deposit_sign (
698 : TALER_ExchangeSignCallback scb,
699 : const struct TALER_Amount *total,
700 : const struct TALER_Amount *wire_fee,
701 : const struct TALER_MerchantPublicKeyP *merchant_pub,
702 : const struct TALER_FullPayto payto,
703 : const struct GNUNET_HashCode *h_details,
704 : struct TALER_ExchangePublicKeyP *pub,
705 : struct TALER_ExchangeSignatureP *sig)
706 : {
707 4 : struct TALER_WireDepositDataPS wdp = {
708 4 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT),
709 4 : .purpose.size = htonl (sizeof (wdp)),
710 : .merchant_pub = *merchant_pub,
711 : .h_details = *h_details
712 : };
713 :
714 4 : TALER_amount_hton (&wdp.total,
715 : total);
716 4 : TALER_amount_hton (&wdp.wire_fee,
717 : wire_fee);
718 4 : TALER_full_payto_hash (payto,
719 : &wdp.h_payto);
720 4 : return scb (&wdp.purpose,
721 : pub,
722 : sig);
723 : }
724 :
725 :
726 : enum GNUNET_GenericReturnValue
727 4 : TALER_exchange_online_wire_deposit_verify (
728 : const struct TALER_Amount *total,
729 : const struct TALER_Amount *wire_fee,
730 : const struct TALER_MerchantPublicKeyP *merchant_pub,
731 : const struct TALER_FullPaytoHashP *h_payto,
732 : const struct GNUNET_HashCode *h_details,
733 : const struct TALER_ExchangePublicKeyP *pub,
734 : const struct TALER_ExchangeSignatureP *sig)
735 : {
736 4 : struct TALER_WireDepositDataPS wdp = {
737 4 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT),
738 4 : .purpose.size = htonl (sizeof (wdp)),
739 : .merchant_pub = *merchant_pub,
740 : .h_details = *h_details,
741 : .h_payto = *h_payto
742 : };
743 :
744 4 : TALER_amount_hton (&wdp.total,
745 : total);
746 4 : TALER_amount_hton (&wdp.wire_fee,
747 : wire_fee);
748 4 : return GNUNET_CRYPTO_eddsa_verify (
749 : TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT,
750 : &wdp,
751 : &sig->eddsa_signature,
752 : &pub->eddsa_pub);
753 : }
754 :
755 :
756 : GNUNET_NETWORK_STRUCT_BEGIN
757 :
758 : /**
759 : * Details affirmed by the exchange about a wire transfer the exchange
760 : * claims to have done with respect to a deposit operation.
761 : */
762 : struct TALER_ConfirmWirePS
763 : {
764 : /**
765 : * Purpose header for the signature over the contract with
766 : * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE.
767 : */
768 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
769 :
770 : /**
771 : * Hash over the wiring information of the merchant.
772 : */
773 : struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
774 :
775 : /**
776 : * Hash over the contract for which this deposit is made.
777 : */
778 : struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
779 :
780 : /**
781 : * Raw value (binary encoding) of the wire transfer subject.
782 : */
783 : struct TALER_WireTransferIdentifierRawP wtid;
784 :
785 : /**
786 : * The coin's public key. This is the value that must have been
787 : * signed (blindly) by the Exchange.
788 : */
789 : struct TALER_CoinSpendPublicKeyP coin_pub;
790 :
791 : /**
792 : * When did the exchange execute this transfer? Note that the
793 : * timestamp may not be exactly the same on the wire, i.e.
794 : * because the wire has a different timezone or resolution.
795 : */
796 : struct GNUNET_TIME_TimestampNBO execution_time;
797 :
798 : /**
799 : * The contribution of @e coin_pub to the total transfer volume.
800 : * This is the value of the deposit minus the fee.
801 : */
802 : struct TALER_AmountNBO coin_contribution;
803 :
804 : };
805 :
806 : GNUNET_NETWORK_STRUCT_END
807 :
808 :
809 : enum TALER_ErrorCode
810 2 : TALER_exchange_online_confirm_wire_sign (
811 : TALER_ExchangeSignCallback scb,
812 : const struct TALER_MerchantWireHashP *h_wire,
813 : const struct TALER_PrivateContractHashP *h_contract_terms,
814 : const struct TALER_WireTransferIdentifierRawP *wtid,
815 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
816 : struct GNUNET_TIME_Timestamp execution_time,
817 : const struct TALER_Amount *coin_contribution,
818 : struct TALER_ExchangePublicKeyP *pub,
819 : struct TALER_ExchangeSignatureP *sig)
820 :
821 : {
822 2 : struct TALER_ConfirmWirePS cw = {
823 2 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE),
824 2 : .purpose.size = htonl (sizeof (cw)),
825 : .h_wire = *h_wire,
826 : .h_contract_terms = *h_contract_terms,
827 : .wtid = *wtid,
828 : .coin_pub = *coin_pub,
829 2 : .execution_time = GNUNET_TIME_timestamp_hton (execution_time)
830 : };
831 :
832 2 : TALER_amount_hton (&cw.coin_contribution,
833 : coin_contribution);
834 2 : return scb (&cw.purpose,
835 : pub,
836 : sig);
837 : }
838 :
839 :
840 : enum GNUNET_GenericReturnValue
841 2 : TALER_exchange_online_confirm_wire_verify (
842 : const struct TALER_MerchantWireHashP *h_wire,
843 : const struct TALER_PrivateContractHashP *h_contract_terms,
844 : const struct TALER_WireTransferIdentifierRawP *wtid,
845 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
846 : struct GNUNET_TIME_Timestamp execution_time,
847 : const struct TALER_Amount *coin_contribution,
848 : const struct TALER_ExchangePublicKeyP *pub,
849 : const struct TALER_ExchangeSignatureP *sig)
850 : {
851 2 : struct TALER_ConfirmWirePS cw = {
852 2 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE),
853 2 : .purpose.size = htonl (sizeof (cw)),
854 : .h_wire = *h_wire,
855 : .h_contract_terms = *h_contract_terms,
856 : .wtid = *wtid,
857 : .coin_pub = *coin_pub,
858 2 : .execution_time = GNUNET_TIME_timestamp_hton (execution_time)
859 : };
860 :
861 2 : TALER_amount_hton (&cw.coin_contribution,
862 : coin_contribution);
863 : return
864 2 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE,
865 : &cw,
866 : &sig->eddsa_signature,
867 : &pub->eddsa_pub);
868 : }
869 :
870 :
871 : GNUNET_NETWORK_STRUCT_BEGIN
872 :
873 : /**
874 : * Response by which the exchange affirms that it will
875 : * refund a coin as part of the emergency /recoup
876 : * protocol. The recoup will go back to the bank
877 : * account that created the reserve.
878 : */
879 : struct TALER_RecoupConfirmationPS
880 : {
881 :
882 : /**
883 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP
884 : */
885 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
886 :
887 : /**
888 : * When did the exchange receive the recoup request?
889 : * Indirectly determines when the wire transfer is (likely)
890 : * to happen.
891 : */
892 : struct GNUNET_TIME_TimestampNBO timestamp;
893 :
894 : /**
895 : * How much of the coin's value will the exchange transfer?
896 : * (Needed in case the coin was partially spent.)
897 : */
898 : struct TALER_AmountNBO recoup_amount;
899 :
900 : /**
901 : * Public key of the coin.
902 : */
903 : struct TALER_CoinSpendPublicKeyP coin_pub;
904 :
905 : /**
906 : * Public key of the reserve that will receive the recoup.
907 : */
908 : struct TALER_ReservePublicKeyP reserve_pub;
909 : };
910 :
911 : GNUNET_NETWORK_STRUCT_END
912 :
913 :
914 : enum TALER_ErrorCode
915 8 : TALER_exchange_online_confirm_recoup_sign (
916 : TALER_ExchangeSignCallback scb,
917 : struct GNUNET_TIME_Timestamp timestamp,
918 : const struct TALER_Amount *recoup_amount,
919 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
920 : const struct TALER_ReservePublicKeyP *reserve_pub,
921 : struct TALER_ExchangePublicKeyP *pub,
922 : struct TALER_ExchangeSignatureP *sig)
923 : {
924 16 : struct TALER_RecoupConfirmationPS pc = {
925 8 : .purpose.size = htonl (sizeof (pc)),
926 8 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
927 8 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
928 : .coin_pub = *coin_pub,
929 : .reserve_pub = *reserve_pub
930 : };
931 :
932 8 : TALER_amount_hton (&pc.recoup_amount,
933 : recoup_amount);
934 8 : return scb (&pc.purpose,
935 : pub,
936 : sig);
937 : }
938 :
939 :
940 : enum GNUNET_GenericReturnValue
941 8 : TALER_exchange_online_confirm_recoup_verify (
942 : struct GNUNET_TIME_Timestamp timestamp,
943 : const struct TALER_Amount *recoup_amount,
944 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
945 : const struct TALER_ReservePublicKeyP *reserve_pub,
946 : const struct TALER_ExchangePublicKeyP *pub,
947 : const struct TALER_ExchangeSignatureP *sig)
948 : {
949 16 : struct TALER_RecoupConfirmationPS pc = {
950 8 : .purpose.size = htonl (sizeof (pc)),
951 8 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
952 8 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
953 : .coin_pub = *coin_pub,
954 : .reserve_pub = *reserve_pub
955 : };
956 :
957 8 : TALER_amount_hton (&pc.recoup_amount,
958 : recoup_amount);
959 : return
960 8 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP,
961 : &pc,
962 : &sig->eddsa_signature,
963 : &pub->eddsa_pub);
964 : }
965 :
966 :
967 : GNUNET_NETWORK_STRUCT_BEGIN
968 :
969 : /**
970 : * Response by which the exchange affirms that it will refund a refreshed coin
971 : * as part of the emergency /recoup protocol. The recoup will go back to the
972 : * old coin's balance.
973 : */
974 : struct TALER_RecoupRefreshConfirmationPS
975 : {
976 :
977 : /**
978 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH
979 : */
980 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
981 :
982 : /**
983 : * When did the exchange receive the recoup request?
984 : * Indirectly determines when the wire transfer is (likely)
985 : * to happen.
986 : */
987 : struct GNUNET_TIME_TimestampNBO timestamp;
988 :
989 : /**
990 : * How much of the coin's value will the exchange transfer?
991 : * (Needed in case the coin was partially spent.)
992 : */
993 : struct TALER_AmountNBO recoup_amount;
994 :
995 : /**
996 : * Public key of the refreshed coin.
997 : */
998 : struct TALER_CoinSpendPublicKeyP coin_pub;
999 :
1000 : /**
1001 : * Public key of the old coin that will receive the recoup.
1002 : */
1003 : struct TALER_CoinSpendPublicKeyP old_coin_pub;
1004 : };
1005 :
1006 : GNUNET_NETWORK_STRUCT_END
1007 :
1008 :
1009 : enum TALER_ErrorCode
1010 0 : TALER_exchange_online_confirm_recoup_refresh_sign (
1011 : TALER_ExchangeSignCallback scb,
1012 : struct GNUNET_TIME_Timestamp timestamp,
1013 : const struct TALER_Amount *recoup_amount,
1014 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
1015 : const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
1016 : struct TALER_ExchangePublicKeyP *pub,
1017 : struct TALER_ExchangeSignatureP *sig)
1018 : {
1019 0 : struct TALER_RecoupRefreshConfirmationPS pc = {
1020 0 : .purpose.purpose = htonl (
1021 : TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
1022 0 : .purpose.size = htonl (sizeof (pc)),
1023 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1024 : .coin_pub = *coin_pub,
1025 : .old_coin_pub = *old_coin_pub
1026 : };
1027 :
1028 0 : TALER_amount_hton (&pc.recoup_amount,
1029 : recoup_amount);
1030 0 : return scb (&pc.purpose,
1031 : pub,
1032 : sig);
1033 : }
1034 :
1035 :
1036 : enum GNUNET_GenericReturnValue
1037 0 : TALER_exchange_online_confirm_recoup_refresh_verify (
1038 : struct GNUNET_TIME_Timestamp timestamp,
1039 : const struct TALER_Amount *recoup_amount,
1040 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
1041 : const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
1042 : const struct TALER_ExchangePublicKeyP *pub,
1043 : const struct TALER_ExchangeSignatureP *sig)
1044 : {
1045 0 : struct TALER_RecoupRefreshConfirmationPS pc = {
1046 0 : .purpose.purpose = htonl (
1047 : TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
1048 0 : .purpose.size = htonl (sizeof (pc)),
1049 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1050 : .coin_pub = *coin_pub,
1051 : .old_coin_pub = *old_coin_pub
1052 : };
1053 :
1054 0 : TALER_amount_hton (&pc.recoup_amount,
1055 : recoup_amount);
1056 :
1057 : return
1058 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH,
1059 : &pc,
1060 : &sig->eddsa_signature,
1061 : &pub->eddsa_pub);
1062 : }
1063 :
1064 :
1065 : void
1066 74 : TALER_recoup_batch_hash (
1067 : size_t num_recoups,
1068 : const struct TALER_RecoupedCoin recoups[static num_recoups],
1069 : struct GNUNET_HashCode *h_recoups)
1070 74 : {
1071 : struct GNUNET_HashContext *hc;
1072 :
1073 74 : hc = GNUNET_CRYPTO_hash_context_start ();
1074 164 : for (size_t i = 0; i < num_recoups; i++)
1075 : {
1076 : struct TALER_AmountNBO amount_nbo;
1077 :
1078 90 : GNUNET_CRYPTO_hash_context_read (hc,
1079 90 : &recoups[i].coin_pub,
1080 : sizeof (recoups[i].coin_pub));
1081 90 : TALER_amount_hton (&amount_nbo,
1082 90 : &recoups[i].amount);
1083 90 : GNUNET_CRYPTO_hash_context_read (hc,
1084 : &amount_nbo,
1085 : sizeof (amount_nbo));
1086 : }
1087 74 : GNUNET_CRYPTO_hash_context_finish (hc,
1088 : h_recoups);
1089 74 : }
1090 :
1091 :
1092 : GNUNET_NETWORK_STRUCT_BEGIN
1093 :
1094 : /**
1095 : * Response by which the exchange affirms that it credited a reserve
1096 : * for all coins recouped in one /recoup-withdraw request.
1097 : */
1098 : struct TALER_RecoupWithdrawBatchConfirmationPS
1099 : {
1100 :
1101 : /**
1102 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_WITHDRAW_BATCH
1103 : */
1104 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1105 :
1106 : /**
1107 : * When did the exchange accept the recoup request?
1108 : */
1109 : struct GNUNET_TIME_TimestampNBO timestamp;
1110 :
1111 : /**
1112 : * Public key of the reserve that was credited.
1113 : */
1114 : struct TALER_ReservePublicKeyP reserve_pub;
1115 :
1116 : /**
1117 : * Commitment of the withdraw operation the coins originated from.
1118 : */
1119 : struct TALER_HashBlindedPlanchetsP planchets_h;
1120 :
1121 : /**
1122 : * Total amount credited to the reserve.
1123 : */
1124 : struct TALER_AmountNBO total_amount;
1125 :
1126 : /**
1127 : * Hash over the recouped coins and their amounts,
1128 : * see #TALER_recoup_batch_hash().
1129 : */
1130 : struct GNUNET_HashCode h_recoups;
1131 : };
1132 :
1133 : GNUNET_NETWORK_STRUCT_END
1134 :
1135 :
1136 : enum TALER_ErrorCode
1137 19 : TALER_exchange_online_confirm_recoup_withdraw_batch_sign (
1138 : TALER_ExchangeSignCallback scb,
1139 : struct GNUNET_TIME_Timestamp timestamp,
1140 : const struct TALER_ReservePublicKeyP *reserve_pub,
1141 : const struct TALER_HashBlindedPlanchetsP *planchets_h,
1142 : const struct TALER_Amount *total_amount,
1143 : const struct GNUNET_HashCode *h_recoups,
1144 : struct TALER_ExchangePublicKeyP *pub,
1145 : struct TALER_ExchangeSignatureP *sig)
1146 : {
1147 38 : struct TALER_RecoupWithdrawBatchConfirmationPS pc = {
1148 19 : .purpose.size = htonl (sizeof (pc)),
1149 19 : .purpose.purpose = htonl (
1150 : TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_WITHDRAW_BATCH),
1151 19 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1152 : .reserve_pub = *reserve_pub,
1153 : .planchets_h = *planchets_h,
1154 : .h_recoups = *h_recoups
1155 : };
1156 :
1157 19 : TALER_amount_hton (&pc.total_amount,
1158 : total_amount);
1159 19 : return scb (&pc.purpose,
1160 : pub,
1161 : sig);
1162 : }
1163 :
1164 :
1165 : enum GNUNET_GenericReturnValue
1166 21 : TALER_exchange_online_confirm_recoup_withdraw_batch_verify (
1167 : struct GNUNET_TIME_Timestamp timestamp,
1168 : const struct TALER_ReservePublicKeyP *reserve_pub,
1169 : const struct TALER_HashBlindedPlanchetsP *planchets_h,
1170 : const struct TALER_Amount *total_amount,
1171 : const struct GNUNET_HashCode *h_recoups,
1172 : const struct TALER_ExchangePublicKeyP *pub,
1173 : const struct TALER_ExchangeSignatureP *sig)
1174 : {
1175 42 : struct TALER_RecoupWithdrawBatchConfirmationPS pc = {
1176 21 : .purpose.size = htonl (sizeof (pc)),
1177 21 : .purpose.purpose = htonl (
1178 : TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_WITHDRAW_BATCH),
1179 21 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1180 : .reserve_pub = *reserve_pub,
1181 : .planchets_h = *planchets_h,
1182 : .h_recoups = *h_recoups
1183 : };
1184 :
1185 21 : TALER_amount_hton (&pc.total_amount,
1186 : total_amount);
1187 : return
1188 21 : GNUNET_CRYPTO_eddsa_verify (
1189 : TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_WITHDRAW_BATCH,
1190 : &pc,
1191 : &sig->eddsa_signature,
1192 : &pub->eddsa_pub);
1193 : }
1194 :
1195 :
1196 : GNUNET_NETWORK_STRUCT_BEGIN
1197 :
1198 : /**
1199 : * Response by which the exchange affirms that it credited an old coin
1200 : * for all coins recouped in one /recoup-refresh request.
1201 : */
1202 : struct TALER_RecoupRefreshBatchConfirmationPS
1203 : {
1204 :
1205 : /**
1206 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH_BATCH
1207 : */
1208 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1209 :
1210 : /**
1211 : * When did the exchange accept the recoup request?
1212 : */
1213 : struct GNUNET_TIME_TimestampNBO timestamp;
1214 :
1215 : /**
1216 : * Public key of the old coin that was credited.
1217 : */
1218 : struct TALER_CoinSpendPublicKeyP old_coin_pub;
1219 :
1220 : /**
1221 : * Commitment of the refresh operation the coins originated from.
1222 : */
1223 : struct TALER_RefreshCommitmentP rc;
1224 :
1225 : /**
1226 : * Total amount credited to the old coin.
1227 : */
1228 : struct TALER_AmountNBO total_amount;
1229 :
1230 : /**
1231 : * Hash over the recouped coins and their amounts,
1232 : * see #TALER_recoup_batch_hash().
1233 : */
1234 : struct GNUNET_HashCode h_recoups;
1235 : };
1236 :
1237 : GNUNET_NETWORK_STRUCT_END
1238 :
1239 :
1240 : enum TALER_ErrorCode
1241 19 : TALER_exchange_online_confirm_recoup_refresh_batch_sign (
1242 : TALER_ExchangeSignCallback scb,
1243 : struct GNUNET_TIME_Timestamp timestamp,
1244 : const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
1245 : const struct TALER_RefreshCommitmentP *rc,
1246 : const struct TALER_Amount *total_amount,
1247 : const struct GNUNET_HashCode *h_recoups,
1248 : struct TALER_ExchangePublicKeyP *pub,
1249 : struct TALER_ExchangeSignatureP *sig)
1250 : {
1251 38 : struct TALER_RecoupRefreshBatchConfirmationPS pc = {
1252 19 : .purpose.size = htonl (sizeof (pc)),
1253 19 : .purpose.purpose = htonl (
1254 : TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH_BATCH),
1255 19 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1256 : .old_coin_pub = *old_coin_pub,
1257 : .rc = *rc,
1258 : .h_recoups = *h_recoups
1259 : };
1260 :
1261 19 : TALER_amount_hton (&pc.total_amount,
1262 : total_amount);
1263 19 : return scb (&pc.purpose,
1264 : pub,
1265 : sig);
1266 : }
1267 :
1268 :
1269 : enum GNUNET_GenericReturnValue
1270 20 : TALER_exchange_online_confirm_recoup_refresh_batch_verify (
1271 : struct GNUNET_TIME_Timestamp timestamp,
1272 : const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
1273 : const struct TALER_RefreshCommitmentP *rc,
1274 : const struct TALER_Amount *total_amount,
1275 : const struct GNUNET_HashCode *h_recoups,
1276 : const struct TALER_ExchangePublicKeyP *pub,
1277 : const struct TALER_ExchangeSignatureP *sig)
1278 : {
1279 40 : struct TALER_RecoupRefreshBatchConfirmationPS pc = {
1280 20 : .purpose.size = htonl (sizeof (pc)),
1281 20 : .purpose.purpose = htonl (
1282 : TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH_BATCH),
1283 20 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1284 : .old_coin_pub = *old_coin_pub,
1285 : .rc = *rc,
1286 : .h_recoups = *h_recoups
1287 : };
1288 :
1289 20 : TALER_amount_hton (&pc.total_amount,
1290 : total_amount);
1291 : return
1292 20 : GNUNET_CRYPTO_eddsa_verify (
1293 : TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH_BATCH,
1294 : &pc,
1295 : &sig->eddsa_signature,
1296 : &pub->eddsa_pub);
1297 : }
1298 :
1299 :
1300 : GNUNET_NETWORK_STRUCT_BEGIN
1301 :
1302 : /**
1303 : * Response by which the exchange affirms that it does not
1304 : * currently know a denomination by the given hash.
1305 : */
1306 : struct TALER_DenominationUnknownAffirmationPS
1307 : {
1308 :
1309 : /**
1310 : * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN
1311 : */
1312 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1313 :
1314 : /**
1315 : * When did the exchange sign this message.
1316 : */
1317 : struct GNUNET_TIME_TimestampNBO timestamp;
1318 :
1319 : /**
1320 : * Hash of the public denomination key we do not know.
1321 : */
1322 : struct TALER_DenominationHashP h_denom_pub;
1323 : };
1324 :
1325 : GNUNET_NETWORK_STRUCT_END
1326 :
1327 :
1328 : enum TALER_ErrorCode
1329 0 : TALER_exchange_online_denomination_unknown_sign (
1330 : TALER_ExchangeSignCallback scb,
1331 : struct GNUNET_TIME_Timestamp timestamp,
1332 : const struct TALER_DenominationHashP *h_denom_pub,
1333 : struct TALER_ExchangePublicKeyP *pub,
1334 : struct TALER_ExchangeSignatureP *sig)
1335 : {
1336 0 : struct TALER_DenominationUnknownAffirmationPS dua = {
1337 0 : .purpose.size = htonl (sizeof (dua)),
1338 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
1339 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1340 : .h_denom_pub = *h_denom_pub,
1341 : };
1342 :
1343 0 : return scb (&dua.purpose,
1344 : pub,
1345 : sig);
1346 : }
1347 :
1348 :
1349 : enum GNUNET_GenericReturnValue
1350 0 : TALER_exchange_online_denomination_unknown_verify (
1351 : struct GNUNET_TIME_Timestamp timestamp,
1352 : const struct TALER_DenominationHashP *h_denom_pub,
1353 : const struct TALER_ExchangePublicKeyP *pub,
1354 : const struct TALER_ExchangeSignatureP *sig)
1355 : {
1356 0 : struct TALER_DenominationUnknownAffirmationPS dua = {
1357 0 : .purpose.size = htonl (sizeof (dua)),
1358 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
1359 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1360 : .h_denom_pub = *h_denom_pub,
1361 : };
1362 :
1363 : return
1364 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN,
1365 : &dua,
1366 : &sig->eddsa_signature,
1367 : &pub->eddsa_pub);
1368 : }
1369 :
1370 :
1371 : GNUNET_NETWORK_STRUCT_BEGIN
1372 :
1373 : /**
1374 : * Response by which the exchange affirms that it does not
1375 : * currently consider the given denomination to be valid
1376 : * for the requested operation.
1377 : */
1378 : struct TALER_DenominationExpiredAffirmationPS
1379 : {
1380 :
1381 : /**
1382 : * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED
1383 : */
1384 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1385 :
1386 : /**
1387 : * When did the exchange sign this message.
1388 : */
1389 : struct GNUNET_TIME_TimestampNBO timestamp;
1390 :
1391 : /**
1392 : * Name of the operation that is not allowed at this time. Might NOT be 0-terminated, but is padded with 0s.
1393 : */
1394 : char operation[8];
1395 :
1396 : /**
1397 : * Hash of the public denomination key we do not know.
1398 : */
1399 : struct TALER_DenominationHashP h_denom_pub;
1400 :
1401 : };
1402 :
1403 : GNUNET_NETWORK_STRUCT_END
1404 :
1405 :
1406 : enum TALER_ErrorCode
1407 6 : TALER_exchange_online_denomination_expired_sign (
1408 : TALER_ExchangeSignCallback scb,
1409 : struct GNUNET_TIME_Timestamp timestamp,
1410 : const struct TALER_DenominationHashP *h_denom_pub,
1411 : const char *op,
1412 : struct TALER_ExchangePublicKeyP *pub,
1413 : struct TALER_ExchangeSignatureP *sig)
1414 : {
1415 12 : struct TALER_DenominationExpiredAffirmationPS dua = {
1416 6 : .purpose.size = htonl (sizeof (dua)),
1417 6 : .purpose.purpose = htonl (
1418 : TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
1419 6 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1420 : .h_denom_pub = *h_denom_pub,
1421 : };
1422 :
1423 : /* strncpy would create a compiler warning */
1424 6 : GNUNET_memcpy (dua.operation,
1425 : op,
1426 : GNUNET_MIN (sizeof (dua.operation),
1427 : strlen (op)));
1428 6 : return scb (&dua.purpose,
1429 : pub,
1430 : sig);
1431 : }
1432 :
1433 :
1434 : enum GNUNET_GenericReturnValue
1435 0 : TALER_exchange_online_denomination_expired_verify (
1436 : struct GNUNET_TIME_Timestamp timestamp,
1437 : const struct TALER_DenominationHashP *h_denom_pub,
1438 : const char *op,
1439 : const struct TALER_ExchangePublicKeyP *pub,
1440 : const struct TALER_ExchangeSignatureP *sig)
1441 : {
1442 0 : struct TALER_DenominationExpiredAffirmationPS dua = {
1443 0 : .purpose.size = htonl (sizeof (dua)),
1444 0 : .purpose.purpose = htonl (
1445 : TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
1446 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1447 : .h_denom_pub = *h_denom_pub,
1448 : };
1449 :
1450 : /* strncpy would create a compiler warning */
1451 0 : GNUNET_memcpy (dua.operation,
1452 : op,
1453 : GNUNET_MIN (sizeof (dua.operation),
1454 : strlen (op)));
1455 : return
1456 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED,
1457 : &dua,
1458 : &sig->eddsa_signature,
1459 : &pub->eddsa_pub);
1460 : }
1461 :
1462 :
1463 : GNUNET_NETWORK_STRUCT_BEGIN
1464 :
1465 : /**
1466 : * Response by which the exchange affirms that it has
1467 : * closed a reserve and send back the funds.
1468 : */
1469 : struct TALER_ReserveCloseConfirmationPS
1470 : {
1471 :
1472 : /**
1473 : * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED
1474 : */
1475 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1476 :
1477 : /**
1478 : * When did the exchange initiate the wire transfer.
1479 : */
1480 : struct GNUNET_TIME_TimestampNBO timestamp;
1481 :
1482 : /**
1483 : * How much did the exchange send?
1484 : */
1485 : struct TALER_AmountNBO closing_amount;
1486 :
1487 : /**
1488 : * How much did the exchange charge for closing the reserve?
1489 : */
1490 : struct TALER_AmountNBO closing_fee;
1491 :
1492 : /**
1493 : * Public key of the reserve that was closed.
1494 : */
1495 : struct TALER_ReservePublicKeyP reserve_pub;
1496 :
1497 : /**
1498 : * Hash of the receiver's bank account.
1499 : */
1500 : struct TALER_FullPaytoHashP h_payto;
1501 :
1502 : /**
1503 : * Wire transfer subject.
1504 : */
1505 : struct TALER_WireTransferIdentifierRawP wtid;
1506 : };
1507 :
1508 : GNUNET_NETWORK_STRUCT_END
1509 :
1510 :
1511 : enum TALER_ErrorCode
1512 0 : TALER_exchange_online_reserve_closed_sign (
1513 : TALER_ExchangeSignCallback scb,
1514 : struct GNUNET_TIME_Timestamp timestamp,
1515 : const struct TALER_Amount *closing_amount,
1516 : const struct TALER_Amount *closing_fee,
1517 : const struct TALER_FullPayto payto,
1518 : const struct TALER_WireTransferIdentifierRawP *wtid,
1519 : const struct TALER_ReservePublicKeyP *reserve_pub,
1520 : struct TALER_ExchangePublicKeyP *pub,
1521 : struct TALER_ExchangeSignatureP *sig)
1522 : {
1523 0 : struct TALER_ReserveCloseConfirmationPS rcc = {
1524 0 : .purpose.size = htonl (sizeof (rcc)),
1525 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED),
1526 : .wtid = *wtid,
1527 : .reserve_pub = *reserve_pub,
1528 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp)
1529 : };
1530 :
1531 0 : TALER_amount_hton (&rcc.closing_amount,
1532 : closing_amount);
1533 0 : TALER_amount_hton (&rcc.closing_fee,
1534 : closing_fee);
1535 0 : TALER_full_payto_hash (payto,
1536 : &rcc.h_payto);
1537 0 : return scb (&rcc.purpose,
1538 : pub,
1539 : sig);
1540 : }
1541 :
1542 :
1543 : enum GNUNET_GenericReturnValue
1544 0 : TALER_exchange_online_reserve_closed_verify (
1545 : struct GNUNET_TIME_Timestamp timestamp,
1546 : const struct TALER_Amount *closing_amount,
1547 : const struct TALER_Amount *closing_fee,
1548 : const struct TALER_FullPayto payto,
1549 : const struct TALER_WireTransferIdentifierRawP *wtid,
1550 : const struct TALER_ReservePublicKeyP *reserve_pub,
1551 : const struct TALER_ExchangePublicKeyP *pub,
1552 : const struct TALER_ExchangeSignatureP *sig)
1553 : {
1554 0 : struct TALER_ReserveCloseConfirmationPS rcc = {
1555 0 : .purpose.size = htonl (sizeof (rcc)),
1556 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED),
1557 : .wtid = *wtid,
1558 : .reserve_pub = *reserve_pub,
1559 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp)
1560 : };
1561 :
1562 0 : TALER_amount_hton (&rcc.closing_amount,
1563 : closing_amount);
1564 0 : TALER_amount_hton (&rcc.closing_fee,
1565 : closing_fee);
1566 0 : TALER_full_payto_hash (payto,
1567 : &rcc.h_payto);
1568 0 : return GNUNET_CRYPTO_eddsa_verify (
1569 : TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED,
1570 : &rcc,
1571 : &sig->eddsa_signature,
1572 : &pub->eddsa_pub);
1573 : }
1574 :
1575 :
1576 : GNUNET_NETWORK_STRUCT_BEGIN
1577 :
1578 : /**
1579 : * Response by which the exchange affirms that it has
1580 : * received funds deposited into a purse.
1581 : */
1582 : struct TALER_PurseCreateDepositConfirmationPS
1583 : {
1584 :
1585 : /**
1586 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION
1587 : */
1588 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1589 :
1590 : /**
1591 : * When did the exchange receive the deposits.
1592 : */
1593 : struct GNUNET_TIME_TimestampNBO exchange_time;
1594 :
1595 : /**
1596 : * When will the purse expire?
1597 : */
1598 : struct GNUNET_TIME_TimestampNBO purse_expiration;
1599 :
1600 : /**
1601 : * How much should the purse ultimately contain.
1602 : */
1603 : struct TALER_AmountNBO amount_without_fee;
1604 :
1605 : /**
1606 : * How much was deposited so far.
1607 : */
1608 : struct TALER_AmountNBO total_deposited;
1609 :
1610 : /**
1611 : * Public key of the purse.
1612 : */
1613 : struct TALER_PurseContractPublicKeyP purse_pub;
1614 :
1615 : /**
1616 : * Hash of the contract of the purse.
1617 : */
1618 : struct TALER_PrivateContractHashP h_contract_terms;
1619 :
1620 : };
1621 :
1622 : GNUNET_NETWORK_STRUCT_END
1623 :
1624 :
1625 : enum TALER_ErrorCode
1626 25 : TALER_exchange_online_purse_created_sign (
1627 : TALER_ExchangeSignCallback scb,
1628 : struct GNUNET_TIME_Timestamp exchange_time,
1629 : struct GNUNET_TIME_Timestamp purse_expiration,
1630 : const struct TALER_Amount *amount_without_fee,
1631 : const struct TALER_Amount *total_deposited,
1632 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1633 : const struct TALER_PrivateContractHashP *h_contract_terms,
1634 : struct TALER_ExchangePublicKeyP *pub,
1635 : struct TALER_ExchangeSignatureP *sig)
1636 : {
1637 50 : struct TALER_PurseCreateDepositConfirmationPS dc = {
1638 25 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION),
1639 25 : .purpose.size = htonl (sizeof (dc)),
1640 : .h_contract_terms = *h_contract_terms,
1641 : .purse_pub = *purse_pub,
1642 25 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1643 25 : .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
1644 : };
1645 :
1646 25 : TALER_amount_hton (&dc.amount_without_fee,
1647 : amount_without_fee);
1648 25 : TALER_amount_hton (&dc.total_deposited,
1649 : total_deposited);
1650 25 : return scb (&dc.purpose,
1651 : pub,
1652 : sig);
1653 : }
1654 :
1655 :
1656 : enum GNUNET_GenericReturnValue
1657 25 : TALER_exchange_online_purse_created_verify (
1658 : struct GNUNET_TIME_Timestamp exchange_time,
1659 : struct GNUNET_TIME_Timestamp purse_expiration,
1660 : const struct TALER_Amount *amount_without_fee,
1661 : const struct TALER_Amount *total_deposited,
1662 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1663 : const struct TALER_PrivateContractHashP *h_contract_terms,
1664 : const struct TALER_ExchangePublicKeyP *pub,
1665 : const struct TALER_ExchangeSignatureP *sig)
1666 : {
1667 50 : struct TALER_PurseCreateDepositConfirmationPS dc = {
1668 25 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION),
1669 25 : .purpose.size = htonl (sizeof (dc)),
1670 : .h_contract_terms = *h_contract_terms,
1671 : .purse_pub = *purse_pub,
1672 25 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1673 25 : .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
1674 : };
1675 :
1676 25 : TALER_amount_hton (&dc.amount_without_fee,
1677 : amount_without_fee);
1678 25 : TALER_amount_hton (&dc.total_deposited,
1679 : total_deposited);
1680 25 : return GNUNET_CRYPTO_eddsa_verify (
1681 : TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION,
1682 : &dc,
1683 : &sig->eddsa_signature,
1684 : &pub->eddsa_pub);
1685 : }
1686 :
1687 :
1688 : GNUNET_NETWORK_STRUCT_BEGIN
1689 :
1690 : /**
1691 : * Response by which the exchange affirms that it has
1692 : * received funds deposited into a purse.
1693 : */
1694 : struct TALER_CoinPurseRefundConfirmationPS
1695 : {
1696 :
1697 : /**
1698 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND
1699 : */
1700 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1701 :
1702 : /**
1703 : * Public key of the purse.
1704 : */
1705 : struct TALER_PurseContractPublicKeyP purse_pub;
1706 :
1707 : /**
1708 : * Public key of the coin.
1709 : */
1710 : struct TALER_CoinSpendPublicKeyP coin_pub;
1711 :
1712 : /**
1713 : * How much will be refunded to the purse.
1714 : */
1715 : struct TALER_AmountNBO refunded_amount;
1716 :
1717 : /**
1718 : * How much was the refund fee.
1719 : */
1720 : struct TALER_AmountNBO refund_fee;
1721 :
1722 : };
1723 :
1724 : GNUNET_NETWORK_STRUCT_END
1725 :
1726 :
1727 : enum TALER_ErrorCode
1728 0 : TALER_exchange_online_purse_refund_sign (
1729 : TALER_ExchangeSignCallback scb,
1730 : const struct TALER_Amount *amount_without_fee,
1731 : const struct TALER_Amount *refund_fee,
1732 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
1733 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1734 : struct TALER_ExchangePublicKeyP *pub,
1735 : struct TALER_ExchangeSignatureP *sig)
1736 : {
1737 0 : struct TALER_CoinPurseRefundConfirmationPS dc = {
1738 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND),
1739 0 : .purpose.size = htonl (sizeof (dc)),
1740 : .coin_pub = *coin_pub,
1741 : .purse_pub = *purse_pub,
1742 : };
1743 :
1744 0 : TALER_amount_hton (&dc.refunded_amount,
1745 : amount_without_fee);
1746 0 : TALER_amount_hton (&dc.refund_fee,
1747 : refund_fee);
1748 0 : return scb (&dc.purpose,
1749 : pub,
1750 : sig);
1751 : }
1752 :
1753 :
1754 : enum GNUNET_GenericReturnValue
1755 0 : TALER_exchange_online_purse_refund_verify (
1756 : const struct TALER_Amount *amount_without_fee,
1757 : const struct TALER_Amount *refund_fee,
1758 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
1759 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1760 : const struct TALER_ExchangePublicKeyP *pub,
1761 : const struct TALER_ExchangeSignatureP *sig)
1762 : {
1763 0 : struct TALER_CoinPurseRefundConfirmationPS dc = {
1764 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND),
1765 0 : .purpose.size = htonl (sizeof (dc)),
1766 : .coin_pub = *coin_pub,
1767 : .purse_pub = *purse_pub,
1768 : };
1769 :
1770 0 : TALER_amount_hton (&dc.refunded_amount,
1771 : amount_without_fee);
1772 0 : TALER_amount_hton (&dc.refund_fee,
1773 : refund_fee);
1774 0 : return GNUNET_CRYPTO_eddsa_verify (
1775 : TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND,
1776 : &dc,
1777 : &sig->eddsa_signature,
1778 : &pub->eddsa_pub);
1779 : }
1780 :
1781 :
1782 : GNUNET_NETWORK_STRUCT_BEGIN
1783 :
1784 : /**
1785 : * Response by which the exchange affirms that it has
1786 : * merged a purse into a reserve.
1787 : */
1788 : struct TALER_PurseMergedConfirmationPS
1789 : {
1790 :
1791 : /**
1792 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED
1793 : */
1794 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1795 :
1796 : /**
1797 : * When did the exchange receive the deposits.
1798 : */
1799 : struct GNUNET_TIME_TimestampNBO exchange_time;
1800 :
1801 : /**
1802 : * When will the purse expire?
1803 : */
1804 : struct GNUNET_TIME_TimestampNBO purse_expiration;
1805 :
1806 : /**
1807 : * How much should the purse ultimately contain.
1808 : */
1809 : struct TALER_AmountNBO amount_without_fee;
1810 :
1811 : /**
1812 : * Public key of the purse.
1813 : */
1814 : struct TALER_PurseContractPublicKeyP purse_pub;
1815 :
1816 : /**
1817 : * Public key of the reserve.
1818 : */
1819 : struct TALER_ReservePublicKeyP reserve_pub;
1820 :
1821 : /**
1822 : * Hash of the contract of the purse.
1823 : */
1824 : struct TALER_PrivateContractHashP h_contract_terms;
1825 :
1826 : /**
1827 : * Hash of the provider URL hosting the reserve.
1828 : */
1829 : struct GNUNET_HashCode h_provider_url;
1830 :
1831 : };
1832 :
1833 : GNUNET_NETWORK_STRUCT_END
1834 :
1835 :
1836 : enum TALER_ErrorCode
1837 3 : TALER_exchange_online_purse_merged_sign (
1838 : TALER_ExchangeSignCallback scb,
1839 : struct GNUNET_TIME_Timestamp exchange_time,
1840 : struct GNUNET_TIME_Timestamp purse_expiration,
1841 : const struct TALER_Amount *amount_without_fee,
1842 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1843 : const struct TALER_PrivateContractHashP *h_contract_terms,
1844 : const struct TALER_ReservePublicKeyP *reserve_pub,
1845 : const char *exchange_url,
1846 : struct TALER_ExchangePublicKeyP *pub,
1847 : struct TALER_ExchangeSignatureP *sig)
1848 : {
1849 6 : struct TALER_PurseMergedConfirmationPS dc = {
1850 3 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED),
1851 3 : .purpose.size = htonl (sizeof (dc)),
1852 : .h_contract_terms = *h_contract_terms,
1853 : .purse_pub = *purse_pub,
1854 : .reserve_pub = *reserve_pub,
1855 3 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1856 3 : .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
1857 : };
1858 :
1859 3 : TALER_amount_hton (&dc.amount_without_fee,
1860 : amount_without_fee);
1861 3 : GNUNET_CRYPTO_hash (exchange_url,
1862 3 : strlen (exchange_url) + 1,
1863 : &dc.h_provider_url);
1864 3 : return scb (&dc.purpose,
1865 : pub,
1866 : sig);
1867 : }
1868 :
1869 :
1870 : enum GNUNET_GenericReturnValue
1871 3 : TALER_exchange_online_purse_merged_verify (
1872 : struct GNUNET_TIME_Timestamp exchange_time,
1873 : struct GNUNET_TIME_Timestamp purse_expiration,
1874 : const struct TALER_Amount *amount_without_fee,
1875 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1876 : const struct TALER_PrivateContractHashP *h_contract_terms,
1877 : const struct TALER_ReservePublicKeyP *reserve_pub,
1878 : const char *exchange_url,
1879 : const struct TALER_ExchangePublicKeyP *pub,
1880 : const struct TALER_ExchangeSignatureP *sig)
1881 : {
1882 6 : struct TALER_PurseMergedConfirmationPS dc = {
1883 3 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED),
1884 3 : .purpose.size = htonl (sizeof (dc)),
1885 : .h_contract_terms = *h_contract_terms,
1886 : .purse_pub = *purse_pub,
1887 : .reserve_pub = *reserve_pub,
1888 3 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1889 3 : .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
1890 : };
1891 :
1892 3 : TALER_amount_hton (&dc.amount_without_fee,
1893 : amount_without_fee);
1894 3 : GNUNET_CRYPTO_hash (exchange_url,
1895 3 : strlen (exchange_url) + 1,
1896 : &dc.h_provider_url);
1897 : return
1898 3 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED,
1899 : &dc,
1900 : &sig->eddsa_signature,
1901 : &pub->eddsa_pub);
1902 : }
1903 :
1904 :
1905 : GNUNET_NETWORK_STRUCT_BEGIN
1906 :
1907 : /**
1908 : * @brief Format used to generate the signature on a purse status
1909 : * from the exchange.
1910 : */
1911 : struct TALER_PurseStatusPS
1912 : {
1913 : /**
1914 : * Purpose must be #TALER_SIGNATURE_EXCHANGE_PURSE_STATUS. Signed
1915 : * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
1916 : */
1917 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1918 :
1919 : /**
1920 : * Time when the purse was merged, possibly 'never'.
1921 : */
1922 : struct GNUNET_TIME_TimestampNBO merge_timestamp;
1923 :
1924 : /**
1925 : * Time when the purse was deposited last, possibly 'never'.
1926 : */
1927 : struct GNUNET_TIME_TimestampNBO deposit_timestamp;
1928 :
1929 : /**
1930 : * Amount deposited in total in the purse without fees.
1931 : * May be possibly less than the target amount.
1932 : */
1933 : struct TALER_AmountNBO balance;
1934 :
1935 : };
1936 :
1937 : GNUNET_NETWORK_STRUCT_END
1938 :
1939 :
1940 : enum TALER_ErrorCode
1941 6 : TALER_exchange_online_purse_status_sign (
1942 : TALER_ExchangeSignCallback scb,
1943 : struct GNUNET_TIME_Timestamp merge_timestamp,
1944 : struct GNUNET_TIME_Timestamp deposit_timestamp,
1945 : const struct TALER_Amount *balance,
1946 : struct TALER_ExchangePublicKeyP *pub,
1947 : struct TALER_ExchangeSignatureP *sig)
1948 : {
1949 6 : struct TALER_PurseStatusPS dcs = {
1950 6 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS),
1951 6 : .purpose.size = htonl (sizeof (dcs)),
1952 6 : .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
1953 6 : .deposit_timestamp = GNUNET_TIME_timestamp_hton (deposit_timestamp)
1954 : };
1955 :
1956 6 : TALER_amount_hton (&dcs.balance,
1957 : balance);
1958 6 : return scb (&dcs.purpose,
1959 : pub,
1960 : sig);
1961 : }
1962 :
1963 :
1964 : enum GNUNET_GenericReturnValue
1965 6 : TALER_exchange_online_purse_status_verify (
1966 : struct GNUNET_TIME_Timestamp merge_timestamp,
1967 : struct GNUNET_TIME_Timestamp deposit_timestamp,
1968 : const struct TALER_Amount *balance,
1969 : const struct TALER_ExchangePublicKeyP *exchange_pub,
1970 : const struct TALER_ExchangeSignatureP *exchange_sig)
1971 : {
1972 6 : struct TALER_PurseStatusPS dcs = {
1973 6 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS),
1974 6 : .purpose.size = htonl (sizeof (dcs)),
1975 6 : .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
1976 6 : .deposit_timestamp = GNUNET_TIME_timestamp_hton (deposit_timestamp)
1977 : };
1978 :
1979 6 : TALER_amount_hton (&dcs.balance,
1980 : balance);
1981 6 : if (GNUNET_OK !=
1982 6 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS,
1983 : &dcs,
1984 : &exchange_sig->eddsa_signature,
1985 : &exchange_pub->eddsa_pub))
1986 : {
1987 0 : GNUNET_break_op (0);
1988 0 : return GNUNET_SYSERR;
1989 : }
1990 6 : return GNUNET_OK;
1991 : }
1992 :
1993 :
1994 : GNUNET_NETWORK_STRUCT_BEGIN
1995 :
1996 : /**
1997 : * Message signed by the exchange to affirm that the
1998 : * owner of a reserve has certain attributes.
1999 : */
2000 : struct TALER_ExchangeAttestPS
2001 : {
2002 :
2003 : /**
2004 : * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS
2005 : */
2006 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
2007 :
2008 : /**
2009 : * Time when the attestation was made.
2010 : */
2011 : struct GNUNET_TIME_TimestampNBO attest_timestamp;
2012 :
2013 : /**
2014 : * Time when the attestation expires.
2015 : */
2016 : struct GNUNET_TIME_TimestampNBO expiration_time;
2017 :
2018 : /**
2019 : * Public key of the reserve for which the attributes
2020 : * are attested.
2021 : */
2022 : struct TALER_ReservePublicKeyP reserve_pub;
2023 :
2024 : /**
2025 : * Hash over the attributes.
2026 : */
2027 : struct GNUNET_HashCode h_attributes;
2028 :
2029 : };
2030 :
2031 : GNUNET_NETWORK_STRUCT_END
2032 :
2033 :
2034 : enum TALER_ErrorCode
2035 1 : TALER_exchange_online_reserve_attest_details_sign (
2036 : TALER_ExchangeSignCallback scb,
2037 : struct GNUNET_TIME_Timestamp attest_timestamp,
2038 : struct GNUNET_TIME_Timestamp expiration_time,
2039 : const struct TALER_ReservePublicKeyP *reserve_pub,
2040 : const json_t *attributes,
2041 : struct TALER_ExchangePublicKeyP *pub,
2042 : struct TALER_ExchangeSignatureP *sig)
2043 : {
2044 2 : struct TALER_ExchangeAttestPS rap = {
2045 1 : .purpose.size = htonl (sizeof (rap)),
2046 1 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS),
2047 1 : .attest_timestamp = GNUNET_TIME_timestamp_hton (attest_timestamp),
2048 1 : .expiration_time = GNUNET_TIME_timestamp_hton (expiration_time),
2049 : .reserve_pub = *reserve_pub
2050 : };
2051 :
2052 1 : TALER_json_hash (attributes,
2053 : &rap.h_attributes);
2054 1 : return scb (&rap.purpose,
2055 : pub,
2056 : sig);
2057 : }
2058 :
2059 :
2060 : enum GNUNET_GenericReturnValue
2061 1 : TALER_exchange_online_reserve_attest_details_verify (
2062 : struct GNUNET_TIME_Timestamp attest_timestamp,
2063 : struct GNUNET_TIME_Timestamp expiration_time,
2064 : const struct TALER_ReservePublicKeyP *reserve_pub,
2065 : const json_t *attributes,
2066 : struct TALER_ExchangePublicKeyP *pub,
2067 : struct TALER_ExchangeSignatureP *sig)
2068 : {
2069 2 : struct TALER_ExchangeAttestPS rap = {
2070 1 : .purpose.size = htonl (sizeof (rap)),
2071 1 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS),
2072 1 : .attest_timestamp = GNUNET_TIME_timestamp_hton (attest_timestamp),
2073 1 : .expiration_time = GNUNET_TIME_timestamp_hton (expiration_time),
2074 : .reserve_pub = *reserve_pub
2075 : };
2076 :
2077 1 : TALER_json_hash (attributes,
2078 : &rap.h_attributes);
2079 1 : if (GNUNET_OK !=
2080 1 : GNUNET_CRYPTO_eddsa_verify (
2081 : TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS,
2082 : &rap,
2083 : &sig->eddsa_signature,
2084 : &pub->eddsa_pub))
2085 : {
2086 0 : GNUNET_break_op (0);
2087 0 : return GNUNET_SYSERR;
2088 : }
2089 1 : return GNUNET_OK;
2090 : }
2091 :
2092 :
2093 : /* end of exchange_signatures.c */
|