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