Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2021, 2022 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file wallet_signatures.c
18 : * @brief Utility functions for Taler wallet signatures
19 : * @author Christian Grothoff
20 : */
21 : #include "platform.h"
22 : #include "taler_util.h"
23 : #include "taler_signatures.h"
24 :
25 :
26 : /**
27 : * @brief Format used to generate the signature on a request to deposit
28 : * a coin into the account of a merchant.
29 : */
30 : struct TALER_DepositRequestPS
31 : {
32 : /**
33 : * Purpose must be #TALER_SIGNATURE_WALLET_COIN_DEPOSIT.
34 : * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`.
35 : */
36 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
37 :
38 : /**
39 : * Hash over the contract for which this deposit is made.
40 : */
41 : struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
42 :
43 : /**
44 : * Hash over the age commitment that went into the coin. Maybe all zero, if
45 : * age commitment isn't applicable to the denomination.
46 : */
47 : struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED;
48 :
49 : /**
50 : * Hash over extension attributes shared with the exchange.
51 : */
52 : struct TALER_ExtensionContractHashP h_extensions GNUNET_PACKED;
53 :
54 : /**
55 : * Hash over the wiring information of the merchant.
56 : */
57 : struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
58 :
59 : /**
60 : * Hash over the denomination public key used to sign the coin.
61 : */
62 : struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED;
63 :
64 : /**
65 : * Time when this request was generated. Used, for example, to
66 : * assess when (roughly) the income was achieved for tax purposes.
67 : * Note that the Exchange will only check that the timestamp is not "too
68 : * far" into the future (i.e. several days). The fact that the
69 : * timestamp falls within the validity period of the coin's
70 : * denomination key is irrelevant for the validity of the deposit
71 : * request, as obviously the customer and merchant could conspire to
72 : * set any timestamp. Also, the Exchange must accept very old deposit
73 : * requests, as the merchant might have been unable to transmit the
74 : * deposit request in a timely fashion (so back-dating is not
75 : * prevented).
76 : */
77 : struct GNUNET_TIME_TimestampNBO wallet_timestamp;
78 :
79 : /**
80 : * How much time does the merchant have to issue a refund request?
81 : * Zero if refunds are not allowed. After this time, the coin
82 : * cannot be refunded.
83 : */
84 : struct GNUNET_TIME_TimestampNBO refund_deadline;
85 :
86 : /**
87 : * Amount to be deposited, including deposit fee charged by the
88 : * exchange. This is the total amount that the coin's value at the exchange
89 : * will be reduced by.
90 : */
91 : struct TALER_AmountNBO amount_with_fee;
92 :
93 : /**
94 : * Depositing fee charged by the exchange. This must match the Exchange's
95 : * denomination key's depositing fee. If the client puts in an
96 : * invalid deposit fee (too high or too low) that does not match the
97 : * Exchange's denomination key, the deposit operation is invalid and
98 : * will be rejected by the exchange. The @e amount_with_fee minus the
99 : * @e deposit_fee is the amount that will be transferred to the
100 : * account identified by @e h_wire.
101 : */
102 : struct TALER_AmountNBO deposit_fee;
103 :
104 : /**
105 : * The Merchant's public key. Allows the merchant to later refund
106 : * the transaction or to inquire about the wire transfer identifier.
107 : */
108 : struct TALER_MerchantPublicKeyP merchant;
109 :
110 : };
111 :
112 :
113 : void
114 0 : TALER_wallet_deposit_sign (
115 : const struct TALER_Amount *amount,
116 : const struct TALER_Amount *deposit_fee,
117 : const struct TALER_MerchantWireHashP *h_wire,
118 : const struct TALER_PrivateContractHashP *h_contract_terms,
119 : const struct TALER_AgeCommitmentHash *h_age_commitment,
120 : const struct TALER_ExtensionContractHashP *h_extensions,
121 : const struct TALER_DenominationHashP *h_denom_pub,
122 : const struct GNUNET_TIME_Timestamp wallet_timestamp,
123 : const struct TALER_MerchantPublicKeyP *merchant_pub,
124 : const struct GNUNET_TIME_Timestamp refund_deadline,
125 : const struct TALER_CoinSpendPrivateKeyP *coin_priv,
126 : struct TALER_CoinSpendSignatureP *coin_sig)
127 : {
128 0 : struct TALER_DepositRequestPS dr = {
129 0 : .purpose.size = htonl (sizeof (dr)),
130 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
131 : .h_contract_terms = *h_contract_terms,
132 : .h_wire = *h_wire,
133 : .h_denom_pub = *h_denom_pub,
134 0 : .wallet_timestamp = GNUNET_TIME_timestamp_hton (wallet_timestamp),
135 0 : .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
136 : .merchant = *merchant_pub
137 : };
138 :
139 0 : if (NULL != h_age_commitment)
140 0 : dr.h_age_commitment = *h_age_commitment;
141 0 : if (NULL != h_extensions)
142 0 : dr.h_extensions = *h_extensions;
143 0 : TALER_amount_hton (&dr.amount_with_fee,
144 : amount);
145 0 : TALER_amount_hton (&dr.deposit_fee,
146 : deposit_fee);
147 0 : GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
148 : &dr,
149 : &coin_sig->eddsa_signature);
150 0 : }
151 :
152 :
153 : enum GNUNET_GenericReturnValue
154 0 : TALER_wallet_deposit_verify (
155 : const struct TALER_Amount *amount,
156 : const struct TALER_Amount *deposit_fee,
157 : const struct TALER_MerchantWireHashP *h_wire,
158 : const struct TALER_PrivateContractHashP *h_contract_terms,
159 : const struct TALER_AgeCommitmentHash *h_age_commitment,
160 : const struct TALER_ExtensionContractHashP *h_extensions,
161 : const struct TALER_DenominationHashP *h_denom_pub,
162 : struct GNUNET_TIME_Timestamp wallet_timestamp,
163 : const struct TALER_MerchantPublicKeyP *merchant_pub,
164 : struct GNUNET_TIME_Timestamp refund_deadline,
165 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
166 : const struct TALER_CoinSpendSignatureP *coin_sig)
167 : {
168 0 : struct TALER_DepositRequestPS dr = {
169 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
170 0 : .purpose.size = htonl (sizeof (dr)),
171 : .h_contract_terms = *h_contract_terms,
172 : .h_wire = *h_wire,
173 : .h_denom_pub = *h_denom_pub,
174 0 : .wallet_timestamp = GNUNET_TIME_timestamp_hton (wallet_timestamp),
175 0 : .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
176 : .merchant = *merchant_pub,
177 : .h_age_commitment = {{{0}}},
178 : .h_extensions = {{{0}}}
179 : };
180 :
181 0 : if (NULL != h_age_commitment)
182 0 : dr.h_age_commitment = *h_age_commitment;
183 0 : if (NULL != h_extensions)
184 0 : dr.h_extensions = *h_extensions;
185 0 : TALER_amount_hton (&dr.amount_with_fee,
186 : amount);
187 0 : TALER_amount_hton (&dr.deposit_fee,
188 : deposit_fee);
189 0 : if (GNUNET_OK !=
190 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
191 : &dr,
192 : &coin_sig->eddsa_signature,
193 : &coin_pub->eddsa_pub))
194 : {
195 0 : GNUNET_break_op (0);
196 0 : return GNUNET_SYSERR;
197 : }
198 0 : return GNUNET_OK;
199 : }
200 :
201 :
202 : /**
203 : * @brief Format used for to allow the wallet to authenticate
204 : * link data provided by the exchange.
205 : */
206 : struct TALER_LinkDataPS
207 : {
208 :
209 : /**
210 : * Purpose must be #TALER_SIGNATURE_WALLET_COIN_LINK.
211 : * Used with an EdDSA signature of a `struct TALER_CoinPublicKeyP`.
212 : */
213 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
214 :
215 : /**
216 : * Hash of the denomination public key of the new coin.
217 : */
218 : struct TALER_DenominationHashP h_denom_pub;
219 :
220 : /**
221 : * Transfer public key (for which the private key was not revealed)
222 : */
223 : struct TALER_TransferPublicKeyP transfer_pub;
224 :
225 : /**
226 : * Hash of the age commitment, if applicable. Can be all zero
227 : */
228 : struct TALER_AgeCommitmentHash h_age_commitment;
229 :
230 : /**
231 : * Hash of the blinded new coin.
232 : */
233 : struct TALER_BlindedCoinHashP coin_envelope_hash;
234 : };
235 :
236 :
237 : void
238 0 : TALER_wallet_link_sign (const struct TALER_DenominationHashP *h_denom_pub,
239 : const struct TALER_TransferPublicKeyP *transfer_pub,
240 : const struct TALER_BlindedCoinHashP *bch,
241 : const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
242 : struct TALER_CoinSpendSignatureP *coin_sig)
243 : {
244 0 : struct TALER_LinkDataPS ldp = {
245 0 : .purpose.size = htonl (sizeof (ldp)),
246 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
247 : .h_denom_pub = *h_denom_pub,
248 : .transfer_pub = *transfer_pub,
249 : .coin_envelope_hash = *bch
250 : };
251 :
252 0 : GNUNET_CRYPTO_eddsa_sign (&old_coin_priv->eddsa_priv,
253 : &ldp,
254 : &coin_sig->eddsa_signature);
255 0 : }
256 :
257 :
258 : enum GNUNET_GenericReturnValue
259 0 : TALER_wallet_link_verify (
260 : const struct TALER_DenominationHashP *h_denom_pub,
261 : const struct TALER_TransferPublicKeyP *transfer_pub,
262 : const struct TALER_BlindedCoinHashP *h_coin_ev,
263 : const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
264 : const struct TALER_CoinSpendSignatureP *coin_sig)
265 : {
266 0 : struct TALER_LinkDataPS ldp = {
267 0 : .purpose.size = htonl (sizeof (ldp)),
268 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
269 : .h_denom_pub = *h_denom_pub,
270 : .transfer_pub = *transfer_pub,
271 : .coin_envelope_hash = *h_coin_ev,
272 : };
273 :
274 : return
275 0 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_LINK,
276 : &ldp,
277 : &coin_sig->eddsa_signature,
278 : &old_coin_pub->eddsa_pub);
279 : }
280 :
281 :
282 : /**
283 : * Signed data to request that a coin should be refunded as part of
284 : * the "emergency" /recoup protocol. The refund will go back to the bank
285 : * account that created the reserve.
286 : */
287 : struct TALER_RecoupRequestPS
288 : {
289 : /**
290 : * Purpose is #TALER_SIGNATURE_WALLET_COIN_RECOUP
291 : * or #TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH.
292 : */
293 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
294 :
295 : /**
296 : * Hash of the (revoked) denomination public key of the coin.
297 : */
298 : struct TALER_DenominationHashP h_denom_pub;
299 :
300 : /**
301 : * Blinding factor that was used to withdraw the coin.
302 : */
303 : union TALER_DenominationBlindingKeyP coin_blind;
304 :
305 : };
306 :
307 :
308 : enum GNUNET_GenericReturnValue
309 0 : TALER_wallet_recoup_verify (
310 : const struct TALER_DenominationHashP *h_denom_pub,
311 : const union TALER_DenominationBlindingKeyP *coin_bks,
312 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
313 : const struct TALER_CoinSpendSignatureP *coin_sig)
314 : {
315 0 : struct TALER_RecoupRequestPS pr = {
316 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
317 0 : .purpose.size = htonl (sizeof (pr)),
318 : .h_denom_pub = *h_denom_pub,
319 : .coin_blind = *coin_bks
320 : };
321 :
322 0 : return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
323 : &pr,
324 : &coin_sig->eddsa_signature,
325 : &coin_pub->eddsa_pub);
326 : }
327 :
328 :
329 : void
330 0 : TALER_wallet_recoup_sign (
331 : const struct TALER_DenominationHashP *h_denom_pub,
332 : const union TALER_DenominationBlindingKeyP *coin_bks,
333 : const struct TALER_CoinSpendPrivateKeyP *coin_priv,
334 : struct TALER_CoinSpendSignatureP *coin_sig)
335 : {
336 0 : struct TALER_RecoupRequestPS pr = {
337 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
338 0 : .purpose.size = htonl (sizeof (pr)),
339 : .h_denom_pub = *h_denom_pub,
340 : .coin_blind = *coin_bks
341 : };
342 :
343 0 : GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
344 : &pr,
345 : &coin_sig->eddsa_signature);
346 0 : }
347 :
348 :
349 : enum GNUNET_GenericReturnValue
350 0 : TALER_wallet_recoup_refresh_verify (
351 : const struct TALER_DenominationHashP *h_denom_pub,
352 : const union TALER_DenominationBlindingKeyP *coin_bks,
353 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
354 : const struct TALER_CoinSpendSignatureP *coin_sig)
355 : {
356 0 : struct TALER_RecoupRequestPS pr = {
357 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH),
358 0 : .purpose.size = htonl (sizeof (pr)),
359 : .h_denom_pub = *h_denom_pub,
360 : .coin_blind = *coin_bks
361 : };
362 :
363 0 : return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH,
364 : &pr,
365 : &coin_sig->eddsa_signature,
366 : &coin_pub->eddsa_pub);
367 : }
368 :
369 :
370 : void
371 0 : TALER_wallet_recoup_refresh_sign (
372 : const struct TALER_DenominationHashP *h_denom_pub,
373 : const union TALER_DenominationBlindingKeyP *coin_bks,
374 : const struct TALER_CoinSpendPrivateKeyP *coin_priv,
375 : struct TALER_CoinSpendSignatureP *coin_sig)
376 : {
377 0 : struct TALER_RecoupRequestPS pr = {
378 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH),
379 0 : .purpose.size = htonl (sizeof (struct TALER_RecoupRequestPS)),
380 : .h_denom_pub = *h_denom_pub,
381 : .coin_blind = *coin_bks
382 : };
383 :
384 0 : GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
385 : &pr,
386 : &coin_sig->eddsa_signature);
387 0 : }
388 :
389 :
390 : /**
391 : * @brief Message signed by a coin to indicate that the coin should be
392 : * melted.
393 : */
394 : struct TALER_RefreshMeltCoinAffirmationPS
395 : {
396 : /**
397 : * Purpose is #TALER_SIGNATURE_WALLET_COIN_MELT.
398 : * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`.
399 : */
400 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
401 :
402 : /**
403 : * Which melt commitment is made by the wallet.
404 : */
405 : struct TALER_RefreshCommitmentP rc GNUNET_PACKED;
406 :
407 : /**
408 : * Hash over the denomination public key used to sign the coin.
409 : */
410 : struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED;
411 :
412 : /**
413 : * If age commitment was provided during the withdrawal of the coin, this is
414 : * the hash of the age commitment vector. It must be all zeroes if no age
415 : * commitment was provided.
416 : */
417 : struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED;
418 :
419 : /**
420 : * How much of the value of the coin should be melted? This amount
421 : * includes the fees, so the final amount contributed to the melt is
422 : * this value minus the fee for melting the coin. We include the
423 : * fee in what is being signed so that we can verify a reserve's
424 : * remaining total balance without needing to access the respective
425 : * denomination key information each time.
426 : */
427 : struct TALER_AmountNBO amount_with_fee;
428 :
429 : /**
430 : * Melting fee charged by the exchange. This must match the Exchange's
431 : * denomination key's melting fee. If the client puts in an invalid
432 : * melting fee (too high or too low) that does not match the Exchange's
433 : * denomination key, the melting operation is invalid and will be
434 : * rejected by the exchange. The @e amount_with_fee minus the @e
435 : * melt_fee is the amount that will be credited to the melting
436 : * session.
437 : */
438 : struct TALER_AmountNBO melt_fee;
439 : };
440 :
441 :
442 : void
443 0 : TALER_wallet_melt_sign (
444 : const struct TALER_Amount *amount_with_fee,
445 : const struct TALER_Amount *melt_fee,
446 : const struct TALER_RefreshCommitmentP *rc,
447 : const struct TALER_DenominationHashP *h_denom_pub,
448 : const struct TALER_AgeCommitmentHash *h_age_commitment,
449 : const struct TALER_CoinSpendPrivateKeyP *coin_priv,
450 : struct TALER_CoinSpendSignatureP *coin_sig)
451 : {
452 0 : struct TALER_RefreshMeltCoinAffirmationPS melt = {
453 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT),
454 0 : .purpose.size = htonl (sizeof (melt)),
455 : .rc = *rc,
456 : .h_denom_pub = *h_denom_pub,
457 : .h_age_commitment = {{{0}}},
458 : };
459 :
460 0 : if (NULL != h_age_commitment)
461 0 : melt.h_age_commitment = *h_age_commitment;
462 :
463 :
464 0 : TALER_amount_hton (&melt.amount_with_fee,
465 : amount_with_fee);
466 0 : TALER_amount_hton (&melt.melt_fee,
467 : melt_fee);
468 0 : GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
469 : &melt,
470 : &coin_sig->eddsa_signature);
471 0 : }
472 :
473 :
474 : enum GNUNET_GenericReturnValue
475 0 : TALER_wallet_melt_verify (
476 : const struct TALER_Amount *amount_with_fee,
477 : const struct TALER_Amount *melt_fee,
478 : const struct TALER_RefreshCommitmentP *rc,
479 : const struct TALER_DenominationHashP *h_denom_pub,
480 : const struct TALER_AgeCommitmentHash *h_age_commitment,
481 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
482 : const struct TALER_CoinSpendSignatureP *coin_sig)
483 : {
484 0 : struct TALER_RefreshMeltCoinAffirmationPS melt = {
485 0 : .purpose.size = htonl (sizeof (melt)),
486 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT),
487 : .rc = *rc,
488 : .h_denom_pub = *h_denom_pub,
489 : .h_age_commitment = {{{0}}},
490 : };
491 :
492 0 : if (NULL != h_age_commitment)
493 0 : melt.h_age_commitment = *h_age_commitment;
494 :
495 0 : TALER_amount_hton (&melt.amount_with_fee,
496 : amount_with_fee);
497 0 : TALER_amount_hton (&melt.melt_fee,
498 : melt_fee);
499 0 : return GNUNET_CRYPTO_eddsa_verify (
500 : TALER_SIGNATURE_WALLET_COIN_MELT,
501 : &melt,
502 : &coin_sig->eddsa_signature,
503 : &coin_pub->eddsa_pub);
504 : }
505 :
506 :
507 : /**
508 : * @brief Format used for to generate the signature on a request to withdraw
509 : * coins from a reserve.
510 : */
511 : struct TALER_WithdrawRequestPS
512 : {
513 :
514 : /**
515 : * Purpose must be #TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW.
516 : * Used with an EdDSA signature of a `struct TALER_ReservePublicKeyP`.
517 : */
518 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
519 :
520 : /**
521 : * Value of the coin being exchanged (matching the denomination key)
522 : * plus the transaction fee. We include this in what is being
523 : * signed so that we can verify a reserve's remaining total balance
524 : * without needing to access the respective denomination key
525 : * information each time.
526 : */
527 : struct TALER_AmountNBO amount_with_fee;
528 :
529 : /**
530 : * Hash of the denomination public key for the coin that is withdrawn.
531 : */
532 : struct TALER_DenominationHashP h_denomination_pub GNUNET_PACKED;
533 :
534 : /**
535 : * Hash of the (blinded) message to be signed by the Exchange.
536 : */
537 : struct TALER_BlindedCoinHashP h_coin_envelope GNUNET_PACKED;
538 : };
539 :
540 :
541 : void
542 0 : TALER_wallet_withdraw_sign (
543 : const struct TALER_DenominationHashP *h_denom_pub,
544 : const struct TALER_Amount *amount_with_fee,
545 : const struct TALER_BlindedCoinHashP *bch,
546 : const struct TALER_ReservePrivateKeyP *reserve_priv,
547 : struct TALER_ReserveSignatureP *reserve_sig)
548 : {
549 0 : struct TALER_WithdrawRequestPS req = {
550 0 : .purpose.size = htonl (sizeof (req)),
551 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
552 : .h_denomination_pub = *h_denom_pub,
553 : .h_coin_envelope = *bch
554 : };
555 :
556 0 : TALER_amount_hton (&req.amount_with_fee,
557 : amount_with_fee);
558 0 : GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
559 : &req,
560 : &reserve_sig->eddsa_signature);
561 0 : }
562 :
563 :
564 : enum GNUNET_GenericReturnValue
565 0 : TALER_wallet_withdraw_verify (
566 : const struct TALER_DenominationHashP *h_denom_pub,
567 : const struct TALER_Amount *amount_with_fee,
568 : const struct TALER_BlindedCoinHashP *bch,
569 : const struct TALER_ReservePublicKeyP *reserve_pub,
570 : const struct TALER_ReserveSignatureP *reserve_sig)
571 : {
572 0 : struct TALER_WithdrawRequestPS wsrd = {
573 0 : .purpose.size = htonl (sizeof (wsrd)),
574 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
575 : .h_denomination_pub = *h_denom_pub,
576 : .h_coin_envelope = *bch
577 : };
578 :
579 0 : TALER_amount_hton (&wsrd.amount_with_fee,
580 : amount_with_fee);
581 0 : return GNUNET_CRYPTO_eddsa_verify (
582 : TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
583 : &wsrd,
584 : &reserve_sig->eddsa_signature,
585 : &reserve_pub->eddsa_pub);
586 : }
587 :
588 :
589 : void
590 0 : TALER_wallet_account_setup_sign (
591 : const struct TALER_ReservePrivateKeyP *reserve_priv,
592 : struct TALER_ReserveSignatureP *reserve_sig)
593 : {
594 0 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
595 0 : .size = htonl (sizeof (purpose)),
596 0 : .purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP)
597 : };
598 :
599 0 : GNUNET_assert (GNUNET_OK ==
600 : GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
601 : &purpose,
602 : &reserve_sig->eddsa_signature));
603 0 : }
604 :
605 :
606 : enum GNUNET_GenericReturnValue
607 0 : TALER_wallet_account_setup_verify (
608 : const struct TALER_ReservePublicKeyP *reserve_pub,
609 : const struct TALER_ReserveSignatureP *reserve_sig)
610 : {
611 0 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
612 0 : .size = htonl (sizeof (purpose)),
613 0 : .purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP)
614 : };
615 :
616 0 : return GNUNET_CRYPTO_eddsa_verify_ (
617 : TALER_SIGNATURE_WALLET_ACCOUNT_SETUP,
618 : &purpose,
619 : &reserve_sig->eddsa_signature,
620 : &reserve_pub->eddsa_pub);
621 : }
622 :
623 :
624 : /**
625 : * Response by which a wallet requests a full
626 : * reserve history and indicates it is willing
627 : * to pay for it.
628 : */
629 : struct TALER_ReserveHistoryRequestPS
630 : {
631 :
632 : /**
633 : * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_HISTORY
634 : */
635 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
636 :
637 : /**
638 : * When did the wallet make the request.
639 : */
640 : struct GNUNET_TIME_TimestampNBO request_timestamp;
641 :
642 : /**
643 : * How much does the exchange charge for the history?
644 : */
645 : struct TALER_AmountNBO history_fee;
646 :
647 : };
648 :
649 :
650 : enum GNUNET_GenericReturnValue
651 0 : TALER_wallet_reserve_history_verify (
652 : const struct GNUNET_TIME_Timestamp ts,
653 : const struct TALER_Amount *history_fee,
654 : const struct TALER_ReservePublicKeyP *reserve_pub,
655 : const struct TALER_ReserveSignatureP *reserve_sig)
656 : {
657 0 : struct TALER_ReserveHistoryRequestPS rhr = {
658 0 : .purpose.size = htonl (sizeof (rhr)),
659 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_HISTORY),
660 0 : .request_timestamp = GNUNET_TIME_timestamp_hton (ts)
661 : };
662 :
663 0 : TALER_amount_hton (&rhr.history_fee,
664 : history_fee);
665 0 : return GNUNET_CRYPTO_eddsa_verify (
666 : TALER_SIGNATURE_WALLET_RESERVE_HISTORY,
667 : &rhr,
668 : &reserve_sig->eddsa_signature,
669 : &reserve_pub->eddsa_pub);
670 : }
671 :
672 :
673 : void
674 0 : TALER_wallet_reserve_history_sign (
675 : const struct GNUNET_TIME_Timestamp ts,
676 : const struct TALER_Amount *history_fee,
677 : const struct TALER_ReservePrivateKeyP *reserve_priv,
678 : struct TALER_ReserveSignatureP *reserve_sig)
679 : {
680 0 : struct TALER_ReserveHistoryRequestPS rhr = {
681 0 : .purpose.size = htonl (sizeof (rhr)),
682 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_HISTORY),
683 0 : .request_timestamp = GNUNET_TIME_timestamp_hton (ts)
684 : };
685 :
686 0 : TALER_amount_hton (&rhr.history_fee,
687 : history_fee);
688 0 : GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
689 : &rhr,
690 : &reserve_sig->eddsa_signature);
691 0 : }
692 :
693 :
694 : /**
695 : * Response by which a wallet requests an account status.
696 : */
697 : struct TALER_ReserveStatusRequestPS
698 : {
699 :
700 : /**
701 : * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_STATUS
702 : */
703 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
704 :
705 : /**
706 : * When did the wallet make the request.
707 : */
708 : struct GNUNET_TIME_TimestampNBO request_timestamp;
709 :
710 : };
711 :
712 :
713 : enum GNUNET_GenericReturnValue
714 0 : TALER_wallet_reserve_status_verify (
715 : const struct GNUNET_TIME_Timestamp ts,
716 : const struct TALER_ReservePublicKeyP *reserve_pub,
717 : const struct TALER_ReserveSignatureP *reserve_sig)
718 : {
719 0 : struct TALER_ReserveStatusRequestPS rsr = {
720 0 : .purpose.size = htonl (sizeof (rsr)),
721 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_STATUS),
722 0 : .request_timestamp = GNUNET_TIME_timestamp_hton (ts)
723 : };
724 :
725 0 : return GNUNET_CRYPTO_eddsa_verify (
726 : TALER_SIGNATURE_WALLET_RESERVE_STATUS,
727 : &rsr,
728 : &reserve_sig->eddsa_signature,
729 : &reserve_pub->eddsa_pub);
730 : }
731 :
732 :
733 : void
734 0 : TALER_wallet_reserve_status_sign (
735 : const struct GNUNET_TIME_Timestamp ts,
736 : const struct TALER_ReservePrivateKeyP *reserve_priv,
737 : struct TALER_ReserveSignatureP *reserve_sig)
738 : {
739 0 : struct TALER_ReserveStatusRequestPS rsr = {
740 0 : .purpose.size = htonl (sizeof (rsr)),
741 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_STATUS),
742 0 : .request_timestamp = GNUNET_TIME_timestamp_hton (ts)
743 : };
744 :
745 0 : GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
746 : &rsr,
747 : &reserve_sig->eddsa_signature);
748 0 : }
749 :
750 :
751 : /**
752 : * Message signed to create a purse (without reserve).
753 : */
754 : struct TALER_PurseCreatePS
755 : {
756 :
757 : /**
758 : * Purpose is #TALER_SIGNATURE_WALLET_PURSE_CREATE
759 : */
760 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
761 :
762 : /**
763 : * Time when the purse will expire if still unmerged or unpaid.
764 : */
765 : struct GNUNET_TIME_TimestampNBO purse_expiration;
766 :
767 : /**
768 : * Total amount (with fees) to be put into the purse.
769 : */
770 : struct TALER_AmountNBO purse_amount;
771 :
772 : /**
773 : * Contract this purse pays for.
774 : */
775 : struct TALER_PrivateContractHashP h_contract_terms;
776 :
777 : /**
778 : * Public key identifying the merge capability.
779 : */
780 : struct TALER_PurseMergePublicKeyP merge_pub;
781 :
782 : /**
783 : * Minimum age required for payments into this purse.
784 : */
785 : uint32_t min_age GNUNET_PACKED;
786 :
787 : };
788 :
789 :
790 : void
791 0 : TALER_wallet_purse_create_sign (
792 : struct GNUNET_TIME_Timestamp purse_expiration,
793 : struct TALER_PrivateContractHashP *h_contract_terms,
794 : const struct TALER_PurseMergePublicKeyP *merge_pub,
795 : uint32_t min_age,
796 : const struct TALER_Amount *amount,
797 : const struct TALER_PurseContractPrivateKeyP *purse_priv,
798 : struct TALER_PurseContractSignatureP *purse_sig)
799 : {
800 0 : struct TALER_PurseCreatePS pm = {
801 0 : .purpose.size = htonl (sizeof (pm)),
802 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_CREATE),
803 0 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
804 : .h_contract_terms = *h_contract_terms,
805 : .merge_pub = *merge_pub,
806 0 : .min_age = htonl (min_age)
807 : };
808 :
809 0 : TALER_amount_hton (&pm.purse_amount,
810 : amount);
811 0 : GNUNET_CRYPTO_eddsa_sign (&purse_priv->eddsa_priv,
812 : &pm,
813 : &purse_sig->eddsa_signature);
814 0 : }
815 :
816 :
817 : enum GNUNET_GenericReturnValue
818 0 : TALER_wallet_purse_create_verify (
819 : struct GNUNET_TIME_Timestamp purse_expiration,
820 : struct TALER_PrivateContractHashP *h_contract_terms,
821 : const struct TALER_PurseMergePublicKeyP *merge_pub,
822 : uint32_t min_age,
823 : const struct TALER_Amount *amount,
824 : const struct TALER_PurseContractPublicKeyP *purse_pub,
825 : const struct TALER_PurseContractSignatureP *purse_sig)
826 : {
827 0 : struct TALER_PurseCreatePS pm = {
828 0 : .purpose.size = htonl (sizeof (pm)),
829 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_CREATE),
830 0 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
831 : .h_contract_terms = *h_contract_terms,
832 : .merge_pub = *merge_pub,
833 0 : .min_age = htonl (min_age)
834 : };
835 :
836 0 : TALER_amount_hton (&pm.purse_amount,
837 : amount);
838 0 : return GNUNET_CRYPTO_eddsa_verify (
839 : TALER_SIGNATURE_WALLET_PURSE_CREATE,
840 : &pm,
841 : &purse_sig->eddsa_signature,
842 : &purse_pub->eddsa_pub);
843 : }
844 :
845 :
846 : void
847 0 : TALER_wallet_purse_status_sign (
848 : const struct TALER_PurseContractPrivateKeyP *purse_priv,
849 : struct TALER_PurseContractSignatureP *purse_sig)
850 : {
851 0 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
852 0 : .size = htonl (sizeof (purpose)),
853 0 : .purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_STATUS)
854 : };
855 :
856 0 : GNUNET_assert (GNUNET_OK ==
857 : GNUNET_CRYPTO_eddsa_sign_ (&purse_priv->eddsa_priv,
858 : &purpose,
859 : &purse_sig->eddsa_signature));
860 0 : }
861 :
862 :
863 : enum GNUNET_GenericReturnValue
864 0 : TALER_wallet_purse_status_verify (
865 : const struct TALER_PurseContractPublicKeyP *purse_pub,
866 : const struct TALER_PurseContractSignatureP *purse_sig)
867 : {
868 0 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
869 0 : .size = htonl (sizeof (purpose)),
870 0 : .purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_STATUS)
871 : };
872 :
873 0 : return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_PURSE_STATUS,
874 : &purpose,
875 : &purse_sig->eddsa_signature,
876 : &purse_pub->eddsa_pub);
877 : }
878 :
879 :
880 : /**
881 : * Message signed to deposit a coin into a purse.
882 : */
883 : struct TALER_PurseDepositPS
884 : {
885 :
886 : /**
887 : * Purpose is #TALER_SIGNATURE_WALLET_PURSE_DEPOSIT
888 : */
889 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
890 :
891 : /**
892 : * Amount (with deposit fee) to be deposited into the purse.
893 : */
894 : struct TALER_AmountNBO coin_amount;
895 :
896 : /**
897 : * Hash over the denomination public key used to sign the coin.
898 : */
899 : struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED;
900 :
901 : /**
902 : * Hash over the age commitment that went into the coin. Maybe all zero, if
903 : * age commitment isn't applicable to the denomination.
904 : */
905 : struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED;
906 :
907 : /**
908 : * Purse to deposit funds into.
909 : */
910 : struct TALER_PurseContractPublicKeyP purse_pub;
911 :
912 : /**
913 : * Hash of the base URL of the exchange hosting the
914 : * @e purse_pub.
915 : */
916 : struct GNUNET_HashCode h_exchange_base_url GNUNET_PACKED;
917 : };
918 :
919 :
920 : void
921 0 : TALER_wallet_purse_deposit_sign (
922 : const char *exchange_base_url,
923 : const struct TALER_PurseContractPublicKeyP *purse_pub,
924 : const struct TALER_Amount *amount,
925 : const struct TALER_DenominationHashP *h_denom_pub,
926 : const struct TALER_AgeCommitmentHash *h_age_commitment,
927 : const struct TALER_CoinSpendPrivateKeyP *coin_priv,
928 : struct TALER_CoinSpendSignatureP *coin_sig)
929 : {
930 0 : struct TALER_PurseDepositPS pm = {
931 0 : .purpose.size = htonl (sizeof (pm)),
932 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
933 : .purse_pub = *purse_pub,
934 : .h_denom_pub = *h_denom_pub,
935 : .h_age_commitment = *h_age_commitment
936 : };
937 :
938 0 : GNUNET_CRYPTO_hash (exchange_base_url,
939 0 : strlen (exchange_base_url) + 1,
940 : &pm.h_exchange_base_url);
941 0 : TALER_amount_hton (&pm.coin_amount,
942 : amount);
943 0 : GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
944 : &pm,
945 : &coin_sig->eddsa_signature);
946 0 : }
947 :
948 :
949 : enum GNUNET_GenericReturnValue
950 0 : TALER_wallet_purse_deposit_verify (
951 : const char *exchange_base_url,
952 : const struct TALER_PurseContractPublicKeyP *purse_pub,
953 : const struct TALER_Amount *amount,
954 : const struct TALER_DenominationHashP *h_denom_pub,
955 : const struct TALER_AgeCommitmentHash *h_age_commitment,
956 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
957 : const struct TALER_CoinSpendSignatureP *coin_sig)
958 : {
959 0 : struct TALER_PurseDepositPS pm = {
960 0 : .purpose.size = htonl (sizeof (pm)),
961 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
962 : .purse_pub = *purse_pub,
963 : .h_denom_pub = *h_denom_pub,
964 : .h_age_commitment = *h_age_commitment
965 : };
966 :
967 0 : GNUNET_CRYPTO_hash (exchange_base_url,
968 0 : strlen (exchange_base_url) + 1,
969 : &pm.h_exchange_base_url);
970 0 : TALER_amount_hton (&pm.coin_amount,
971 : amount);
972 0 : return GNUNET_CRYPTO_eddsa_verify (
973 : TALER_SIGNATURE_WALLET_PURSE_DEPOSIT,
974 : &pm,
975 : &coin_sig->eddsa_signature,
976 : &coin_pub->eddsa_pub);
977 : }
978 :
979 :
980 : /**
981 : * Message signed to merge a purse into a reserve.
982 : */
983 : struct TALER_PurseMergePS
984 : {
985 :
986 : /**
987 : * Purpose is #TALER_SIGNATURE_WALLET_PURSE_MERGE
988 : */
989 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
990 :
991 : /**
992 : * Time when the purse is merged into the reserve.
993 : */
994 : struct GNUNET_TIME_TimestampNBO merge_timestamp;
995 :
996 : /**
997 : * Which purse is being merged?
998 : */
999 : struct TALER_PurseContractPublicKeyP purse_pub;
1000 :
1001 : /**
1002 : * Which reserve should the purse be merged with.
1003 : * Hash of the reserve's payto:// URI.
1004 : */
1005 : struct TALER_PaytoHashP h_payto;
1006 :
1007 : };
1008 :
1009 :
1010 : void
1011 0 : TALER_wallet_purse_merge_sign (
1012 : const char *reserve_uri,
1013 : struct GNUNET_TIME_Timestamp merge_timestamp,
1014 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1015 : const struct TALER_PurseMergePrivateKeyP *merge_priv,
1016 : struct TALER_PurseMergeSignatureP *merge_sig)
1017 : {
1018 0 : struct TALER_PurseMergePS pm = {
1019 0 : .purpose.size = htonl (sizeof (pm)),
1020 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_MERGE),
1021 0 : .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
1022 : .purse_pub = *purse_pub
1023 : };
1024 :
1025 0 : GNUNET_assert (0 ==
1026 : strncasecmp (reserve_uri,
1027 : "payto://taler-reserve",
1028 : strlen ("payto://taler-reserve")));
1029 0 : TALER_payto_hash (reserve_uri,
1030 : &pm.h_payto);
1031 0 : GNUNET_CRYPTO_eddsa_sign (&merge_priv->eddsa_priv,
1032 : &pm,
1033 : &merge_sig->eddsa_signature);
1034 0 : }
1035 :
1036 :
1037 : enum GNUNET_GenericReturnValue
1038 0 : TALER_wallet_purse_merge_verify (
1039 : const char *reserve_uri,
1040 : struct GNUNET_TIME_Timestamp merge_timestamp,
1041 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1042 : const struct TALER_PurseMergePublicKeyP *merge_pub,
1043 : const struct TALER_PurseMergeSignatureP *merge_sig)
1044 : {
1045 0 : struct TALER_PurseMergePS pm = {
1046 0 : .purpose.size = htonl (sizeof (pm)),
1047 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_MERGE),
1048 0 : .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
1049 : .purse_pub = *purse_pub
1050 : };
1051 :
1052 0 : if (0 !=
1053 0 : strncasecmp (reserve_uri,
1054 : "payto://taler-reserve",
1055 : strlen ("payto://taler-reserve")))
1056 : {
1057 0 : GNUNET_break (0);
1058 0 : return GNUNET_NO;
1059 : }
1060 0 : TALER_payto_hash (reserve_uri,
1061 : &pm.h_payto);
1062 0 : return GNUNET_CRYPTO_eddsa_verify (
1063 : TALER_SIGNATURE_WALLET_PURSE_MERGE,
1064 : &pm,
1065 : &merge_sig->eddsa_signature,
1066 : &merge_pub->eddsa_pub);
1067 : }
1068 :
1069 :
1070 : /**
1071 : * Message signed by account to merge a purse into a reserve.
1072 : */
1073 : struct TALER_AccountMergePS
1074 : {
1075 :
1076 : /**
1077 : * Purpose is #TALER_SIGNATURE_WALLET_ACCOUNT_MERGE
1078 : */
1079 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
1080 :
1081 : /**
1082 : * Time when the purse will expire if still unmerged or unpaid.
1083 : */
1084 : struct GNUNET_TIME_TimestampNBO purse_expiration;
1085 :
1086 : /**
1087 : * Total amount (with fees) to be put into the purse.
1088 : */
1089 : struct TALER_AmountNBO purse_amount;
1090 :
1091 : /**
1092 : * Purse creation fee to be paid by the reserve for
1093 : * this operation.
1094 : */
1095 : struct TALER_AmountNBO purse_fee;
1096 :
1097 : /**
1098 : * Contract this purse pays for.
1099 : */
1100 : struct TALER_PrivateContractHashP h_contract_terms;
1101 :
1102 : /**
1103 : * Purse to merge.
1104 : */
1105 : struct TALER_PurseContractPublicKeyP purse_pub;
1106 :
1107 : /**
1108 : * Time when the purse is merged into the reserve.
1109 : */
1110 : struct GNUNET_TIME_TimestampNBO merge_timestamp;
1111 :
1112 : /**
1113 : * Minimum age required for payments into this purse,
1114 : * in NBO.
1115 : */
1116 : uint32_t min_age GNUNET_PACKED;
1117 :
1118 : /**
1119 : * Flags for the operation, in NBO. See
1120 : * `enum TALER_WalletAccountMergeFlags`.
1121 : */
1122 : uint32_t flags GNUNET_PACKED;
1123 : };
1124 :
1125 :
1126 : void
1127 0 : TALER_wallet_account_merge_sign (
1128 : struct GNUNET_TIME_Timestamp merge_timestamp,
1129 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1130 : struct GNUNET_TIME_Timestamp purse_expiration,
1131 : const struct TALER_PrivateContractHashP *h_contract_terms,
1132 : const struct TALER_Amount *amount,
1133 : const struct TALER_Amount *purse_fee,
1134 : uint32_t min_age,
1135 : enum TALER_WalletAccountMergeFlags flags,
1136 : const struct TALER_ReservePrivateKeyP *reserve_priv,
1137 : struct TALER_ReserveSignatureP *reserve_sig)
1138 : {
1139 0 : struct TALER_AccountMergePS pm = {
1140 0 : .purpose.size = htonl (sizeof (pm)),
1141 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_MERGE),
1142 0 : .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
1143 : .purse_pub = *purse_pub,
1144 0 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1145 : .h_contract_terms = *h_contract_terms,
1146 0 : .min_age = htonl (min_age),
1147 0 : .flags = htonl ((uint32_t) flags)
1148 : };
1149 :
1150 0 : TALER_amount_hton (&pm.purse_amount,
1151 : amount);
1152 0 : TALER_amount_hton (&pm.purse_fee,
1153 : purse_fee);
1154 0 : GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
1155 : &pm,
1156 : &reserve_sig->eddsa_signature);
1157 0 : }
1158 :
1159 :
1160 : enum GNUNET_GenericReturnValue
1161 0 : TALER_wallet_account_merge_verify (
1162 : struct GNUNET_TIME_Timestamp merge_timestamp,
1163 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1164 : struct GNUNET_TIME_Timestamp purse_expiration,
1165 : const struct TALER_PrivateContractHashP *h_contract_terms,
1166 : const struct TALER_Amount *amount,
1167 : const struct TALER_Amount *purse_fee,
1168 : uint32_t min_age,
1169 : enum TALER_WalletAccountMergeFlags flags,
1170 : const struct TALER_ReservePublicKeyP *reserve_pub,
1171 : const struct TALER_ReserveSignatureP *reserve_sig)
1172 : {
1173 0 : struct TALER_AccountMergePS pm = {
1174 0 : .purpose.size = htonl (sizeof (pm)),
1175 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_MERGE),
1176 0 : .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
1177 : .purse_pub = *purse_pub,
1178 0 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1179 : .h_contract_terms = *h_contract_terms,
1180 0 : .min_age = htonl (min_age),
1181 0 : .flags = htonl ((uint32_t) flags)
1182 : };
1183 :
1184 0 : TALER_amount_hton (&pm.purse_amount,
1185 : amount);
1186 0 : TALER_amount_hton (&pm.purse_fee,
1187 : purse_fee);
1188 0 : return GNUNET_CRYPTO_eddsa_verify (
1189 : TALER_SIGNATURE_WALLET_ACCOUNT_MERGE,
1190 : &pm,
1191 : &reserve_sig->eddsa_signature,
1192 : &reserve_pub->eddsa_pub);
1193 : }
1194 :
1195 :
1196 : void
1197 0 : TALER_wallet_account_close_sign (
1198 : const struct TALER_ReservePrivateKeyP *reserve_priv,
1199 : struct TALER_ReserveSignatureP *reserve_sig)
1200 : {
1201 0 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
1202 0 : .size = htonl (sizeof (purpose)),
1203 0 : .purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE)
1204 : };
1205 :
1206 0 : GNUNET_assert (GNUNET_OK ==
1207 : GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
1208 : &purpose,
1209 : &reserve_sig->eddsa_signature));
1210 0 : }
1211 :
1212 :
1213 : enum GNUNET_GenericReturnValue
1214 0 : TALER_wallet_account_close_verify (
1215 : const struct TALER_ReservePublicKeyP *reserve_pub,
1216 : const struct TALER_ReserveSignatureP *reserve_sig)
1217 : {
1218 0 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
1219 0 : .size = htonl (sizeof (purpose)),
1220 0 : .purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE)
1221 : };
1222 :
1223 0 : return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_RESERVE_CLOSE,
1224 : &purpose,
1225 : &reserve_sig->eddsa_signature,
1226 : &reserve_pub->eddsa_pub);
1227 : }
1228 :
1229 :
1230 : /**
1231 : * Message signed by purse to associate an encrypted contract.
1232 : */
1233 : struct TALER_PurseContractPS
1234 : {
1235 :
1236 : /**
1237 : * Purpose is #TALER_SIGNATURE_WALLET_PURSE_ECONTRACT
1238 : */
1239 : struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
1240 :
1241 : /**
1242 : * Hash over the encrypted contract.
1243 : */
1244 : struct GNUNET_HashCode h_econtract;
1245 :
1246 : /**
1247 : * Public key to decrypt the contract.
1248 : */
1249 : struct TALER_ContractDiffiePublicP contract_pub;
1250 : };
1251 :
1252 :
1253 : void
1254 0 : TALER_wallet_econtract_upload_sign (
1255 : const void *econtract,
1256 : size_t econtract_size,
1257 : const struct TALER_ContractDiffiePublicP *contract_pub,
1258 : const struct TALER_PurseContractPrivateKeyP *purse_priv,
1259 : struct TALER_PurseContractSignatureP *purse_sig)
1260 : {
1261 0 : struct TALER_PurseContractPS pc = {
1262 0 : .purpose.size = htonl (sizeof (pc)),
1263 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT),
1264 : .contract_pub = *contract_pub
1265 : };
1266 :
1267 0 : GNUNET_CRYPTO_hash (econtract,
1268 : econtract_size,
1269 : &pc.h_econtract);
1270 0 : GNUNET_assert (GNUNET_OK ==
1271 : GNUNET_CRYPTO_eddsa_sign_ (&purse_priv->eddsa_priv,
1272 : &pc.purpose,
1273 : &purse_sig->eddsa_signature));
1274 0 : }
1275 :
1276 :
1277 : enum GNUNET_GenericReturnValue
1278 0 : TALER_wallet_econtract_upload_verify2 (
1279 : const struct GNUNET_HashCode *h_econtract,
1280 : const struct TALER_ContractDiffiePublicP *contract_pub,
1281 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1282 : const struct TALER_PurseContractSignatureP *purse_sig)
1283 : {
1284 0 : struct TALER_PurseContractPS pc = {
1285 0 : .purpose.size = htonl (sizeof (pc)),
1286 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT),
1287 : .contract_pub = *contract_pub,
1288 : .h_econtract = *h_econtract
1289 : };
1290 :
1291 0 : return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT,
1292 : &pc.purpose,
1293 : &purse_sig->eddsa_signature,
1294 : &purse_pub->eddsa_pub);
1295 : }
1296 :
1297 :
1298 : enum GNUNET_GenericReturnValue
1299 0 : TALER_wallet_econtract_upload_verify (
1300 : const void *econtract,
1301 : size_t econtract_size,
1302 : const struct TALER_ContractDiffiePublicP *contract_pub,
1303 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1304 : const struct TALER_PurseContractSignatureP *purse_sig)
1305 : {
1306 : struct GNUNET_HashCode h_econtract;
1307 :
1308 0 : GNUNET_CRYPTO_hash (econtract,
1309 : econtract_size,
1310 : &h_econtract);
1311 0 : return TALER_wallet_econtract_upload_verify2 (&h_econtract,
1312 : contract_pub,
1313 : purse_pub,
1314 : purse_sig);
1315 : }
1316 :
1317 :
1318 : /* end of wallet_signatures.c */
|