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 84 : 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 84 : {
114 168 : struct TALER_DepositConfirmationPS dcs = {
115 84 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
116 84 : .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
117 : .h_contract_terms = *h_contract_terms,
118 : .h_wire = *h_wire,
119 84 : .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
120 84 : .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
121 84 : .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 84 : hc = GNUNET_CRYPTO_hash_context_start ();
128 170 : for (unsigned int i = 0; i<num_coins; i++)
129 86 : GNUNET_CRYPTO_hash_context_read (hc,
130 86 : coin_sigs[i],
131 : sizeof (*coin_sigs[i]));
132 84 : GNUNET_CRYPTO_hash_context_finish (hc,
133 : &dcs.h_coin_sigs);
134 84 : if (NULL != h_policy)
135 0 : dcs.h_policy = *h_policy;
136 84 : TALER_amount_hton (&dcs.total_without_fee,
137 : total_without_fee);
138 84 : return scb (&dcs.purpose,
139 : pub,
140 : sig);
141 : }
142 :
143 :
144 : enum GNUNET_GenericReturnValue
145 88 : 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 88 : {
159 176 : struct TALER_DepositConfirmationPS dcs = {
160 88 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
161 88 : .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
162 : .h_contract_terms = *h_contract_terms,
163 : .h_wire = *h_wire,
164 88 : .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
165 88 : .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
166 88 : .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
167 : .merchant_pub = *merchant_pub
168 : };
169 : struct GNUNET_HashContext *hc;
170 :
171 88 : hc = GNUNET_CRYPTO_hash_context_start ();
172 178 : for (unsigned int i = 0; i<num_coins; i++)
173 90 : GNUNET_CRYPTO_hash_context_read (hc,
174 90 : coin_sigs[i],
175 : sizeof (*coin_sigs[i]));
176 88 : GNUNET_CRYPTO_hash_context_finish (hc,
177 : &dcs.h_coin_sigs);
178 88 : if (NULL != h_policy)
179 88 : dcs.h_policy = *h_policy;
180 88 : TALER_amount_hton (&dcs.total_without_fee,
181 : total_without_fee);
182 88 : if (GNUNET_OK !=
183 88 : 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 88 : 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 16 : 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 16 : struct TALER_RefreshMeltConfirmationPS confirm = {
344 16 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
345 16 : .purpose.size = htonl (sizeof (confirm)),
346 : .rc = *rc,
347 16 : .noreveal_index = htonl (noreveal_index)
348 : };
349 :
350 16 : return scb (&confirm.purpose,
351 : pub,
352 : sig);
353 : }
354 :
355 :
356 : enum GNUNET_GenericReturnValue
357 16 : 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 16 : struct TALER_RefreshMeltConfirmationPS confirm = {
364 16 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
365 16 : .purpose.size = htonl (sizeof (confirm)),
366 : .rc = *rc,
367 16 : .noreveal_index = htonl (noreveal_index)
368 : };
369 :
370 : return
371 16 : 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 91 : 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 182 : struct TALER_ExchangeKeySetPS ks = {
553 91 : .purpose.size = htonl (sizeof (ks)),
554 91 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
555 91 : .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp),
556 : .hc = *hc
557 : };
558 :
559 91 : return scb (cls,
560 : &ks.purpose,
561 : pub,
562 : sig);
563 : }
564 :
565 :
566 : enum GNUNET_GenericReturnValue
567 34 : 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 68 : struct TALER_ExchangeKeySetPS ks = {
574 34 : .purpose.size = htonl (sizeof (ks)),
575 34 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
576 34 : .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp),
577 : .hc = *hc
578 : };
579 :
580 : return
581 34 : 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 0 : 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 0 : struct TALER_RecoupConfirmationPS pc = {
925 0 : .purpose.size = htonl (sizeof (pc)),
926 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
927 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
928 : .coin_pub = *coin_pub,
929 : .reserve_pub = *reserve_pub
930 : };
931 :
932 0 : TALER_amount_hton (&pc.recoup_amount,
933 : recoup_amount);
934 0 : return scb (&pc.purpose,
935 : pub,
936 : sig);
937 : }
938 :
939 :
940 : enum GNUNET_GenericReturnValue
941 0 : 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 0 : struct TALER_RecoupConfirmationPS pc = {
950 0 : .purpose.size = htonl (sizeof (pc)),
951 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
952 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
953 : .coin_pub = *coin_pub,
954 : .reserve_pub = *reserve_pub
955 : };
956 :
957 0 : TALER_amount_hton (&pc.recoup_amount,
958 : recoup_amount);
959 : return
960 0 : 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 : GNUNET_NETWORK_STRUCT_BEGIN
1066 :
1067 : /**
1068 : * Response by which the exchange affirms that it does not
1069 : * currently know a denomination by the given hash.
1070 : */
1071 : struct TALER_DenominationUnknownAffirmationPS
1072 : {
1073 :
1074 : /**
1075 : * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN
1076 : */
1077 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1078 :
1079 : /**
1080 : * When did the exchange sign this message.
1081 : */
1082 : struct GNUNET_TIME_TimestampNBO timestamp;
1083 :
1084 : /**
1085 : * Hash of the public denomination key we do not know.
1086 : */
1087 : struct TALER_DenominationHashP h_denom_pub;
1088 : };
1089 :
1090 : GNUNET_NETWORK_STRUCT_END
1091 :
1092 :
1093 : enum TALER_ErrorCode
1094 0 : TALER_exchange_online_denomination_unknown_sign (
1095 : TALER_ExchangeSignCallback scb,
1096 : struct GNUNET_TIME_Timestamp timestamp,
1097 : const struct TALER_DenominationHashP *h_denom_pub,
1098 : struct TALER_ExchangePublicKeyP *pub,
1099 : struct TALER_ExchangeSignatureP *sig)
1100 : {
1101 0 : struct TALER_DenominationUnknownAffirmationPS dua = {
1102 0 : .purpose.size = htonl (sizeof (dua)),
1103 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
1104 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1105 : .h_denom_pub = *h_denom_pub,
1106 : };
1107 :
1108 0 : return scb (&dua.purpose,
1109 : pub,
1110 : sig);
1111 : }
1112 :
1113 :
1114 : enum GNUNET_GenericReturnValue
1115 0 : TALER_exchange_online_denomination_unknown_verify (
1116 : struct GNUNET_TIME_Timestamp timestamp,
1117 : const struct TALER_DenominationHashP *h_denom_pub,
1118 : const struct TALER_ExchangePublicKeyP *pub,
1119 : const struct TALER_ExchangeSignatureP *sig)
1120 : {
1121 0 : struct TALER_DenominationUnknownAffirmationPS dua = {
1122 0 : .purpose.size = htonl (sizeof (dua)),
1123 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
1124 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1125 : .h_denom_pub = *h_denom_pub,
1126 : };
1127 :
1128 : return
1129 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN,
1130 : &dua,
1131 : &sig->eddsa_signature,
1132 : &pub->eddsa_pub);
1133 : }
1134 :
1135 :
1136 : GNUNET_NETWORK_STRUCT_BEGIN
1137 :
1138 : /**
1139 : * Response by which the exchange affirms that it does not
1140 : * currently consider the given denomination to be valid
1141 : * for the requested operation.
1142 : */
1143 : struct TALER_DenominationExpiredAffirmationPS
1144 : {
1145 :
1146 : /**
1147 : * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED
1148 : */
1149 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1150 :
1151 : /**
1152 : * When did the exchange sign this message.
1153 : */
1154 : struct GNUNET_TIME_TimestampNBO timestamp;
1155 :
1156 : /**
1157 : * Name of the operation that is not allowed at this time. Might NOT be 0-terminated, but is padded with 0s.
1158 : */
1159 : char operation[8];
1160 :
1161 : /**
1162 : * Hash of the public denomination key we do not know.
1163 : */
1164 : struct TALER_DenominationHashP h_denom_pub;
1165 :
1166 : };
1167 :
1168 : GNUNET_NETWORK_STRUCT_END
1169 :
1170 :
1171 : enum TALER_ErrorCode
1172 0 : TALER_exchange_online_denomination_expired_sign (
1173 : TALER_ExchangeSignCallback scb,
1174 : struct GNUNET_TIME_Timestamp timestamp,
1175 : const struct TALER_DenominationHashP *h_denom_pub,
1176 : const char *op,
1177 : struct TALER_ExchangePublicKeyP *pub,
1178 : struct TALER_ExchangeSignatureP *sig)
1179 : {
1180 0 : struct TALER_DenominationExpiredAffirmationPS dua = {
1181 0 : .purpose.size = htonl (sizeof (dua)),
1182 0 : .purpose.purpose = htonl (
1183 : TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
1184 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1185 : .h_denom_pub = *h_denom_pub,
1186 : };
1187 :
1188 : /* strncpy would create a compiler warning */
1189 0 : GNUNET_memcpy (dua.operation,
1190 : op,
1191 : GNUNET_MIN (sizeof (dua.operation),
1192 : strlen (op)));
1193 0 : return scb (&dua.purpose,
1194 : pub,
1195 : sig);
1196 : }
1197 :
1198 :
1199 : enum GNUNET_GenericReturnValue
1200 0 : TALER_exchange_online_denomination_expired_verify (
1201 : struct GNUNET_TIME_Timestamp timestamp,
1202 : const struct TALER_DenominationHashP *h_denom_pub,
1203 : const char *op,
1204 : const struct TALER_ExchangePublicKeyP *pub,
1205 : const struct TALER_ExchangeSignatureP *sig)
1206 : {
1207 0 : struct TALER_DenominationExpiredAffirmationPS dua = {
1208 0 : .purpose.size = htonl (sizeof (dua)),
1209 0 : .purpose.purpose = htonl (
1210 : TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
1211 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
1212 : .h_denom_pub = *h_denom_pub,
1213 : };
1214 :
1215 : /* strncpy would create a compiler warning */
1216 0 : GNUNET_memcpy (dua.operation,
1217 : op,
1218 : GNUNET_MIN (sizeof (dua.operation),
1219 : strlen (op)));
1220 : return
1221 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED,
1222 : &dua,
1223 : &sig->eddsa_signature,
1224 : &pub->eddsa_pub);
1225 : }
1226 :
1227 :
1228 : GNUNET_NETWORK_STRUCT_BEGIN
1229 :
1230 : /**
1231 : * Response by which the exchange affirms that it has
1232 : * closed a reserve and send back the funds.
1233 : */
1234 : struct TALER_ReserveCloseConfirmationPS
1235 : {
1236 :
1237 : /**
1238 : * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED
1239 : */
1240 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1241 :
1242 : /**
1243 : * When did the exchange initiate the wire transfer.
1244 : */
1245 : struct GNUNET_TIME_TimestampNBO timestamp;
1246 :
1247 : /**
1248 : * How much did the exchange send?
1249 : */
1250 : struct TALER_AmountNBO closing_amount;
1251 :
1252 : /**
1253 : * How much did the exchange charge for closing the reserve?
1254 : */
1255 : struct TALER_AmountNBO closing_fee;
1256 :
1257 : /**
1258 : * Public key of the reserve that was closed.
1259 : */
1260 : struct TALER_ReservePublicKeyP reserve_pub;
1261 :
1262 : /**
1263 : * Hash of the receiver's bank account.
1264 : */
1265 : struct TALER_FullPaytoHashP h_payto;
1266 :
1267 : /**
1268 : * Wire transfer subject.
1269 : */
1270 : struct TALER_WireTransferIdentifierRawP wtid;
1271 : };
1272 :
1273 : GNUNET_NETWORK_STRUCT_END
1274 :
1275 :
1276 : enum TALER_ErrorCode
1277 0 : TALER_exchange_online_reserve_closed_sign (
1278 : TALER_ExchangeSignCallback scb,
1279 : struct GNUNET_TIME_Timestamp timestamp,
1280 : const struct TALER_Amount *closing_amount,
1281 : const struct TALER_Amount *closing_fee,
1282 : const struct TALER_FullPayto payto,
1283 : const struct TALER_WireTransferIdentifierRawP *wtid,
1284 : const struct TALER_ReservePublicKeyP *reserve_pub,
1285 : struct TALER_ExchangePublicKeyP *pub,
1286 : struct TALER_ExchangeSignatureP *sig)
1287 : {
1288 0 : struct TALER_ReserveCloseConfirmationPS rcc = {
1289 0 : .purpose.size = htonl (sizeof (rcc)),
1290 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED),
1291 : .wtid = *wtid,
1292 : .reserve_pub = *reserve_pub,
1293 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp)
1294 : };
1295 :
1296 0 : TALER_amount_hton (&rcc.closing_amount,
1297 : closing_amount);
1298 0 : TALER_amount_hton (&rcc.closing_fee,
1299 : closing_fee);
1300 0 : TALER_full_payto_hash (payto,
1301 : &rcc.h_payto);
1302 0 : return scb (&rcc.purpose,
1303 : pub,
1304 : sig);
1305 : }
1306 :
1307 :
1308 : enum GNUNET_GenericReturnValue
1309 0 : TALER_exchange_online_reserve_closed_verify (
1310 : struct GNUNET_TIME_Timestamp timestamp,
1311 : const struct TALER_Amount *closing_amount,
1312 : const struct TALER_Amount *closing_fee,
1313 : const struct TALER_FullPayto payto,
1314 : const struct TALER_WireTransferIdentifierRawP *wtid,
1315 : const struct TALER_ReservePublicKeyP *reserve_pub,
1316 : const struct TALER_ExchangePublicKeyP *pub,
1317 : const struct TALER_ExchangeSignatureP *sig)
1318 : {
1319 0 : struct TALER_ReserveCloseConfirmationPS rcc = {
1320 0 : .purpose.size = htonl (sizeof (rcc)),
1321 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED),
1322 : .wtid = *wtid,
1323 : .reserve_pub = *reserve_pub,
1324 0 : .timestamp = GNUNET_TIME_timestamp_hton (timestamp)
1325 : };
1326 :
1327 0 : TALER_amount_hton (&rcc.closing_amount,
1328 : closing_amount);
1329 0 : TALER_amount_hton (&rcc.closing_fee,
1330 : closing_fee);
1331 0 : TALER_full_payto_hash (payto,
1332 : &rcc.h_payto);
1333 0 : return GNUNET_CRYPTO_eddsa_verify (
1334 : TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED,
1335 : &rcc,
1336 : &sig->eddsa_signature,
1337 : &pub->eddsa_pub);
1338 : }
1339 :
1340 :
1341 : GNUNET_NETWORK_STRUCT_BEGIN
1342 :
1343 : /**
1344 : * Response by which the exchange affirms that it has
1345 : * received funds deposited into a purse.
1346 : */
1347 : struct TALER_PurseCreateDepositConfirmationPS
1348 : {
1349 :
1350 : /**
1351 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION
1352 : */
1353 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1354 :
1355 : /**
1356 : * When did the exchange receive the deposits.
1357 : */
1358 : struct GNUNET_TIME_TimestampNBO exchange_time;
1359 :
1360 : /**
1361 : * When will the purse expire?
1362 : */
1363 : struct GNUNET_TIME_TimestampNBO purse_expiration;
1364 :
1365 : /**
1366 : * How much should the purse ultimately contain.
1367 : */
1368 : struct TALER_AmountNBO amount_without_fee;
1369 :
1370 : /**
1371 : * How much was deposited so far.
1372 : */
1373 : struct TALER_AmountNBO total_deposited;
1374 :
1375 : /**
1376 : * Public key of the purse.
1377 : */
1378 : struct TALER_PurseContractPublicKeyP purse_pub;
1379 :
1380 : /**
1381 : * Hash of the contract of the purse.
1382 : */
1383 : struct TALER_PrivateContractHashP h_contract_terms;
1384 :
1385 : };
1386 :
1387 : GNUNET_NETWORK_STRUCT_END
1388 :
1389 :
1390 : enum TALER_ErrorCode
1391 25 : TALER_exchange_online_purse_created_sign (
1392 : TALER_ExchangeSignCallback scb,
1393 : struct GNUNET_TIME_Timestamp exchange_time,
1394 : struct GNUNET_TIME_Timestamp purse_expiration,
1395 : const struct TALER_Amount *amount_without_fee,
1396 : const struct TALER_Amount *total_deposited,
1397 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1398 : const struct TALER_PrivateContractHashP *h_contract_terms,
1399 : struct TALER_ExchangePublicKeyP *pub,
1400 : struct TALER_ExchangeSignatureP *sig)
1401 : {
1402 50 : struct TALER_PurseCreateDepositConfirmationPS dc = {
1403 25 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION),
1404 25 : .purpose.size = htonl (sizeof (dc)),
1405 : .h_contract_terms = *h_contract_terms,
1406 : .purse_pub = *purse_pub,
1407 25 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1408 25 : .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
1409 : };
1410 :
1411 25 : TALER_amount_hton (&dc.amount_without_fee,
1412 : amount_without_fee);
1413 25 : TALER_amount_hton (&dc.total_deposited,
1414 : total_deposited);
1415 25 : return scb (&dc.purpose,
1416 : pub,
1417 : sig);
1418 : }
1419 :
1420 :
1421 : enum GNUNET_GenericReturnValue
1422 25 : TALER_exchange_online_purse_created_verify (
1423 : struct GNUNET_TIME_Timestamp exchange_time,
1424 : struct GNUNET_TIME_Timestamp purse_expiration,
1425 : const struct TALER_Amount *amount_without_fee,
1426 : const struct TALER_Amount *total_deposited,
1427 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1428 : const struct TALER_PrivateContractHashP *h_contract_terms,
1429 : const struct TALER_ExchangePublicKeyP *pub,
1430 : const struct TALER_ExchangeSignatureP *sig)
1431 : {
1432 50 : struct TALER_PurseCreateDepositConfirmationPS dc = {
1433 25 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION),
1434 25 : .purpose.size = htonl (sizeof (dc)),
1435 : .h_contract_terms = *h_contract_terms,
1436 : .purse_pub = *purse_pub,
1437 25 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1438 25 : .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
1439 : };
1440 :
1441 25 : TALER_amount_hton (&dc.amount_without_fee,
1442 : amount_without_fee);
1443 25 : TALER_amount_hton (&dc.total_deposited,
1444 : total_deposited);
1445 25 : return GNUNET_CRYPTO_eddsa_verify (
1446 : TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION,
1447 : &dc,
1448 : &sig->eddsa_signature,
1449 : &pub->eddsa_pub);
1450 : }
1451 :
1452 :
1453 : GNUNET_NETWORK_STRUCT_BEGIN
1454 :
1455 : /**
1456 : * Response by which the exchange affirms that it has
1457 : * received funds deposited into a purse.
1458 : */
1459 : struct TALER_CoinPurseRefundConfirmationPS
1460 : {
1461 :
1462 : /**
1463 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND
1464 : */
1465 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1466 :
1467 : /**
1468 : * Public key of the purse.
1469 : */
1470 : struct TALER_PurseContractPublicKeyP purse_pub;
1471 :
1472 : /**
1473 : * Public key of the coin.
1474 : */
1475 : struct TALER_CoinSpendPublicKeyP coin_pub;
1476 :
1477 : /**
1478 : * How much will be refunded to the purse.
1479 : */
1480 : struct TALER_AmountNBO refunded_amount;
1481 :
1482 : /**
1483 : * How much was the refund fee.
1484 : */
1485 : struct TALER_AmountNBO refund_fee;
1486 :
1487 : };
1488 :
1489 : GNUNET_NETWORK_STRUCT_END
1490 :
1491 :
1492 : enum TALER_ErrorCode
1493 0 : TALER_exchange_online_purse_refund_sign (
1494 : TALER_ExchangeSignCallback scb,
1495 : const struct TALER_Amount *amount_without_fee,
1496 : const struct TALER_Amount *refund_fee,
1497 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
1498 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1499 : struct TALER_ExchangePublicKeyP *pub,
1500 : struct TALER_ExchangeSignatureP *sig)
1501 : {
1502 0 : struct TALER_CoinPurseRefundConfirmationPS dc = {
1503 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND),
1504 0 : .purpose.size = htonl (sizeof (dc)),
1505 : .coin_pub = *coin_pub,
1506 : .purse_pub = *purse_pub,
1507 : };
1508 :
1509 0 : TALER_amount_hton (&dc.refunded_amount,
1510 : amount_without_fee);
1511 0 : TALER_amount_hton (&dc.refund_fee,
1512 : refund_fee);
1513 0 : return scb (&dc.purpose,
1514 : pub,
1515 : sig);
1516 : }
1517 :
1518 :
1519 : enum GNUNET_GenericReturnValue
1520 0 : TALER_exchange_online_purse_refund_verify (
1521 : const struct TALER_Amount *amount_without_fee,
1522 : const struct TALER_Amount *refund_fee,
1523 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
1524 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1525 : const struct TALER_ExchangePublicKeyP *pub,
1526 : const struct TALER_ExchangeSignatureP *sig)
1527 : {
1528 0 : struct TALER_CoinPurseRefundConfirmationPS dc = {
1529 0 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND),
1530 0 : .purpose.size = htonl (sizeof (dc)),
1531 : .coin_pub = *coin_pub,
1532 : .purse_pub = *purse_pub,
1533 : };
1534 :
1535 0 : TALER_amount_hton (&dc.refunded_amount,
1536 : amount_without_fee);
1537 0 : TALER_amount_hton (&dc.refund_fee,
1538 : refund_fee);
1539 0 : return GNUNET_CRYPTO_eddsa_verify (
1540 : TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND,
1541 : &dc,
1542 : &sig->eddsa_signature,
1543 : &pub->eddsa_pub);
1544 : }
1545 :
1546 :
1547 : GNUNET_NETWORK_STRUCT_BEGIN
1548 :
1549 : /**
1550 : * Response by which the exchange affirms that it has
1551 : * merged a purse into a reserve.
1552 : */
1553 : struct TALER_PurseMergedConfirmationPS
1554 : {
1555 :
1556 : /**
1557 : * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED
1558 : */
1559 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1560 :
1561 : /**
1562 : * When did the exchange receive the deposits.
1563 : */
1564 : struct GNUNET_TIME_TimestampNBO exchange_time;
1565 :
1566 : /**
1567 : * When will the purse expire?
1568 : */
1569 : struct GNUNET_TIME_TimestampNBO purse_expiration;
1570 :
1571 : /**
1572 : * How much should the purse ultimately contain.
1573 : */
1574 : struct TALER_AmountNBO amount_without_fee;
1575 :
1576 : /**
1577 : * Public key of the purse.
1578 : */
1579 : struct TALER_PurseContractPublicKeyP purse_pub;
1580 :
1581 : /**
1582 : * Public key of the reserve.
1583 : */
1584 : struct TALER_ReservePublicKeyP reserve_pub;
1585 :
1586 : /**
1587 : * Hash of the contract of the purse.
1588 : */
1589 : struct TALER_PrivateContractHashP h_contract_terms;
1590 :
1591 : /**
1592 : * Hash of the provider URL hosting the reserve.
1593 : */
1594 : struct GNUNET_HashCode h_provider_url;
1595 :
1596 : };
1597 :
1598 : GNUNET_NETWORK_STRUCT_END
1599 :
1600 :
1601 : enum TALER_ErrorCode
1602 3 : TALER_exchange_online_purse_merged_sign (
1603 : TALER_ExchangeSignCallback scb,
1604 : struct GNUNET_TIME_Timestamp exchange_time,
1605 : struct GNUNET_TIME_Timestamp purse_expiration,
1606 : const struct TALER_Amount *amount_without_fee,
1607 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1608 : const struct TALER_PrivateContractHashP *h_contract_terms,
1609 : const struct TALER_ReservePublicKeyP *reserve_pub,
1610 : const char *exchange_url,
1611 : struct TALER_ExchangePublicKeyP *pub,
1612 : struct TALER_ExchangeSignatureP *sig)
1613 : {
1614 6 : struct TALER_PurseMergedConfirmationPS dc = {
1615 3 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED),
1616 3 : .purpose.size = htonl (sizeof (dc)),
1617 : .h_contract_terms = *h_contract_terms,
1618 : .purse_pub = *purse_pub,
1619 : .reserve_pub = *reserve_pub,
1620 3 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1621 3 : .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
1622 : };
1623 :
1624 3 : TALER_amount_hton (&dc.amount_without_fee,
1625 : amount_without_fee);
1626 3 : GNUNET_CRYPTO_hash (exchange_url,
1627 3 : strlen (exchange_url) + 1,
1628 : &dc.h_provider_url);
1629 3 : return scb (&dc.purpose,
1630 : pub,
1631 : sig);
1632 : }
1633 :
1634 :
1635 : enum GNUNET_GenericReturnValue
1636 3 : TALER_exchange_online_purse_merged_verify (
1637 : struct GNUNET_TIME_Timestamp exchange_time,
1638 : struct GNUNET_TIME_Timestamp purse_expiration,
1639 : const struct TALER_Amount *amount_without_fee,
1640 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1641 : const struct TALER_PrivateContractHashP *h_contract_terms,
1642 : const struct TALER_ReservePublicKeyP *reserve_pub,
1643 : const char *exchange_url,
1644 : const struct TALER_ExchangePublicKeyP *pub,
1645 : const struct TALER_ExchangeSignatureP *sig)
1646 : {
1647 6 : struct TALER_PurseMergedConfirmationPS dc = {
1648 3 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED),
1649 3 : .purpose.size = htonl (sizeof (dc)),
1650 : .h_contract_terms = *h_contract_terms,
1651 : .purse_pub = *purse_pub,
1652 : .reserve_pub = *reserve_pub,
1653 3 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1654 3 : .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
1655 : };
1656 :
1657 3 : TALER_amount_hton (&dc.amount_without_fee,
1658 : amount_without_fee);
1659 3 : GNUNET_CRYPTO_hash (exchange_url,
1660 3 : strlen (exchange_url) + 1,
1661 : &dc.h_provider_url);
1662 : return
1663 3 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED,
1664 : &dc,
1665 : &sig->eddsa_signature,
1666 : &pub->eddsa_pub);
1667 : }
1668 :
1669 :
1670 : GNUNET_NETWORK_STRUCT_BEGIN
1671 :
1672 : /**
1673 : * @brief Format used to generate the signature on a purse status
1674 : * from the exchange.
1675 : */
1676 : struct TALER_PurseStatusPS
1677 : {
1678 : /**
1679 : * Purpose must be #TALER_SIGNATURE_EXCHANGE_PURSE_STATUS. Signed
1680 : * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
1681 : */
1682 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1683 :
1684 : /**
1685 : * Time when the purse was merged, possibly 'never'.
1686 : */
1687 : struct GNUNET_TIME_TimestampNBO merge_timestamp;
1688 :
1689 : /**
1690 : * Time when the purse was deposited last, possibly 'never'.
1691 : */
1692 : struct GNUNET_TIME_TimestampNBO deposit_timestamp;
1693 :
1694 : /**
1695 : * Amount deposited in total in the purse without fees.
1696 : * May be possibly less than the target amount.
1697 : */
1698 : struct TALER_AmountNBO balance;
1699 :
1700 : };
1701 :
1702 : GNUNET_NETWORK_STRUCT_END
1703 :
1704 :
1705 : enum TALER_ErrorCode
1706 6 : TALER_exchange_online_purse_status_sign (
1707 : TALER_ExchangeSignCallback scb,
1708 : struct GNUNET_TIME_Timestamp merge_timestamp,
1709 : struct GNUNET_TIME_Timestamp deposit_timestamp,
1710 : const struct TALER_Amount *balance,
1711 : struct TALER_ExchangePublicKeyP *pub,
1712 : struct TALER_ExchangeSignatureP *sig)
1713 : {
1714 6 : struct TALER_PurseStatusPS dcs = {
1715 6 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS),
1716 6 : .purpose.size = htonl (sizeof (dcs)),
1717 6 : .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
1718 6 : .deposit_timestamp = GNUNET_TIME_timestamp_hton (deposit_timestamp)
1719 : };
1720 :
1721 6 : TALER_amount_hton (&dcs.balance,
1722 : balance);
1723 6 : return scb (&dcs.purpose,
1724 : pub,
1725 : sig);
1726 : }
1727 :
1728 :
1729 : enum GNUNET_GenericReturnValue
1730 6 : TALER_exchange_online_purse_status_verify (
1731 : struct GNUNET_TIME_Timestamp merge_timestamp,
1732 : struct GNUNET_TIME_Timestamp deposit_timestamp,
1733 : const struct TALER_Amount *balance,
1734 : const struct TALER_ExchangePublicKeyP *exchange_pub,
1735 : const struct TALER_ExchangeSignatureP *exchange_sig)
1736 : {
1737 6 : struct TALER_PurseStatusPS dcs = {
1738 6 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS),
1739 6 : .purpose.size = htonl (sizeof (dcs)),
1740 6 : .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
1741 6 : .deposit_timestamp = GNUNET_TIME_timestamp_hton (deposit_timestamp)
1742 : };
1743 :
1744 6 : TALER_amount_hton (&dcs.balance,
1745 : balance);
1746 6 : if (GNUNET_OK !=
1747 6 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS,
1748 : &dcs,
1749 : &exchange_sig->eddsa_signature,
1750 : &exchange_pub->eddsa_pub))
1751 : {
1752 0 : GNUNET_break_op (0);
1753 0 : return GNUNET_SYSERR;
1754 : }
1755 6 : return GNUNET_OK;
1756 : }
1757 :
1758 :
1759 : GNUNET_NETWORK_STRUCT_BEGIN
1760 :
1761 : /**
1762 : * Message signed by the exchange to affirm that the
1763 : * owner of a reserve has certain attributes.
1764 : */
1765 : struct TALER_ExchangeAttestPS
1766 : {
1767 :
1768 : /**
1769 : * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS
1770 : */
1771 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1772 :
1773 : /**
1774 : * Time when the attestation was made.
1775 : */
1776 : struct GNUNET_TIME_TimestampNBO attest_timestamp;
1777 :
1778 : /**
1779 : * Time when the attestation expires.
1780 : */
1781 : struct GNUNET_TIME_TimestampNBO expiration_time;
1782 :
1783 : /**
1784 : * Public key of the reserve for which the attributes
1785 : * are attested.
1786 : */
1787 : struct TALER_ReservePublicKeyP reserve_pub;
1788 :
1789 : /**
1790 : * Hash over the attributes.
1791 : */
1792 : struct GNUNET_HashCode h_attributes;
1793 :
1794 : };
1795 :
1796 : GNUNET_NETWORK_STRUCT_END
1797 :
1798 :
1799 : enum TALER_ErrorCode
1800 1 : TALER_exchange_online_reserve_attest_details_sign (
1801 : TALER_ExchangeSignCallback scb,
1802 : struct GNUNET_TIME_Timestamp attest_timestamp,
1803 : struct GNUNET_TIME_Timestamp expiration_time,
1804 : const struct TALER_ReservePublicKeyP *reserve_pub,
1805 : const json_t *attributes,
1806 : struct TALER_ExchangePublicKeyP *pub,
1807 : struct TALER_ExchangeSignatureP *sig)
1808 : {
1809 2 : struct TALER_ExchangeAttestPS rap = {
1810 1 : .purpose.size = htonl (sizeof (rap)),
1811 1 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS),
1812 1 : .attest_timestamp = GNUNET_TIME_timestamp_hton (attest_timestamp),
1813 1 : .expiration_time = GNUNET_TIME_timestamp_hton (expiration_time),
1814 : .reserve_pub = *reserve_pub
1815 : };
1816 :
1817 1 : TALER_json_hash (attributes,
1818 : &rap.h_attributes);
1819 1 : return scb (&rap.purpose,
1820 : pub,
1821 : sig);
1822 : }
1823 :
1824 :
1825 : enum GNUNET_GenericReturnValue
1826 1 : TALER_exchange_online_reserve_attest_details_verify (
1827 : struct GNUNET_TIME_Timestamp attest_timestamp,
1828 : struct GNUNET_TIME_Timestamp expiration_time,
1829 : const struct TALER_ReservePublicKeyP *reserve_pub,
1830 : const json_t *attributes,
1831 : struct TALER_ExchangePublicKeyP *pub,
1832 : struct TALER_ExchangeSignatureP *sig)
1833 : {
1834 2 : struct TALER_ExchangeAttestPS rap = {
1835 1 : .purpose.size = htonl (sizeof (rap)),
1836 1 : .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS),
1837 1 : .attest_timestamp = GNUNET_TIME_timestamp_hton (attest_timestamp),
1838 1 : .expiration_time = GNUNET_TIME_timestamp_hton (expiration_time),
1839 : .reserve_pub = *reserve_pub
1840 : };
1841 :
1842 1 : TALER_json_hash (attributes,
1843 : &rap.h_attributes);
1844 1 : if (GNUNET_OK !=
1845 1 : GNUNET_CRYPTO_eddsa_verify (
1846 : TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS,
1847 : &rap,
1848 : &sig->eddsa_signature,
1849 : &pub->eddsa_pub))
1850 : {
1851 0 : GNUNET_break_op (0);
1852 0 : return GNUNET_SYSERR;
1853 : }
1854 1 : return GNUNET_OK;
1855 : }
1856 :
1857 :
1858 : /* end of exchange_signatures.c */
|