Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2021, 2022 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 "platform.h"
22 : #include "taler_util.h"
23 : #include "taler_signatures.h"
24 :
25 :
26 : GNUNET_NETWORK_STRUCT_BEGIN
27 :
28 : /**
29 : * @brief Format used to generate the signature on a confirmation
30 : * from the exchange that a deposit request succeeded.
31 : */
32 : struct TALER_DepositConfirmationPS
33 : {
34 : /**
35 : * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT. Signed
36 : * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
37 : */
38 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
39 :
40 : /**
41 : * Hash over the contract for which this deposit is made.
42 : */
43 : struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
44 :
45 : /**
46 : * Hash over the wiring information of the merchant.
47 : */
48 : struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
49 :
50 : /**
51 : * Hash over the extension options of the deposit, 0 if there
52 : * were not extension options.
53 : */
54 : struct TALER_ExtensionContractHashP h_extensions GNUNET_PACKED;
55 :
56 : /**
57 : * Time when this confirmation was generated / when the exchange received
58 : * the deposit request.
59 : */
60 : struct GNUNET_TIME_TimestampNBO exchange_timestamp;
61 :
62 : /**
63 : * By when does the exchange expect to pay the merchant
64 : * (as per the merchant's request).
65 : */
66 : struct GNUNET_TIME_TimestampNBO wire_deadline;
67 :
68 : /**
69 : * How much time does the @e merchant have to issue a refund
70 : * request? Zero if refunds are not allowed. After this time, the
71 : * coin cannot be refunded. Note that the wire transfer will not be
72 : * performed by the exchange until the refund deadline. This value
73 : * is taken from the original deposit request.
74 : */
75 : struct GNUNET_TIME_TimestampNBO refund_deadline;
76 :
77 : /**
78 : * Amount to be deposited, excluding fee. Calculated from the
79 : * amount with fee and the fee from the deposit request.
80 : */
81 : struct TALER_AmountNBO amount_without_fee;
82 :
83 : /**
84 : * The public key of the coin that was deposited.
85 : */
86 : struct TALER_CoinSpendPublicKeyP coin_pub;
87 :
88 : /**
89 : * The Merchant's public key. Allows the merchant to later refund
90 : * the transaction or to inquire about the wire transfer identifier.
91 : */
92 : struct TALER_MerchantPublicKeyP merchant_pub;
93 :
94 : };
95 :
96 : GNUNET_NETWORK_STRUCT_END
97 :
98 :
99 : enum TALER_ErrorCode
100 0 : TALER_exchange_online_deposit_confirmation_sign (
101 : TALER_ExchangeSignCallback scb,
102 : const struct TALER_PrivateContractHashP *h_contract_terms,
103 : const struct TALER_MerchantWireHashP *h_wire,
104 : const struct TALER_ExtensionContractHashP *h_extensions,
105 : struct GNUNET_TIME_Timestamp exchange_timestamp,
106 : struct GNUNET_TIME_Timestamp wire_deadline,
107 : struct GNUNET_TIME_Timestamp refund_deadline,
108 : const struct TALER_Amount *amount_without_fee,
109 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
110 : const struct TALER_MerchantPublicKeyP *merchant_pub,
111 : struct TALER_ExchangePublicKeyP *pub,
112 : struct TALER_ExchangeSignatureP *sig)
113 : {
114 0 : struct TALER_DepositConfirmationPS dcs = {
115 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
116 0 : .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
117 : .h_contract_terms = *h_contract_terms,
118 : .h_wire = *h_wire,
119 0 : .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
120 0 : .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
121 0 : .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
122 : .coin_pub = *coin_pub,
123 : .merchant_pub = *merchant_pub
124 : };
125 :
126 0 : if (NULL != h_extensions)
127 0 : dcs.h_extensions = *h_extensions;
128 0 : TALER_amount_hton (&dcs.amount_without_fee,
129 : amount_without_fee);
130 0 : return scb (&dcs.purpose,
131 : pub,
132 : sig);
133 : }
134 :
135 :
136 : enum GNUNET_GenericReturnValue
137 0 : TALER_exchange_online_deposit_confirmation_verify (
138 : const struct TALER_PrivateContractHashP *h_contract_terms,
139 : const struct TALER_MerchantWireHashP *h_wire,
140 : const struct TALER_ExtensionContractHashP *h_extensions,
141 : struct GNUNET_TIME_Timestamp exchange_timestamp,
142 : struct GNUNET_TIME_Timestamp wire_deadline,
143 : struct GNUNET_TIME_Timestamp refund_deadline,
144 : const struct TALER_Amount *amount_without_fee,
145 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
146 : const struct TALER_MerchantPublicKeyP *merchant_pub,
147 : const struct TALER_ExchangePublicKeyP *exchange_pub,
148 : const struct TALER_ExchangeSignatureP *exchange_sig)
149 : {
150 0 : struct TALER_DepositConfirmationPS dcs = {
151 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
152 0 : .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
153 : .h_contract_terms = *h_contract_terms,
154 : .h_wire = *h_wire,
155 0 : .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
156 0 : .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
157 0 : .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
158 : .coin_pub = *coin_pub,
159 : .merchant_pub = *merchant_pub
160 : };
161 :
162 0 : if (NULL != h_extensions)
163 0 : dcs.h_extensions = *h_extensions;
164 0 : TALER_amount_hton (&dcs.amount_without_fee,
165 : amount_without_fee);
166 0 : if (GNUNET_OK !=
167 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT,
168 : &dcs,
169 : &exchange_sig->eddsa_signature,
170 : &exchange_pub->eddsa_pub))
171 : {
172 0 : GNUNET_break_op (0);
173 0 : return GNUNET_SYSERR;
174 : }
175 0 : return GNUNET_OK;
176 : }
177 :
178 :
179 : GNUNET_NETWORK_STRUCT_BEGIN
180 :
181 : /**
182 : * @brief Format used to generate the signature on a request to refund
183 : * a coin into the account of the customer.
184 : */
185 : struct TALER_RefundConfirmationPS
186 : {
187 : /**
188 : * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND.
189 : */
190 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
191 :
192 : /**
193 : * Hash over the proposal data to identify the contract
194 : * which is being refunded.
195 : */
196 : struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
197 :
198 : /**
199 : * The coin's public key. This is the value that must have been
200 : * signed (blindly) by the Exchange.
201 : */
202 : struct TALER_CoinSpendPublicKeyP coin_pub;
203 :
204 : /**
205 : * The Merchant's public key. Allows the merchant to later refund
206 : * the transaction or to inquire about the wire transfer identifier.
207 : */
208 : struct TALER_MerchantPublicKeyP merchant;
209 :
210 : /**
211 : * Merchant-generated transaction ID for the refund.
212 : */
213 : uint64_t rtransaction_id GNUNET_PACKED;
214 :
215 : /**
216 : * Amount to be refunded, including refund fee charged by the
217 : * exchange to the customer.
218 : */
219 : struct TALER_AmountNBO refund_amount;
220 : };
221 :
222 : GNUNET_NETWORK_STRUCT_END
223 :
224 :
225 : enum TALER_ErrorCode
226 0 : TALER_exchange_online_refund_confirmation_sign (
227 : TALER_ExchangeSignCallback scb,
228 : const struct TALER_PrivateContractHashP *h_contract_terms,
229 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
230 : const struct TALER_MerchantPublicKeyP *merchant,
231 : uint64_t rtransaction_id,
232 : const struct TALER_Amount *refund_amount,
233 : struct TALER_ExchangePublicKeyP *pub,
234 : struct TALER_ExchangeSignatureP *sig)
235 : {
236 0 : struct TALER_RefundConfirmationPS rc = {
237 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND),
238 0 : .purpose.size = htonl (sizeof (rc)),
239 : .h_contract_terms = *h_contract_terms,
240 : .coin_pub = *coin_pub,
241 : .merchant = *merchant,
242 0 : .rtransaction_id = GNUNET_htonll (rtransaction_id)
243 : };
244 :
245 0 : TALER_amount_hton (&rc.refund_amount,
246 : refund_amount);
247 0 : return scb (&rc.purpose,
248 : pub,
249 : sig);
250 : }
251 :
252 :
253 : enum GNUNET_GenericReturnValue
254 0 : TALER_exchange_online_refund_confirmation_verify (
255 : const struct TALER_PrivateContractHashP *h_contract_terms,
256 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
257 : const struct TALER_MerchantPublicKeyP *merchant,
258 : uint64_t rtransaction_id,
259 : const struct TALER_Amount *refund_amount,
260 : const struct TALER_ExchangePublicKeyP *pub,
261 : const struct TALER_ExchangeSignatureP *sig)
262 : {
263 0 : struct TALER_RefundConfirmationPS rc = {
264 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND),
265 0 : .purpose.size = htonl (sizeof (rc)),
266 : .h_contract_terms = *h_contract_terms,
267 : .coin_pub = *coin_pub,
268 : .merchant = *merchant,
269 0 : .rtransaction_id = GNUNET_htonll (rtransaction_id)
270 : };
271 :
272 0 : TALER_amount_hton (&rc.refund_amount,
273 : refund_amount);
274 0 : if (GNUNET_OK !=
275 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND,
276 : &rc,
277 : &sig->eddsa_signature,
278 : &pub->eddsa_pub))
279 : {
280 0 : GNUNET_break_op (0);
281 0 : return GNUNET_SYSERR;
282 : }
283 0 : return GNUNET_OK;
284 : }
285 :
286 :
287 : GNUNET_NETWORK_STRUCT_BEGIN
288 :
289 : /**
290 : * @brief Format of the block signed by the Exchange in response to a successful
291 : * "/refresh/melt" request. Hereby the exchange affirms that all of the
292 : * coins were successfully melted. This also commits the exchange to a
293 : * particular index to not be revealed during the refresh.
294 : */
295 : struct TALER_RefreshMeltConfirmationPS
296 : {
297 : /**
298 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT. Signed
299 : * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
300 : */
301 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
302 :
303 : /**
304 : * Commitment made in the /refresh/melt.
305 : */
306 : struct TALER_RefreshCommitmentP rc GNUNET_PACKED;
307 :
308 : /**
309 : * Index that the client will not have to reveal, in NBO.
310 : * Must be smaller than #TALER_CNC_KAPPA.
311 : */
312 : uint32_t noreveal_index GNUNET_PACKED;
313 :
314 : };
315 :
316 : GNUNET_NETWORK_STRUCT_END
317 :
318 :
319 : enum TALER_ErrorCode
320 0 : TALER_exchange_online_melt_confirmation_sign (
321 : TALER_ExchangeSignCallback scb,
322 : const struct TALER_RefreshCommitmentP *rc,
323 : uint32_t noreveal_index,
324 : struct TALER_ExchangePublicKeyP *pub,
325 : struct TALER_ExchangeSignatureP *sig)
326 : {
327 0 : struct TALER_RefreshMeltConfirmationPS confirm = {
328 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
329 0 : .purpose.size = htonl (sizeof (confirm)),
330 : .rc = *rc,
331 0 : .noreveal_index = htonl (noreveal_index)
332 : };
333 :
334 0 : return scb (&confirm.purpose,
335 : pub,
336 : sig);
337 : }
338 :
339 :
340 : enum GNUNET_GenericReturnValue
341 0 : TALER_exchange_online_melt_confirmation_verify (
342 : const struct TALER_RefreshCommitmentP *rc,
343 : uint32_t noreveal_index,
344 : const struct TALER_ExchangePublicKeyP *exchange_pub,
345 : const struct TALER_ExchangeSignatureP *exchange_sig)
346 : {
347 0 : struct TALER_RefreshMeltConfirmationPS confirm = {
348 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
349 0 : .purpose.size = htonl (sizeof (confirm)),
350 : .rc = *rc,
351 0 : .noreveal_index = htonl (noreveal_index)
352 : };
353 :
354 : return
355 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT,
356 : &confirm,
357 : &exchange_sig->eddsa_signature,
358 : &exchange_pub->eddsa_pub);
359 : }
360 :
361 :
362 : GNUNET_NETWORK_STRUCT_BEGIN
363 :
364 : /**
365 : * @brief Signature made by the exchange over the full set of keys, used
366 : * to detect cheating exchanges that give out different sets to
367 : * different users.
368 : */
369 : struct TALER_ExchangeKeySetPS
370 : {
371 :
372 : /**
373 : * Purpose is #TALER_SIGNATURE_EXCHANGE_KEY_SET. Signed
374 : * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
375 : */
376 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
377 :
378 : /**
379 : * Time of the key set issue.
380 : */
381 : struct GNUNET_TIME_TimestampNBO list_issue_date;
382 :
383 : /**
384 : * Hash over the various denomination signing keys returned.
385 : */
386 : struct GNUNET_HashCode hc GNUNET_PACKED;
387 : };
388 :
389 : GNUNET_NETWORK_STRUCT_END
390 :
391 :
392 : enum TALER_ErrorCode
393 0 : TALER_exchange_online_key_set_sign (
394 : TALER_ExchangeSignCallback2 scb,
395 : void *cls,
396 : struct GNUNET_TIME_Timestamp timestamp,
397 : const struct GNUNET_HashCode *hc,
398 : struct TALER_ExchangePublicKeyP *pub,
399 : struct TALER_ExchangeSignatureP *sig)
400 : {
401 0 : struct TALER_ExchangeKeySetPS ks = {
402 0 : .purpose.size = htonl (sizeof (ks)),
403 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
404 0 : .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp),
405 : .hc = *hc
406 : };
407 :
408 0 : return scb (cls,
409 : &ks.purpose,
410 : pub,
411 : sig);
412 : }
413 :
414 :
415 : enum GNUNET_GenericReturnValue
416 0 : TALER_exchange_online_key_set_verify (
417 : struct GNUNET_TIME_Timestamp timestamp,
418 : const struct GNUNET_HashCode *hc,
419 : const struct TALER_ExchangePublicKeyP *pub,
420 : const struct TALER_ExchangeSignatureP *sig)
421 : {
422 0 : struct TALER_ExchangeKeySetPS ks = {
423 0 : .purpose.size = htonl (sizeof (ks)),
424 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
425 0 : .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp),
426 : .hc = *hc
427 : };
428 :
429 : return
430 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_KEY_SET,
431 : &ks,
432 : &sig->eddsa_signature,
433 : &pub->eddsa_pub);
434 : }
435 :
436 :
437 : GNUNET_NETWORK_STRUCT_BEGIN
438 :
439 : /**
440 : * @brief Signature by which an exchange affirms that an account
441 : * successfully passed the KYC checks.
442 : */
443 : struct TALER_ExchangeAccountSetupSuccessPS
444 : {
445 : /**
446 : * Purpose is #TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS. Signed by a
447 : * `struct TALER_ExchangePublicKeyP` using EdDSA.
448 : */
449 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
450 :
451 : /**
452 : * Hash over the payto for which the signature was
453 : * made.
454 : */
455 : struct TALER_PaytoHashP h_payto;
456 :
457 : // FIXME: include details on *which* KYC process
458 : // was satisfied!
459 :
460 : /**
461 : * When was the signature made.
462 : * FIXME: replace by *expiration* time!
463 : */
464 : struct GNUNET_TIME_TimestampNBO timestamp;
465 : };
466 :
467 : GNUNET_NETWORK_STRUCT_END
468 :
469 :
470 : enum TALER_ErrorCode
471 0 : TALER_exchange_online_account_setup_success_sign (
472 : TALER_ExchangeSignCallback scb,
473 : const struct TALER_PaytoHashP *h_payto,
474 : struct GNUNET_TIME_Timestamp timestamp,
475 : struct TALER_ExchangePublicKeyP *pub,
476 : struct TALER_ExchangeSignatureP *sig)
477 : {
478 0 : struct TALER_ExchangeAccountSetupSuccessPS kyc_purpose = {
479 0 : .purpose.size = htonl (sizeof (kyc_purpose)),
480 0 : .purpose.purpose = htonl (
481 : TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS),
482 : .h_payto = *h_payto,
483 0 : .timestamp = GNUNET_TIME_timestamp_hton (
484 : timestamp)
485 : };
486 :
487 0 : return scb (&kyc_purpose.purpose,
488 : pub,
489 : sig);
490 : }
491 :
492 :
493 : enum GNUNET_GenericReturnValue
494 0 : TALER_exchange_online_account_setup_success_verify (
495 : const struct TALER_PaytoHashP *h_payto,
496 : struct GNUNET_TIME_Timestamp timestamp,
497 : const struct TALER_ExchangePublicKeyP *pub,
498 : const struct TALER_ExchangeSignatureP *sig)
499 : {
500 0 : struct TALER_ExchangeAccountSetupSuccessPS kyc_purpose = {
501 0 : .purpose.size = htonl (sizeof (kyc_purpose)),
502 0 : .purpose.purpose = htonl (
503 : TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS),
504 : .h_payto = *h_payto,
505 0 : .timestamp = GNUNET_TIME_timestamp_hton (
506 : timestamp)
507 : };
508 :
509 : return
510 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS,
511 : &kyc_purpose,
512 : &sig->eddsa_signature,
513 : &pub->eddsa_pub);
514 : }
515 :
516 :
517 : GNUNET_NETWORK_STRUCT_BEGIN
518 :
519 : /**
520 : * @brief Format internally used for packing the detailed information
521 : * to generate the signature for /track/transfer signatures.
522 : */
523 : struct TALER_WireDepositDetailP
524 : {
525 :
526 : /**
527 : * Hash of the contract
528 : */
529 : struct TALER_PrivateContractHashP h_contract_terms;
530 :
531 : /**
532 : * Time when the wire transfer was performed by the exchange.
533 : */
534 : struct GNUNET_TIME_TimestampNBO execution_time;
535 :
536 : /**
537 : * Coin's public key.
538 : */
539 : struct TALER_CoinSpendPublicKeyP coin_pub;
540 :
541 : /**
542 : * Total value of the coin.
543 : */
544 : struct TALER_AmountNBO deposit_value;
545 :
546 : /**
547 : * Fees charged by the exchange for the deposit.
548 : */
549 : struct TALER_AmountNBO deposit_fee;
550 :
551 : };
552 :
553 : GNUNET_NETWORK_STRUCT_END
554 :
555 :
556 : void
557 0 : TALER_exchange_online_wire_deposit_append (
558 : struct GNUNET_HashContext *hash_context,
559 : const struct TALER_PrivateContractHashP *h_contract_terms,
560 : struct GNUNET_TIME_Timestamp execution_time,
561 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
562 : const struct TALER_Amount *deposit_value,
563 : const struct TALER_Amount *deposit_fee)
564 : {
565 0 : struct TALER_WireDepositDetailP dd = {
566 : .h_contract_terms = *h_contract_terms,
567 0 : .execution_time = GNUNET_TIME_timestamp_hton (execution_time),
568 : .coin_pub = *coin_pub
569 : };
570 0 : TALER_amount_hton (&dd.deposit_value,
571 : deposit_value);
572 0 : TALER_amount_hton (&dd.deposit_fee,
573 : deposit_fee);
574 0 : GNUNET_CRYPTO_hash_context_read (hash_context,
575 : &dd,
576 : sizeof (dd));
577 0 : }
578 :
579 :
580 : GNUNET_NETWORK_STRUCT_BEGIN
581 :
582 : /**
583 : * @brief Format used to generate the signature for /wire/deposit
584 : * replies.
585 : */
586 : struct TALER_WireDepositDataPS
587 : {
588 : /**
589 : * Purpose header for the signature over the contract with
590 : * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT.
591 : */
592 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
593 :
594 : /**
595 : * Total amount that was transferred.
596 : */
597 : struct TALER_AmountNBO total;
598 :
599 : /**
600 : * Wire fee that was charged.
601 : */
602 : struct TALER_AmountNBO wire_fee;
603 :
604 : /**
605 : * Public key of the merchant (for all aggregated transactions).
606 : */
607 : struct TALER_MerchantPublicKeyP merchant_pub;
608 :
609 : /**
610 : * Hash of bank account of the merchant.
611 : */
612 : struct TALER_PaytoHashP h_payto;
613 :
614 : /**
615 : * Hash of the individual deposits that were aggregated,
616 : * each in the format of a `struct TALER_WireDepositDetailP`.
617 : */
618 : struct GNUNET_HashCode h_details;
619 :
620 : };
621 :
622 : GNUNET_NETWORK_STRUCT_END
623 :
624 :
625 : enum TALER_ErrorCode
626 0 : TALER_exchange_online_wire_deposit_sign (
627 : TALER_ExchangeSignCallback scb,
628 : const struct TALER_Amount *total,
629 : const struct TALER_Amount *wire_fee,
630 : const struct TALER_MerchantPublicKeyP *merchant_pub,
631 : const char *payto,
632 : const struct GNUNET_HashCode *h_details,
633 : struct TALER_ExchangePublicKeyP *pub,
634 : struct TALER_ExchangeSignatureP *sig)
635 : {
636 0 : struct TALER_WireDepositDataPS wdp = {
637 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT),
638 0 : .purpose.size = htonl (sizeof (wdp)),
639 : .merchant_pub = *merchant_pub,
640 : .h_details = *h_details
641 : };
642 :
643 0 : TALER_amount_hton (&wdp.total,
644 : total);
645 0 : TALER_amount_hton (&wdp.wire_fee,
646 : wire_fee);
647 0 : TALER_payto_hash (payto,
648 : &wdp.h_payto);
649 0 : return scb (&wdp.purpose,
650 : pub,
651 : sig);
652 : }
653 :
654 :
655 : enum GNUNET_GenericReturnValue
656 0 : TALER_exchange_online_wire_deposit_verify (
657 : const struct TALER_Amount *total,
658 : const struct TALER_Amount *wire_fee,
659 : const struct TALER_MerchantPublicKeyP *merchant_pub,
660 : const struct TALER_PaytoHashP *h_payto,
661 : const struct GNUNET_HashCode *h_details,
662 : const struct TALER_ExchangePublicKeyP *pub,
663 : const struct TALER_ExchangeSignatureP *sig)
664 : {
665 0 : struct TALER_WireDepositDataPS wdp = {
666 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT),
667 0 : .purpose.size = htonl (sizeof (wdp)),
668 : .merchant_pub = *merchant_pub,
669 : .h_details = *h_details,
670 : .h_payto = *h_payto
671 : };
672 :
673 0 : TALER_amount_hton (&wdp.total,
674 : total);
675 0 : TALER_amount_hton (&wdp.wire_fee,
676 : wire_fee);
677 : return
678 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT,
679 : &wdp,
680 : &sig->eddsa_signature,
681 : &pub->eddsa_pub);
682 : }
683 :
684 :
685 : GNUNET_NETWORK_STRUCT_BEGIN
686 :
687 : /**
688 : * Details affirmed by the exchange about a wire transfer the exchange
689 : * claims to have done with respect to a deposit operation.
690 : */
691 : struct TALER_ConfirmWirePS
692 : {
693 : /**
694 : * Purpose header for the signature over the contract with
695 : * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE.
696 : */
697 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
698 :
699 : /**
700 : * Hash over the wiring information of the merchant.
701 : */
702 : struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
703 :
704 : /**
705 : * Hash over the contract for which this deposit is made.
706 : */
707 : struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
708 :
709 : /**
710 : * Raw value (binary encoding) of the wire transfer subject.
711 : */
712 : struct TALER_WireTransferIdentifierRawP wtid;
713 :
714 : /**
715 : * The coin's public key. This is the value that must have been
716 : * signed (blindly) by the Exchange.
717 : */
718 : struct TALER_CoinSpendPublicKeyP coin_pub;
719 :
720 : /**
721 : * When did the exchange execute this transfer? Note that the
722 : * timestamp may not be exactly the same on the wire, i.e.
723 : * because the wire has a different timezone or resolution.
724 : */
725 : struct GNUNET_TIME_TimestampNBO execution_time;
726 :
727 : /**
728 : * The contribution of @e coin_pub to the total transfer volume.
729 : * This is the value of the deposit minus the fee.
730 : */
731 : struct TALER_AmountNBO coin_contribution;
732 :
733 : };
734 :
735 : GNUNET_NETWORK_STRUCT_END
736 :
737 :
738 : enum TALER_ErrorCode
739 0 : TALER_exchange_online_confirm_wire_sign (
740 : TALER_ExchangeSignCallback scb,
741 : const struct TALER_MerchantWireHashP *h_wire,
742 : const struct TALER_PrivateContractHashP *h_contract_terms,
743 : const struct TALER_WireTransferIdentifierRawP *wtid,
744 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
745 : struct GNUNET_TIME_Timestamp execution_time,
746 : const struct TALER_Amount *coin_contribution,
747 : struct TALER_ExchangePublicKeyP *pub,
748 : struct TALER_ExchangeSignatureP *sig)
749 :
750 : {
751 0 : struct TALER_ConfirmWirePS cw = {
752 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE),
753 0 : .purpose.size = htonl (sizeof (cw)),
754 : .h_wire = *h_wire,
755 : .h_contract_terms = *h_contract_terms,
756 : .wtid = *wtid,
757 : .coin_pub = *coin_pub,
758 0 : .execution_time = GNUNET_TIME_timestamp_hton (execution_time)
759 : };
760 :
761 0 : TALER_amount_hton (&cw.coin_contribution,
762 : coin_contribution);
763 0 : return scb (&cw.purpose,
764 : pub,
765 : sig);
766 : }
767 :
768 :
769 : enum GNUNET_GenericReturnValue
770 0 : TALER_exchange_online_confirm_wire_verify (
771 : const struct TALER_MerchantWireHashP *h_wire,
772 : const struct TALER_PrivateContractHashP *h_contract_terms,
773 : const struct TALER_WireTransferIdentifierRawP *wtid,
774 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
775 : struct GNUNET_TIME_Timestamp execution_time,
776 : const struct TALER_Amount *coin_contribution,
777 : const struct TALER_ExchangePublicKeyP *pub,
778 : const struct TALER_ExchangeSignatureP *sig)
779 : {
780 0 : struct TALER_ConfirmWirePS cw = {
781 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE),
782 0 : .purpose.size = htonl (sizeof (cw)),
783 : .h_wire = *h_wire,
784 : .h_contract_terms = *h_contract_terms,
785 : .wtid = *wtid,
786 : .coin_pub = *coin_pub,
787 0 : .execution_time = GNUNET_TIME_timestamp_hton (execution_time)
788 : };
789 :
790 0 : TALER_amount_hton (&cw.coin_contribution,
791 : coin_contribution);
792 : return
793 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE,
794 : &cw,
795 : &sig->eddsa_signature,
796 : &pub->eddsa_pub);
797 : }
798 :
799 :
800 : GNUNET_NETWORK_STRUCT_BEGIN
801 :
802 : /**
803 : * Response by which the exchange affirms that it will
804 : * refund a coin as part of the emergency /recoup
805 : * protocol. The recoup will go back to the bank
806 : * account that created the reserve.
807 : */
808 : struct TALER_RecoupConfirmationPS
809 : {
810 :
811 : /**
812 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP
813 : */
814 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
815 :
816 : /**
817 : * When did the exchange receive the recoup request?
818 : * Indirectly determines when the wire transfer is (likely)
819 : * to happen.
820 : */
821 : struct GNUNET_TIME_TimestampNBO timestamp;
822 :
823 : /**
824 : * How much of the coin's value will the exchange transfer?
825 : * (Needed in case the coin was partially spent.)
826 : */
827 : struct TALER_AmountNBO recoup_amount;
828 :
829 : /**
830 : * Public key of the coin.
831 : */
832 : struct TALER_CoinSpendPublicKeyP coin_pub;
833 :
834 : /**
835 : * Public key of the reserve that will receive the recoup.
836 : */
837 : struct TALER_ReservePublicKeyP reserve_pub;
838 : };
839 :
840 : GNUNET_NETWORK_STRUCT_END
841 :
842 :
843 : enum TALER_ErrorCode
844 0 : TALER_exchange_online_confirm_recoup_sign (
845 : TALER_ExchangeSignCallback scb,
846 : struct GNUNET_TIME_Timestamp timestamp,
847 : const struct TALER_Amount *recoup_amount,
848 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
849 : const struct TALER_ReservePublicKeyP *reserve_pub,
850 : struct TALER_ExchangePublicKeyP *pub,
851 : struct TALER_ExchangeSignatureP *sig)
852 : {
853 0 : struct TALER_RecoupConfirmationPS pc = {
854 0 : .purpose.size = htonl (sizeof (pc)),
855 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
856 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
857 : .coin_pub = *coin_pub,
858 : .reserve_pub = *reserve_pub
859 : };
860 :
861 0 : TALER_amount_hton (&pc.recoup_amount,
862 : recoup_amount);
863 0 : return scb (&pc.purpose,
864 : pub,
865 : sig);
866 : }
867 :
868 :
869 : enum GNUNET_GenericReturnValue
870 0 : TALER_exchange_online_confirm_recoup_verify (
871 : struct GNUNET_TIME_Timestamp timestamp,
872 : const struct TALER_Amount *recoup_amount,
873 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
874 : const struct TALER_ReservePublicKeyP *reserve_pub,
875 : const struct TALER_ExchangePublicKeyP *pub,
876 : const struct TALER_ExchangeSignatureP *sig)
877 : {
878 0 : struct TALER_RecoupConfirmationPS pc = {
879 0 : .purpose.size = htonl (sizeof (pc)),
880 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
881 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
882 : .coin_pub = *coin_pub,
883 : .reserve_pub = *reserve_pub
884 : };
885 :
886 0 : TALER_amount_hton (&pc.recoup_amount,
887 : recoup_amount);
888 : return
889 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP,
890 : &pc,
891 : &sig->eddsa_signature,
892 : &pub->eddsa_pub);
893 : }
894 :
895 :
896 : GNUNET_NETWORK_STRUCT_BEGIN
897 :
898 : /**
899 : * Response by which the exchange affirms that it will refund a refreshed coin
900 : * as part of the emergency /recoup protocol. The recoup will go back to the
901 : * old coin's balance.
902 : */
903 : struct TALER_RecoupRefreshConfirmationPS
904 : {
905 :
906 : /**
907 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH
908 : */
909 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
910 :
911 : /**
912 : * When did the exchange receive the recoup request?
913 : * Indirectly determines when the wire transfer is (likely)
914 : * to happen.
915 : */
916 : struct GNUNET_TIME_TimestampNBO timestamp;
917 :
918 : /**
919 : * How much of the coin's value will the exchange transfer?
920 : * (Needed in case the coin was partially spent.)
921 : */
922 : struct TALER_AmountNBO recoup_amount;
923 :
924 : /**
925 : * Public key of the refreshed coin.
926 : */
927 : struct TALER_CoinSpendPublicKeyP coin_pub;
928 :
929 : /**
930 : * Public key of the old coin that will receive the recoup.
931 : */
932 : struct TALER_CoinSpendPublicKeyP old_coin_pub;
933 : };
934 :
935 : GNUNET_NETWORK_STRUCT_END
936 :
937 :
938 : enum TALER_ErrorCode
939 0 : TALER_exchange_online_confirm_recoup_refresh_sign (
940 : TALER_ExchangeSignCallback scb,
941 : struct GNUNET_TIME_Timestamp timestamp,
942 : const struct TALER_Amount *recoup_amount,
943 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
944 : const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
945 : struct TALER_ExchangePublicKeyP *pub,
946 : struct TALER_ExchangeSignatureP *sig)
947 : {
948 0 : struct TALER_RecoupRefreshConfirmationPS pc = {
949 0 : .purpose.purpose = htonl (
950 : TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
951 0 : .purpose.size = htonl (sizeof (pc)),
952 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
953 : .coin_pub = *coin_pub,
954 : .old_coin_pub = *old_coin_pub
955 : };
956 :
957 0 : TALER_amount_hton (&pc.recoup_amount,
958 : recoup_amount);
959 0 : return scb (&pc.purpose,
960 : pub,
961 : sig);
962 : }
963 :
964 :
965 : enum GNUNET_GenericReturnValue
966 0 : TALER_exchange_online_confirm_recoup_refresh_verify (
967 : struct GNUNET_TIME_Timestamp timestamp,
968 : const struct TALER_Amount *recoup_amount,
969 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
970 : const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
971 : const struct TALER_ExchangePublicKeyP *pub,
972 : const struct TALER_ExchangeSignatureP *sig)
973 : {
974 0 : struct TALER_RecoupRefreshConfirmationPS pc = {
975 0 : .purpose.purpose = htonl (
976 : TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
977 0 : .purpose.size = htonl (sizeof (pc)),
978 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
979 : .coin_pub = *coin_pub,
980 : .old_coin_pub = *old_coin_pub
981 : };
982 :
983 0 : TALER_amount_hton (&pc.recoup_amount,
984 : recoup_amount);
985 :
986 : return
987 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH,
988 : &pc,
989 : &sig->eddsa_signature,
990 : &pub->eddsa_pub);
991 : }
992 :
993 :
994 : GNUNET_NETWORK_STRUCT_BEGIN
995 :
996 : /**
997 : * Response by which the exchange affirms that it does not
998 : * currently know a denomination by the given hash.
999 : */
1000 : struct TALER_DenominationUnknownAffirmationPS
1001 : {
1002 :
1003 : /**
1004 : * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN
1005 : */
1006 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
1007 :
1008 : /**
1009 : * When did the exchange sign this message.
1010 : */
1011 : struct GNUNET_TIME_TimestampNBO timestamp;
1012 :
1013 : /**
1014 : * Hash of the public denomination key we do not know.
1015 : */
1016 : struct TALER_DenominationHashP h_denom_pub;
1017 : };
1018 :
1019 : GNUNET_NETWORK_STRUCT_END
1020 :
1021 :
1022 : enum TALER_ErrorCode
1023 0 : TALER_exchange_online_denomination_unknown_sign (
1024 : TALER_ExchangeSignCallback scb,
1025 : struct GNUNET_TIME_Timestamp timestamp,
1026 : const struct TALER_DenominationHashP *h_denom_pub,
1027 : struct TALER_ExchangePublicKeyP *pub,
1028 : struct TALER_ExchangeSignatureP *sig)
1029 : {
1030 0 : struct TALER_DenominationUnknownAffirmationPS dua = {
1031 0 : .purpose.size = htonl (sizeof (dua)),
1032 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
1033 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1034 : .h_denom_pub = *h_denom_pub,
1035 : };
1036 :
1037 0 : return scb (&dua.purpose,
1038 : pub,
1039 : sig);
1040 : }
1041 :
1042 :
1043 : enum GNUNET_GenericReturnValue
1044 0 : TALER_exchange_online_denomination_unknown_verify (
1045 : struct GNUNET_TIME_Timestamp timestamp,
1046 : const struct TALER_DenominationHashP *h_denom_pub,
1047 : const struct TALER_ExchangePublicKeyP *pub,
1048 : const struct TALER_ExchangeSignatureP *sig)
1049 : {
1050 0 : struct TALER_DenominationUnknownAffirmationPS dua = {
1051 0 : .purpose.size = htonl (sizeof (dua)),
1052 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
1053 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1054 : .h_denom_pub = *h_denom_pub,
1055 : };
1056 :
1057 : return
1058 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN,
1059 : &dua,
1060 : &sig->eddsa_signature,
1061 : &pub->eddsa_pub);
1062 : }
1063 :
1064 :
1065 : GNUNET_NETWORK_STRUCT_BEGIN
1066 :
1067 : /**
1068 : * Response by which the exchange affirms that it does not
1069 : * currently consider the given denomination to be valid
1070 : * for the requested operation.
1071 : */
1072 : struct TALER_DenominationExpiredAffirmationPS
1073 : {
1074 :
1075 : /**
1076 : * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED
1077 : */
1078 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
1079 :
1080 : /**
1081 : * When did the exchange sign this message.
1082 : */
1083 : struct GNUNET_TIME_TimestampNBO timestamp;
1084 :
1085 : /**
1086 : * Name of the operation that is not allowed at this time. Might NOT be 0-terminated, but is padded with 0s.
1087 : */
1088 : char operation[8];
1089 :
1090 : /**
1091 : * Hash of the public denomination key we do not know.
1092 : */
1093 : struct TALER_DenominationHashP h_denom_pub;
1094 :
1095 : };
1096 :
1097 : GNUNET_NETWORK_STRUCT_END
1098 :
1099 :
1100 : enum TALER_ErrorCode
1101 0 : TALER_exchange_online_denomination_expired_sign (
1102 : TALER_ExchangeSignCallback scb,
1103 : struct GNUNET_TIME_Timestamp timestamp,
1104 : const struct TALER_DenominationHashP *h_denom_pub,
1105 : const char *op,
1106 : struct TALER_ExchangePublicKeyP *pub,
1107 : struct TALER_ExchangeSignatureP *sig)
1108 : {
1109 0 : struct TALER_DenominationExpiredAffirmationPS dua = {
1110 0 : .purpose.size = htonl (sizeof (dua)),
1111 0 : .purpose.purpose = htonl (
1112 : TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
1113 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1114 : .h_denom_pub = *h_denom_pub,
1115 : };
1116 :
1117 : /* strncpy would create a compiler warning */
1118 0 : memcpy (dua.operation,
1119 : op,
1120 0 : GNUNET_MIN (sizeof (dua.operation),
1121 : strlen (op)));
1122 0 : return scb (&dua.purpose,
1123 : pub,
1124 : sig);
1125 : }
1126 :
1127 :
1128 : enum GNUNET_GenericReturnValue
1129 0 : TALER_exchange_online_denomination_expired_verify (
1130 : struct GNUNET_TIME_Timestamp timestamp,
1131 : const struct TALER_DenominationHashP *h_denom_pub,
1132 : const char *op,
1133 : const struct TALER_ExchangePublicKeyP *pub,
1134 : const struct TALER_ExchangeSignatureP *sig)
1135 : {
1136 0 : struct TALER_DenominationExpiredAffirmationPS dua = {
1137 0 : .purpose.size = htonl (sizeof (dua)),
1138 0 : .purpose.purpose = htonl (
1139 : TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
1140 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1141 : .h_denom_pub = *h_denom_pub,
1142 : };
1143 :
1144 : /* strncpy would create a compiler warning */
1145 0 : memcpy (dua.operation,
1146 : op,
1147 0 : GNUNET_MIN (sizeof (dua.operation),
1148 : strlen (op)));
1149 : return
1150 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED,
1151 : &dua,
1152 : &sig->eddsa_signature,
1153 : &pub->eddsa_pub);
1154 : }
1155 :
1156 :
1157 : GNUNET_NETWORK_STRUCT_BEGIN
1158 :
1159 : /**
1160 : * Response by which the exchange affirms that it has
1161 : * closed a reserve and send back the funds.
1162 : */
1163 : struct TALER_ReserveCloseConfirmationPS
1164 : {
1165 :
1166 : /**
1167 : * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED
1168 : */
1169 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
1170 :
1171 : /**
1172 : * When did the exchange initiate the wire transfer.
1173 : */
1174 : struct GNUNET_TIME_TimestampNBO timestamp;
1175 :
1176 : /**
1177 : * How much did the exchange send?
1178 : */
1179 : struct TALER_AmountNBO closing_amount;
1180 :
1181 : /**
1182 : * How much did the exchange charge for closing the reserve?
1183 : */
1184 : struct TALER_AmountNBO closing_fee;
1185 :
1186 : /**
1187 : * Public key of the reserve that was closed.
1188 : */
1189 : struct TALER_ReservePublicKeyP reserve_pub;
1190 :
1191 : /**
1192 : * Hash of the receiver's bank account.
1193 : */
1194 : struct TALER_PaytoHashP h_payto;
1195 :
1196 : /**
1197 : * Wire transfer subject.
1198 : */
1199 : struct TALER_WireTransferIdentifierRawP wtid;
1200 : };
1201 :
1202 : GNUNET_NETWORK_STRUCT_END
1203 :
1204 :
1205 : enum TALER_ErrorCode
1206 0 : TALER_exchange_online_reserve_closed_sign (
1207 : TALER_ExchangeSignCallback scb,
1208 : struct GNUNET_TIME_Timestamp timestamp,
1209 : const struct TALER_Amount *closing_amount,
1210 : const struct TALER_Amount *closing_fee,
1211 : const char *payto,
1212 : const struct TALER_WireTransferIdentifierRawP *wtid,
1213 : const struct TALER_ReservePublicKeyP *reserve_pub,
1214 : struct TALER_ExchangePublicKeyP *pub,
1215 : struct TALER_ExchangeSignatureP *sig)
1216 : {
1217 0 : struct TALER_ReserveCloseConfirmationPS rcc = {
1218 0 : .purpose.size = htonl (sizeof (rcc)),
1219 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED),
1220 : .wtid = *wtid,
1221 : .reserve_pub = *reserve_pub,
1222 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp)
1223 : };
1224 :
1225 0 : TALER_amount_hton (&rcc.closing_amount,
1226 : closing_amount);
1227 0 : TALER_amount_hton (&rcc.closing_fee,
1228 : closing_fee);
1229 0 : TALER_payto_hash (payto,
1230 : &rcc.h_payto);
1231 0 : return scb (&rcc.purpose,
1232 : pub,
1233 : sig);
1234 : }
1235 :
1236 :
1237 : enum GNUNET_GenericReturnValue
1238 0 : TALER_exchange_online_reserve_closed_verify (
1239 : struct GNUNET_TIME_Timestamp timestamp,
1240 : const struct TALER_Amount *closing_amount,
1241 : const struct TALER_Amount *closing_fee,
1242 : const char *payto,
1243 : const struct TALER_WireTransferIdentifierRawP *wtid,
1244 : const struct TALER_ReservePublicKeyP *reserve_pub,
1245 : const struct TALER_ExchangePublicKeyP *pub,
1246 : const struct TALER_ExchangeSignatureP *sig)
1247 : {
1248 0 : struct TALER_ReserveCloseConfirmationPS rcc = {
1249 0 : .purpose.size = htonl (sizeof (rcc)),
1250 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED),
1251 : .wtid = *wtid,
1252 : .reserve_pub = *reserve_pub,
1253 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp)
1254 : };
1255 :
1256 0 : TALER_amount_hton (&rcc.closing_amount,
1257 : closing_amount);
1258 0 : TALER_amount_hton (&rcc.closing_fee,
1259 : closing_fee);
1260 0 : TALER_payto_hash (payto,
1261 : &rcc.h_payto);
1262 : return
1263 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED,
1264 : &rcc,
1265 : &sig->eddsa_signature,
1266 : &pub->eddsa_pub);
1267 : }
1268 :
1269 :
1270 : GNUNET_NETWORK_STRUCT_BEGIN
1271 :
1272 : /**
1273 : * Response by which the exchange affirms that it has
1274 : * received funds deposited into a purse.
1275 : */
1276 : struct TALER_PurseCreateDepositConfirmationPS
1277 : {
1278 :
1279 : /**
1280 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION
1281 : */
1282 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
1283 :
1284 : /**
1285 : * When did the exchange receive the deposits.
1286 : */
1287 : struct GNUNET_TIME_TimestampNBO exchange_time;
1288 :
1289 : /**
1290 : * When will the purse expire?
1291 : */
1292 : struct GNUNET_TIME_TimestampNBO purse_expiration;
1293 :
1294 : /**
1295 : * How much should the purse ultimately contain.
1296 : */
1297 : struct TALER_AmountNBO amount_without_fee;
1298 :
1299 : /**
1300 : * How much was deposited so far.
1301 : */
1302 : struct TALER_AmountNBO total_deposited;
1303 :
1304 : /**
1305 : * Public key of the purse.
1306 : */
1307 : struct TALER_PurseContractPublicKeyP purse_pub;
1308 :
1309 : /**
1310 : * Hash of the contract of the purse.
1311 : */
1312 : struct TALER_PrivateContractHashP h_contract_terms;
1313 :
1314 : };
1315 :
1316 : GNUNET_NETWORK_STRUCT_END
1317 :
1318 :
1319 : enum TALER_ErrorCode
1320 0 : TALER_exchange_online_purse_created_sign (
1321 : TALER_ExchangeSignCallback scb,
1322 : struct GNUNET_TIME_Timestamp exchange_time,
1323 : struct GNUNET_TIME_Timestamp purse_expiration,
1324 : const struct TALER_Amount *amount_without_fee,
1325 : const struct TALER_Amount *total_deposited,
1326 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1327 : const struct TALER_PrivateContractHashP *h_contract_terms,
1328 : struct TALER_ExchangePublicKeyP *pub,
1329 : struct TALER_ExchangeSignatureP *sig)
1330 : {
1331 0 : struct TALER_PurseCreateDepositConfirmationPS dc = {
1332 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION),
1333 0 : .purpose.size = htonl (sizeof (dc)),
1334 : .h_contract_terms = *h_contract_terms,
1335 : .purse_pub = *purse_pub,
1336 0 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1337 0 : .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
1338 : };
1339 :
1340 0 : TALER_amount_hton (&dc.amount_without_fee,
1341 : amount_without_fee);
1342 0 : TALER_amount_hton (&dc.total_deposited,
1343 : total_deposited);
1344 0 : return scb (&dc.purpose,
1345 : pub,
1346 : sig);
1347 : }
1348 :
1349 :
1350 : enum GNUNET_GenericReturnValue
1351 0 : TALER_exchange_online_purse_created_verify (
1352 : struct GNUNET_TIME_Timestamp exchange_time,
1353 : struct GNUNET_TIME_Timestamp purse_expiration,
1354 : const struct TALER_Amount *amount_without_fee,
1355 : const struct TALER_Amount *total_deposited,
1356 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1357 : const struct TALER_PrivateContractHashP *h_contract_terms,
1358 : const struct TALER_ExchangePublicKeyP *pub,
1359 : const struct TALER_ExchangeSignatureP *sig)
1360 : {
1361 0 : struct TALER_PurseCreateDepositConfirmationPS dc = {
1362 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION),
1363 0 : .purpose.size = htonl (sizeof (dc)),
1364 : .h_contract_terms = *h_contract_terms,
1365 : .purse_pub = *purse_pub,
1366 0 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1367 0 : .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
1368 : };
1369 :
1370 0 : TALER_amount_hton (&dc.amount_without_fee,
1371 : amount_without_fee);
1372 0 : TALER_amount_hton (&dc.total_deposited,
1373 : total_deposited);
1374 : return
1375 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION,
1376 : &dc,
1377 : &sig->eddsa_signature,
1378 : &pub->eddsa_pub);
1379 : }
1380 :
1381 :
1382 : GNUNET_NETWORK_STRUCT_BEGIN
1383 :
1384 : /**
1385 : * Response by which the exchange affirms that it has
1386 : * merged a purse into a reserve.
1387 : */
1388 : struct TALER_PurseMergedConfirmationPS
1389 : {
1390 :
1391 : /**
1392 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED
1393 : */
1394 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
1395 :
1396 : /**
1397 : * When did the exchange receive the deposits.
1398 : */
1399 : struct GNUNET_TIME_TimestampNBO exchange_time;
1400 :
1401 : /**
1402 : * When will the purse expire?
1403 : */
1404 : struct GNUNET_TIME_TimestampNBO purse_expiration;
1405 :
1406 : /**
1407 : * How much should the purse ultimately contain.
1408 : */
1409 : struct TALER_AmountNBO amount_without_fee;
1410 :
1411 : /**
1412 : * Public key of the purse.
1413 : */
1414 : struct TALER_PurseContractPublicKeyP purse_pub;
1415 :
1416 : /**
1417 : * Public key of the reserve.
1418 : */
1419 : struct TALER_ReservePublicKeyP reserve_pub;
1420 :
1421 : /**
1422 : * Hash of the contract of the purse.
1423 : */
1424 : struct TALER_PrivateContractHashP h_contract_terms;
1425 :
1426 : /**
1427 : * Hash of the provider URL hosting the reserve.
1428 : */
1429 : struct GNUNET_HashCode h_provider_url;
1430 :
1431 : };
1432 :
1433 : GNUNET_NETWORK_STRUCT_END
1434 :
1435 :
1436 : enum TALER_ErrorCode
1437 0 : TALER_exchange_online_purse_merged_sign (
1438 : TALER_ExchangeSignCallback scb,
1439 : struct GNUNET_TIME_Timestamp exchange_time,
1440 : struct GNUNET_TIME_Timestamp purse_expiration,
1441 : const struct TALER_Amount *amount_without_fee,
1442 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1443 : const struct TALER_PrivateContractHashP *h_contract_terms,
1444 : const struct TALER_ReservePublicKeyP *reserve_pub,
1445 : const char *exchange_url,
1446 : struct TALER_ExchangePublicKeyP *pub,
1447 : struct TALER_ExchangeSignatureP *sig)
1448 : {
1449 0 : struct TALER_PurseMergedConfirmationPS dc = {
1450 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED),
1451 0 : .purpose.size = htonl (sizeof (dc)),
1452 : .h_contract_terms = *h_contract_terms,
1453 : .purse_pub = *purse_pub,
1454 : .reserve_pub = *reserve_pub,
1455 0 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1456 0 : .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
1457 : };
1458 :
1459 0 : TALER_amount_hton (&dc.amount_without_fee,
1460 : amount_without_fee);
1461 0 : GNUNET_CRYPTO_hash (exchange_url,
1462 0 : strlen (exchange_url) + 1,
1463 : &dc.h_provider_url);
1464 0 : return scb (&dc.purpose,
1465 : pub,
1466 : sig);
1467 : }
1468 :
1469 :
1470 : enum GNUNET_GenericReturnValue
1471 0 : TALER_exchange_online_purse_merged_verify (
1472 : struct GNUNET_TIME_Timestamp exchange_time,
1473 : struct GNUNET_TIME_Timestamp purse_expiration,
1474 : const struct TALER_Amount *amount_without_fee,
1475 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1476 : const struct TALER_PrivateContractHashP *h_contract_terms,
1477 : const struct TALER_ReservePublicKeyP *reserve_pub,
1478 : const char *exchange_url,
1479 : const struct TALER_ExchangePublicKeyP *pub,
1480 : const struct TALER_ExchangeSignatureP *sig)
1481 : {
1482 0 : struct TALER_PurseMergedConfirmationPS dc = {
1483 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED),
1484 0 : .purpose.size = htonl (sizeof (dc)),
1485 : .h_contract_terms = *h_contract_terms,
1486 : .purse_pub = *purse_pub,
1487 : .reserve_pub = *reserve_pub,
1488 0 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1489 0 : .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
1490 : };
1491 :
1492 0 : TALER_amount_hton (&dc.amount_without_fee,
1493 : amount_without_fee);
1494 0 : GNUNET_CRYPTO_hash (exchange_url,
1495 0 : strlen (exchange_url) + 1,
1496 : &dc.h_provider_url);
1497 : return
1498 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED,
1499 : &dc,
1500 : &sig->eddsa_signature,
1501 : &pub->eddsa_pub);
1502 : }
1503 :
1504 :
1505 : GNUNET_NETWORK_STRUCT_BEGIN
1506 :
1507 : /**
1508 : * @brief Format used to generate the signature on a purse status
1509 : * from the exchange.
1510 : */
1511 : struct TALER_PurseStatusPS
1512 : {
1513 : /**
1514 : * Purpose must be #TALER_SIGNATURE_EXCHANGE_PURSE_STATUS. Signed
1515 : * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
1516 : */
1517 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
1518 :
1519 : /**
1520 : * Time when the purse was merged, possibly 'never'.
1521 : */
1522 : struct GNUNET_TIME_TimestampNBO merge_timestamp;
1523 :
1524 : /**
1525 : * Time when the purse was deposited last, possibly 'never'.
1526 : */
1527 : struct GNUNET_TIME_TimestampNBO deposit_timestamp;
1528 :
1529 : /**
1530 : * Amount deposited in total in the purse without fees.
1531 : * May be possibly less than the target amount.
1532 : */
1533 : struct TALER_AmountNBO balance;
1534 :
1535 : };
1536 :
1537 : GNUNET_NETWORK_STRUCT_END
1538 :
1539 :
1540 : enum TALER_ErrorCode
1541 0 : TALER_exchange_online_purse_status_sign (
1542 : TALER_ExchangeSignCallback scb,
1543 : struct GNUNET_TIME_Timestamp merge_timestamp,
1544 : struct GNUNET_TIME_Timestamp deposit_timestamp,
1545 : const struct TALER_Amount *balance,
1546 : struct TALER_ExchangePublicKeyP *pub,
1547 : struct TALER_ExchangeSignatureP *sig)
1548 : {
1549 0 : struct TALER_PurseStatusPS dcs = {
1550 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS),
1551 0 : .purpose.size = htonl (sizeof (dcs)),
1552 0 : .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
1553 0 : .deposit_timestamp = GNUNET_TIME_timestamp_hton (deposit_timestamp)
1554 : };
1555 :
1556 0 : TALER_amount_hton (&dcs.balance,
1557 : balance);
1558 0 : return scb (&dcs.purpose,
1559 : pub,
1560 : sig);
1561 : }
1562 :
1563 :
1564 : enum GNUNET_GenericReturnValue
1565 0 : TALER_exchange_online_purse_status_verify (
1566 : struct GNUNET_TIME_Timestamp merge_timestamp,
1567 : struct GNUNET_TIME_Timestamp deposit_timestamp,
1568 : const struct TALER_Amount *balance,
1569 : const struct TALER_ExchangePublicKeyP *exchange_pub,
1570 : const struct TALER_ExchangeSignatureP *exchange_sig)
1571 : {
1572 0 : struct TALER_PurseStatusPS dcs = {
1573 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS),
1574 0 : .purpose.size = htonl (sizeof (dcs)),
1575 0 : .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
1576 0 : .deposit_timestamp = GNUNET_TIME_timestamp_hton (deposit_timestamp)
1577 : };
1578 :
1579 0 : TALER_amount_hton (&dcs.balance,
1580 : balance);
1581 0 : if (GNUNET_OK !=
1582 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS,
1583 : &dcs,
1584 : &exchange_sig->eddsa_signature,
1585 : &exchange_pub->eddsa_pub))
1586 : {
1587 0 : GNUNET_break_op (0);
1588 0 : return GNUNET_SYSERR;
1589 : }
1590 0 : return GNUNET_OK;
1591 : }
1592 :
1593 :
1594 : /* end of exchange_signatures.c */
|