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 json/json_pack.c
18 : * @brief helper functions for JSON object packing
19 : * @author Christian Grothoff
20 : * @author Özgür Kesim
21 : */
22 : #include "taler/platform.h"
23 : #include <gnunet/gnunet_util_lib.h>
24 : #include "taler/taler_util.h"
25 : #include "taler/taler_json_lib.h"
26 :
27 :
28 : struct GNUNET_JSON_PackSpec
29 0 : TALER_JSON_pack_time_abs_human (const char *name,
30 : struct GNUNET_TIME_Absolute at)
31 : {
32 0 : struct GNUNET_JSON_PackSpec ps = {
33 : .field_name = name,
34 0 : .object = json_string (
35 : GNUNET_STRINGS_absolute_time_to_string (at))
36 : };
37 :
38 0 : return ps;
39 : }
40 :
41 :
42 : struct GNUNET_JSON_PackSpec
43 25 : TALER_JSON_pack_econtract (
44 : const char *name,
45 : const struct TALER_EncryptedContract *econtract)
46 : {
47 25 : struct GNUNET_JSON_PackSpec ps = {
48 : .field_name = name,
49 : };
50 :
51 25 : if (NULL == econtract)
52 0 : return ps;
53 : ps.object
54 25 : = GNUNET_JSON_PACK (
55 : GNUNET_JSON_pack_data_varsize ("econtract",
56 : econtract->econtract,
57 : econtract->econtract_size),
58 : GNUNET_JSON_pack_data_auto ("econtract_sig",
59 : &econtract->econtract_sig),
60 : GNUNET_JSON_pack_data_auto ("contract_pub",
61 : &econtract->contract_pub));
62 25 : return ps;
63 : }
64 :
65 :
66 : struct GNUNET_JSON_PackSpec
67 8 : TALER_JSON_pack_age_commitment (
68 : const char *name,
69 : const struct TALER_AgeCommitment *age_commitment)
70 : {
71 8 : struct GNUNET_JSON_PackSpec ps = {
72 : .field_name = name,
73 : };
74 : json_t *keys;
75 :
76 8 : if (NULL == age_commitment ||
77 8 : 0 == age_commitment->num)
78 0 : return ps;
79 :
80 8 : GNUNET_assert (NULL !=
81 : (keys = json_array ()));
82 :
83 8 : for (size_t i = 0;
84 64 : i < age_commitment->num;
85 56 : i++)
86 : {
87 : json_t *val;
88 56 : val = GNUNET_JSON_from_data (&age_commitment->pubs[i],
89 : sizeof(age_commitment->pubs[i]));
90 56 : GNUNET_assert (NULL != val);
91 56 : GNUNET_assert (0 ==
92 : json_array_append_new (keys, val));
93 : }
94 :
95 8 : ps.object = keys;
96 8 : return ps;
97 : }
98 :
99 :
100 : struct GNUNET_JSON_PackSpec
101 88 : TALER_JSON_pack_kycte (const char *name,
102 : enum TALER_KYCLOGIC_KycTriggerEvent event)
103 : {
104 88 : const char *str = "INVALID";
105 :
106 88 : switch (event)
107 : {
108 0 : case TALER_KYCLOGIC_KYC_TRIGGER_NONE:
109 0 : str = "NONE";
110 0 : break;
111 12 : case TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW:
112 12 : str = "WITHDRAW";
113 12 : break;
114 2 : case TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT:
115 2 : str = "DEPOSIT";
116 2 : break;
117 8 : case TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE:
118 8 : str = "MERGE";
119 8 : break;
120 10 : case TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE:
121 10 : str = "BALANCE";
122 10 : break;
123 47 : case TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE:
124 47 : str = "CLOSE";
125 47 : break;
126 9 : case TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE:
127 9 : str = "AGGREGATE";
128 9 : break;
129 0 : case TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION:
130 0 : str = "TRANSACTION";
131 0 : break;
132 0 : case TALER_KYCLOGIC_KYC_TRIGGER_REFUND:
133 0 : str = "REFUND";
134 0 : break;
135 : }
136 88 : return GNUNET_JSON_pack_string (name,
137 : str);
138 : }
139 :
140 :
141 : struct GNUNET_JSON_PackSpec
142 5382 : TALER_JSON_pack_denom_pub (
143 : const char *name,
144 : const struct TALER_DenominationPublicKey *pk)
145 : {
146 : const struct GNUNET_CRYPTO_BlindSignPublicKey *bsp;
147 5382 : struct GNUNET_JSON_PackSpec ps = {
148 : .field_name = name,
149 : };
150 :
151 5382 : if (NULL == pk)
152 0 : return ps;
153 5382 : bsp = pk->bsign_pub_key;
154 5382 : switch (bsp->cipher)
155 : {
156 0 : case GNUNET_CRYPTO_BSA_INVALID:
157 0 : break;
158 2712 : case GNUNET_CRYPTO_BSA_RSA:
159 : ps.object
160 2712 : = GNUNET_JSON_PACK (
161 : GNUNET_JSON_pack_string ("cipher",
162 : "RSA"),
163 : GNUNET_JSON_pack_uint64 ("age_mask",
164 : pk->age_mask.bits),
165 : GNUNET_JSON_pack_rsa_public_key ("rsa_pub",
166 : bsp->details.rsa_public_key));
167 5382 : return ps;
168 2670 : case GNUNET_CRYPTO_BSA_CS:
169 : ps.object
170 2670 : = GNUNET_JSON_PACK (
171 : GNUNET_JSON_pack_string ("cipher",
172 : "CS"),
173 : GNUNET_JSON_pack_uint64 ("age_mask",
174 : pk->age_mask.bits),
175 : GNUNET_JSON_pack_data_varsize ("cs_pub",
176 : &bsp->details.cs_public_key,
177 : sizeof (bsp->details.cs_public_key)));
178 2670 : return ps;
179 : }
180 0 : GNUNET_assert (0);
181 : return ps;
182 : }
183 :
184 :
185 : struct GNUNET_JSON_PackSpec
186 0 : TALER_JSON_pack_token_pub (
187 : const char *name,
188 : const struct TALER_TokenIssuePublicKey *pk)
189 : {
190 : const struct GNUNET_CRYPTO_BlindSignPublicKey *bsp;
191 0 : struct GNUNET_JSON_PackSpec ps = {
192 : .field_name = name,
193 : };
194 :
195 0 : if (NULL == pk)
196 0 : return ps;
197 0 : bsp = pk->public_key;
198 0 : switch (bsp->cipher)
199 : {
200 0 : case GNUNET_CRYPTO_BSA_INVALID:
201 0 : break;
202 0 : case GNUNET_CRYPTO_BSA_RSA:
203 : ps.object
204 0 : = GNUNET_JSON_PACK (
205 : GNUNET_JSON_pack_string ("cipher",
206 : "RSA"),
207 : GNUNET_JSON_pack_rsa_public_key ("rsa_pub",
208 : bsp->details.rsa_public_key));
209 0 : return ps;
210 0 : case GNUNET_CRYPTO_BSA_CS:
211 : ps.object
212 0 : = GNUNET_JSON_PACK (
213 : GNUNET_JSON_pack_string ("cipher",
214 : "CS"),
215 : GNUNET_JSON_pack_data_varsize ("cs_pub",
216 : &bsp->details.cs_public_key,
217 : sizeof (bsp->details.cs_public_key)));
218 0 : return ps;
219 : }
220 0 : GNUNET_assert (0);
221 : return ps;
222 : }
223 :
224 :
225 : struct GNUNET_JSON_PackSpec
226 152 : TALER_JSON_pack_denom_sig (
227 : const char *name,
228 : const struct TALER_DenominationSignature *sig)
229 : {
230 152 : struct GNUNET_JSON_PackSpec ps = {
231 : .field_name = name,
232 : };
233 152 : if (NULL == sig)
234 0 : return ps;
235 152 : return GNUNET_JSON_pack_unblinded_signature (name,
236 152 : sig->unblinded_sig);
237 : }
238 :
239 :
240 : struct GNUNET_JSON_PackSpec
241 0 : TALER_JSON_pack_token_issue_sig (
242 : const char *name,
243 : const struct TALER_TokenIssueSignature *sig)
244 : {
245 0 : struct GNUNET_JSON_PackSpec ps = {
246 : .field_name = name,
247 : };
248 0 : if (NULL == sig)
249 0 : return ps;
250 0 : return GNUNET_JSON_pack_unblinded_signature (name,
251 0 : sig->signature);
252 : }
253 :
254 :
255 : struct GNUNET_JSON_PackSpec
256 0 : TALER_JSON_pack_token_envelope (
257 : const char *name,
258 : const struct TALER_TokenEnvelope *envelope)
259 : {
260 0 : struct GNUNET_JSON_PackSpec ps = {
261 : .field_name = name,
262 : };
263 :
264 0 : if (NULL == envelope)
265 0 : return ps;
266 0 : return GNUNET_JSON_pack_blinded_message (name,
267 0 : envelope->blinded_pub);
268 : }
269 :
270 :
271 : struct GNUNET_JSON_PackSpec
272 0 : TALER_JSON_pack_exchange_blinding_values (
273 : const char *name,
274 : const struct TALER_ExchangeBlindingValues *ewv)
275 : {
276 : const struct GNUNET_CRYPTO_BlindingInputValues *biv;
277 0 : struct GNUNET_JSON_PackSpec ps = {
278 : .field_name = name,
279 : };
280 :
281 0 : if (NULL == ewv)
282 0 : return ps;
283 0 : biv = ewv->blinding_inputs;
284 0 : switch (biv->cipher)
285 : {
286 0 : case GNUNET_CRYPTO_BSA_INVALID:
287 0 : break;
288 0 : case GNUNET_CRYPTO_BSA_RSA:
289 0 : ps.object = GNUNET_JSON_PACK (
290 : GNUNET_JSON_pack_string ("cipher",
291 : "RSA"));
292 0 : return ps;
293 0 : case GNUNET_CRYPTO_BSA_CS:
294 0 : ps.object = GNUNET_JSON_PACK (
295 : GNUNET_JSON_pack_string ("cipher",
296 : "CS"),
297 : GNUNET_JSON_pack_data_varsize (
298 : "r_pub_0",
299 : &biv->details.cs_values.r_pub[0],
300 : sizeof(struct GNUNET_CRYPTO_CsRPublic)),
301 : GNUNET_JSON_pack_data_varsize (
302 : "r_pub_1",
303 : &biv->details.cs_values.r_pub[1],
304 : sizeof(struct GNUNET_CRYPTO_CsRPublic))
305 : );
306 0 : return ps;
307 : }
308 0 : GNUNET_assert (0);
309 : return ps;
310 : }
311 :
312 :
313 : struct GNUNET_JSON_PackSpec
314 50 : TALER_JSON_pack_blinding_prepare_response (
315 : const char *name,
316 : const struct TALER_BlindingPrepareResponse *bpr)
317 : {
318 50 : struct GNUNET_JSON_PackSpec ps = {
319 : .field_name = name,
320 : };
321 50 : if (NULL == bpr)
322 0 : return ps;
323 50 : switch (bpr->cipher)
324 : {
325 0 : case GNUNET_CRYPTO_BSA_INVALID:
326 0 : break;
327 0 : case GNUNET_CRYPTO_BSA_RSA:
328 0 : ps.object = GNUNET_JSON_PACK (
329 : GNUNET_JSON_pack_string ("cipher",
330 : "RSA"));
331 50 : return ps;
332 50 : case GNUNET_CRYPTO_BSA_CS: {
333 50 : json_t *j_rpubs = json_array ();
334 :
335 50 : GNUNET_assert (NULL!=j_rpubs);
336 :
337 148 : for (size_t i = 0; i < bpr->num; i++)
338 : {
339 98 : struct GNUNET_CRYPTO_CSPublicRPairP *pair =
340 98 : &bpr->details.cs[i];
341 : json_t *j_pubs[2];
342 : json_t *j_pair;
343 :
344 98 : j_pair = json_array ();
345 98 : GNUNET_assert (NULL != j_pair);
346 :
347 196 : j_pubs[0] = GNUNET_JSON_from_data (
348 98 : &pair->r_pub[0],
349 : sizeof(pair->r_pub[0]));
350 98 : GNUNET_assert (NULL != j_pubs[0]);
351 :
352 196 : j_pubs[1] = GNUNET_JSON_from_data (
353 98 : &pair->r_pub[1],
354 : sizeof(pair->r_pub[1]));
355 98 : GNUNET_assert (NULL != j_pubs[1]);
356 :
357 98 : GNUNET_assert (0 == json_array_append_new (j_pair, j_pubs[0]));
358 98 : GNUNET_assert (0 == json_array_append_new (j_pair, j_pubs[1]));
359 98 : GNUNET_assert (0 == json_array_append_new (j_rpubs, j_pair));
360 : }
361 :
362 50 : ps.object = GNUNET_JSON_PACK (
363 : GNUNET_JSON_pack_string ("cipher", "CS"),
364 : GNUNET_JSON_pack_array_steal ("r_pubs", j_rpubs));
365 50 : return ps;
366 : }
367 : }
368 0 : GNUNET_assert (0);
369 : return ps;
370 : }
371 :
372 :
373 : struct GNUNET_JSON_PackSpec
374 126 : TALER_JSON_pack_blinded_denom_sig (
375 : const char *name,
376 : const struct TALER_BlindedDenominationSignature *sig)
377 : {
378 : const struct GNUNET_CRYPTO_BlindedSignature *bs;
379 126 : struct GNUNET_JSON_PackSpec ps = {
380 : .field_name = name,
381 : };
382 :
383 126 : if (NULL == sig)
384 0 : return ps;
385 126 : bs = sig->blinded_sig;
386 126 : switch (bs->cipher)
387 : {
388 0 : case GNUNET_CRYPTO_BSA_INVALID:
389 0 : break;
390 65 : case GNUNET_CRYPTO_BSA_RSA:
391 65 : ps.object = GNUNET_JSON_PACK (
392 : GNUNET_JSON_pack_string ("cipher",
393 : "RSA"),
394 : GNUNET_JSON_pack_rsa_signature ("blinded_rsa_signature",
395 : bs->details.blinded_rsa_signature));
396 126 : return ps;
397 61 : case GNUNET_CRYPTO_BSA_CS:
398 61 : ps.object = GNUNET_JSON_PACK (
399 : GNUNET_JSON_pack_string ("cipher",
400 : "CS"),
401 : GNUNET_JSON_pack_uint64 ("b",
402 : bs->details.blinded_cs_answer.b),
403 : GNUNET_JSON_pack_data_auto ("s",
404 : &bs->details.blinded_cs_answer.s_scalar));
405 61 : return ps;
406 : }
407 0 : GNUNET_assert (0);
408 : return ps;
409 : }
410 :
411 :
412 : struct GNUNET_JSON_PackSpec
413 459 : TALER_JSON_pack_blinded_planchet (
414 : const char *name,
415 : const struct TALER_BlindedPlanchet *blinded_planchet)
416 : {
417 459 : struct GNUNET_JSON_PackSpec ps = {
418 : .field_name = name,
419 : };
420 :
421 459 : if (NULL == blinded_planchet)
422 0 : return ps;
423 459 : return GNUNET_JSON_pack_blinded_message (name,
424 459 : blinded_planchet->blinded_message);
425 : }
426 :
427 :
428 : struct GNUNET_JSON_PackSpec
429 31166 : TALER_JSON_pack_amount (const char *name,
430 : const struct TALER_Amount *amount)
431 : {
432 62332 : struct GNUNET_JSON_PackSpec ps = {
433 : .field_name = name,
434 : .object = (NULL != amount)
435 31149 : ? TALER_JSON_from_amount (amount)
436 31166 : : NULL
437 : };
438 :
439 31166 : return ps;
440 : }
441 :
442 :
443 : struct GNUNET_JSON_PackSpec
444 1 : TALER_JSON_pack_amount_array (const char *name,
445 : size_t len,
446 : const struct TALER_Amount *amounts)
447 : {
448 1 : struct GNUNET_JSON_PackSpec ps = {
449 : .field_name = name,
450 : };
451 :
452 1 : if (NULL == amounts)
453 : {
454 0 : ps.object = json_null ();
455 0 : return ps;
456 : }
457 : {
458 1 : json_t *array = json_array ();
459 :
460 1 : GNUNET_assert (NULL != array);
461 3 : for (size_t i = 0; i<len; i++)
462 : {
463 : json_t *entry;
464 :
465 2 : char *amount_str = TALER_amount_to_string (&amounts[i]);
466 2 : GNUNET_assert (NULL != amount_str);
467 :
468 2 : entry = json_string (amount_str);
469 :
470 2 : GNUNET_free (amount_str);
471 2 : GNUNET_assert (NULL != entry);
472 2 : GNUNET_assert (0 ==
473 : json_array_append_new (array,
474 : entry));
475 : }
476 1 : ps.object = array;
477 : }
478 1 : return ps;
479 : }
480 :
481 :
482 : struct GNUNET_JSON_PackSpec
483 353 : TALER_JSON_pack_full_payto (
484 : const char *name,
485 : const struct TALER_FullPayto payto)
486 : {
487 706 : return GNUNET_JSON_pack_string (name,
488 353 : payto.full_payto);
489 : }
490 :
491 :
492 : struct GNUNET_JSON_PackSpec
493 6 : TALER_JSON_pack_normalized_payto (
494 : const char *name,
495 : const struct TALER_NormalizedPayto payto)
496 : {
497 12 : return GNUNET_JSON_pack_string (name,
498 6 : payto.normalized_payto);
499 : }
500 :
501 :
502 : struct GNUNET_JSON_PackSpec
503 0 : TALER_JSON_pack_tuple (
504 : const char *name,
505 : const struct GNUNET_JSON_PackSpec packers[])
506 : {
507 : static size_t max_packers = 256;
508 0 : struct GNUNET_JSON_PackSpec ps = {
509 : .field_name = name,
510 : };
511 : size_t idx;
512 0 : json_t *j_array = json_array ();
513 :
514 0 : GNUNET_assert (NULL!=j_array);
515 :
516 0 : for (idx = 0; idx < max_packers; idx++)
517 : {
518 0 : if (NULL == packers[idx].object)
519 0 : break;
520 :
521 0 : GNUNET_assert (0 ==
522 : json_array_append_new (j_array,
523 : packers[idx].object));
524 : }
525 :
526 0 : GNUNET_assert (idx != max_packers);
527 :
528 0 : ps.object = j_array;
529 0 : return ps;
530 :
531 : }
532 :
533 :
534 : struct GNUNET_JSON_PackSpec
535 130 : TALER_JSON_pack_array_of_data (
536 : const char *name,
537 : size_t num,
538 : const void *data,
539 : size_t size)
540 : {
541 130 : const char *blob = data;
542 130 : struct GNUNET_JSON_PackSpec ps = {
543 : .field_name = name,
544 : };
545 130 : json_t *j_array = json_array ();
546 :
547 130 : GNUNET_assert (NULL!=j_array);
548 130 : if (0 == num)
549 : {
550 3 : ps.object = j_array;
551 3 : return ps;
552 : }
553 127 : GNUNET_assert ((0 == size) ||
554 : (num == 1) ||
555 : (num * size > size));
556 :
557 616 : for (size_t idx = 0; idx < num; idx++)
558 : {
559 489 : GNUNET_assert (0 ==
560 : json_array_append_new (
561 : j_array,
562 : GNUNET_JSON_from_data (
563 : blob,
564 : size)));
565 489 : blob += size;
566 : }
567 :
568 127 : ps.object = j_array;
569 127 : return ps;
570 : }
571 :
572 :
573 : /* End of json/json_pack.c */
|