aboutsummaryrefslogtreecommitdiff
path: root/src/mint/taler-mint-httpd_refresh.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mint/taler-mint-httpd_refresh.c')
-rw-r--r--src/mint/taler-mint-httpd_refresh.c381
1 files changed, 164 insertions, 217 deletions
diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c
index cfb3ba0f5..d7b670749 100644
--- a/src/mint/taler-mint-httpd_refresh.c
+++ b/src/mint/taler-mint-httpd_refresh.c
@@ -151,6 +151,15 @@ request_json_check_signature (struct MHD_Connection *connection,
151 * @param coin_public_infos array with @a coin_count entries about the coins 151 * @param coin_public_infos array with @a coin_count entries about the coins
152 * @param coin_melt_details array with @a coin_count entries with melting details 152 * @param coin_melt_details array with @a coin_count entries with melting details
153 * @param melt_sig_json signature affirming the overall melt operation 153 * @param melt_sig_json signature affirming the overall melt operation
154 * @param commit_client_sig signature of the client over this commitment
155 * @param kappa size of x-dimension of @commit_coin and @commit_link arrays
156 * @param num_oldcoins size of y-dimension of @commit_coin array
157 * @param num_newcoins size of y-dimension of @commit_link array
158 * @param commit_coin 2d array of coin commitments (what the mint is to sign
159 * once the "/refres/reveal" of cut and choose is done)
160 * @param commit_link 2d array of coin link commitments (what the mint is
161 * to return via "/refresh/link" to enable linkage in the
162 * future)
154 * @return MHD result code 163 * @return MHD result code
155 */ 164 */
156static int 165static int
@@ -161,7 +170,14 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
161 unsigned int coin_count, 170 unsigned int coin_count,
162 struct TALER_CoinPublicInfo *coin_public_infos, 171 struct TALER_CoinPublicInfo *coin_public_infos,
163 const struct MeltDetails *coin_melt_details, 172 const struct MeltDetails *coin_melt_details,
164 const json_t *melt_sig_json) 173 const json_t *melt_sig_json,
174 const struct GNUNET_CRYPTO_EddsaSignature *commit_client_sig,
175 unsigned int kappa,
176 unsigned int num_oldcoins,
177 unsigned int num_newcoins,
178 struct RefreshCommitCoin *const* commit_coin,
179 struct RefreshCommitLink *const* commit_link)
180
165{ 181{
166 int res; 182 int res;
167 unsigned int i; 183 unsigned int i;
@@ -256,7 +272,13 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
256 denom_pubs, 272 denom_pubs,
257 coin_count, 273 coin_count,
258 coin_public_infos, 274 coin_public_infos,
259 coin_melt_details); 275 coin_melt_details,
276 NULL /* FIXME: 3635! */,
277 kappa,
278 num_oldcoins,
279 num_newcoins,
280 commit_coin,
281 commit_link);
260} 282}
261 283
262 284
@@ -364,6 +386,58 @@ get_and_verify_coin_public_info (struct MHD_Connection *connection,
364 386
365 387
366/** 388/**
389 * Release memory from the @a commit_coin array.
390 *
391 * @param commit_coin array to release
392 * @param kappa size of 1st dimension
393 * @param num_new_coins size of 2nd dimension
394 */
395static void
396free_commit_coins (struct RefreshCommitCoin **commit_coin,
397 unsigned int kappa,
398 unsigned int num_new_coins)
399{
400 unsigned int i;
401 unsigned int j;
402
403 for (i=0;i<kappa;i++)
404 {
405 if (NULL == commit_coin[i])
406 break;
407 for (j=0;j<num_new_coins;j++)
408 {
409 GNUNET_free_non_null (commit_coin[i][j].coin_ev);
410 GNUNET_free_non_null (commit_coin[i][j].refresh_link);
411 }
412 GNUNET_free (commit_coin[i]);
413 }
414}
415
416
417/**
418 * Release memory from the @a commit_link array.
419 *
420 * @param commit_coin array to release
421 * @param kappa size of 1st dimension
422 * @param num_old_coins size of 2nd dimension
423 */
424static void
425free_commit_links (struct RefreshCommitLink **commit_link,
426 unsigned int kappa,
427 unsigned int num_old_coins)
428{
429 unsigned int i;
430
431 for (i=0;i<kappa;i++)
432 {
433 if (NULL == commit_link[i])
434 break;
435 GNUNET_free (commit_link[i]);
436 }
437}
438
439
440/**
367 * Handle a "/refresh/melt" request after the first parsing has happened. 441 * Handle a "/refresh/melt" request after the first parsing has happened.
368 * We now need to validate the coins being melted and the session signature 442 * We now need to validate the coins being melted and the session signature
369 * and then hand things of to execute the melt operation. This function 443 * and then hand things of to execute the melt operation. This function
@@ -375,6 +449,14 @@ get_and_verify_coin_public_info (struct MHD_Connection *connection,
375 * @param new_denoms array of denomination keys 449 * @param new_denoms array of denomination keys
376 * @param melt_coins array of coins to melt 450 * @param melt_coins array of coins to melt
377 * @param melt_sig_json signature affirming the melt operation 451 * @param melt_sig_json signature affirming the melt operation
452 * @param commit_signature signature over the commit
453 * @param kappa security parameter for cut and choose
454 * @param num_oldcoins number of coins that are being melted
455 * @param transfer_pubs @a kappa-dimensional array of @a num_oldcoins transfer keys
456 * @param secret_encs @a kappa-dimensional array of @a num_oldcoins secrets
457 * @param num_newcoins number of coins that the refresh will generate
458 * @param coin_envs @a kappa-dimensional array of @a num_newcoins envelopes to sign
459 * @param link_encs @a kappa-dimensional array of @a num_newcoins encrypted links
378 * @return MHD result code 460 * @return MHD result code
379 */ 461 */
380static int 462static int
@@ -382,7 +464,16 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
382 const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub, 464 const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
383 const json_t *new_denoms, 465 const json_t *new_denoms,
384 const json_t *melt_coins, 466 const json_t *melt_coins,
385 const json_t *melt_sig_json) 467 const json_t *melt_sig_json,
468 const json_t *commit_signature,
469 unsigned int kappa,
470 unsigned int num_oldcoins,
471 const json_t *transfer_pubs,
472 const json_t *secret_encs,
473 unsigned int num_newcoins,
474 const json_t *coin_evs,
475 const json_t *link_encs)
476
386{ 477{
387 int res; 478 int res;
388 unsigned int i; 479 unsigned int i;
@@ -392,6 +483,11 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
392 struct TALER_CoinPublicInfo *coin_public_infos; 483 struct TALER_CoinPublicInfo *coin_public_infos;
393 struct MeltDetails *coin_melt_details; 484 struct MeltDetails *coin_melt_details;
394 unsigned int coin_count; 485 unsigned int coin_count;
486 struct GNUNET_HashCode commit_hash;
487 struct GNUNET_HashContext *hash_context;
488 struct RefreshCommitSignatureBody body;
489 struct RefreshCommitCoin *commit_coin[kappa];
490 struct RefreshCommitLink *commit_link[kappa];
395 491
396 num_new_denoms = json_array_size (new_denoms); 492 num_new_denoms = json_array_size (new_denoms);
397 denom_pubs = GNUNET_malloc (num_new_denoms * 493 denom_pubs = GNUNET_malloc (num_new_denoms *
@@ -441,180 +537,6 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
441 } 537 }
442 } 538 }
443 539
444 res = handle_refresh_melt_binary (connection,
445 refresh_session_pub,
446 num_new_denoms,
447 denom_pubs,
448 coin_count,
449 coin_public_infos,
450 coin_melt_details,
451 melt_sig_json);
452 for (j=0;j<coin_count;j++)
453 {
454 GNUNET_CRYPTO_rsa_public_key_free (coin_public_infos[j].denom_pub);
455 GNUNET_CRYPTO_rsa_signature_free (coin_public_infos[j].denom_sig);
456 }
457 GNUNET_free (coin_public_infos);
458 for (j=0;j<num_new_denoms;j++)
459 {
460 GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j]);
461 }
462 GNUNET_free (coin_melt_details);
463 GNUNET_free (denom_pubs);
464 return res;
465}
466
467
468/**
469 * Handle a "/refresh/melt" request. Parses the request into the JSON
470 * components and then hands things of to #handle_referesh_melt_json()
471 * to validate the melted coins, the signature and execute the melt
472 * using TALER_MINT_db_execute_refresh_melt().
473 *
474 * @param rh context of the handler
475 * @param connection the MHD connection to handle
476 * @param[IN|OUT] connection_cls the connection's closure (can be updated)
477 * @param upload_data upload data
478 * @param[IN|OUT] upload_data_size number of bytes (left) in @a upload_data
479 * @return MHD result code
480 */
481int
482TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
483 struct MHD_Connection *connection,
484 void **connection_cls,
485 const char *upload_data,
486 size_t *upload_data_size)
487{
488 json_t *root;
489 json_t *new_denoms;
490 json_t *melt_coins;
491 json_t *melt_sig_json;
492 struct GNUNET_CRYPTO_EddsaPublicKey refresh_session_pub;
493 int res;
494 struct GNUNET_MINT_ParseFieldSpec spec[] = {
495 TALER_MINT_PARSE_FIXED ("session_pub", &refresh_session_pub),
496 TALER_MINT_PARSE_ARRAY ("new_denoms", &new_denoms),
497 TALER_MINT_PARSE_ARRAY ("melt_coins", &melt_coins),
498 TALER_MINT_PARSE_ARRAY ("melt_signature", &melt_sig_json),
499 TALER_MINT_PARSE_END
500 };
501
502 res = TALER_MINT_parse_post_json (connection,
503 connection_cls,
504 upload_data,
505 upload_data_size,
506 &root);
507 if (GNUNET_SYSERR == res)
508 return MHD_NO;
509 if ( (GNUNET_NO == res) || (NULL == root) )
510 return MHD_YES;
511
512 res = TALER_MINT_parse_json_data (connection,
513 root,
514 spec);
515 json_decref (root);
516 if (GNUNET_OK != res)
517 return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
518 res = handle_refresh_melt_json (connection,
519 &refresh_session_pub,
520 new_denoms,
521 melt_coins,
522 melt_sig_json);
523 TALER_MINT_release_parsed_data (spec);
524 return res;
525}
526
527
528/**
529 * Release memory from the @a commit_coin array.
530 *
531 * @param commit_coin array to release
532 * @param kappa size of 1st dimension
533 * @param num_new_coins size of 2nd dimension
534 */
535static void
536free_commit_coins (struct RefreshCommitCoin **commit_coin,
537 unsigned int kappa,
538 unsigned int num_new_coins)
539{
540 unsigned int i;
541 unsigned int j;
542
543 for (i=0;i<kappa;i++)
544 {
545 if (NULL == commit_coin[i])
546 break;
547 for (j=0;j<num_new_coins;j++)
548 {
549 GNUNET_free_non_null (commit_coin[i][j].coin_ev);
550 GNUNET_free_non_null (commit_coin[i][j].refresh_link);
551 }
552 GNUNET_free (commit_coin[i]);
553 }
554}
555
556
557/**
558 * Release memory from the @a commit_link array.
559 *
560 * @param commit_coin array to release
561 * @param kappa size of 1st dimension
562 * @param num_old_coins size of 2nd dimension
563 */
564static void
565free_commit_links (struct RefreshCommitLink **commit_link,
566 unsigned int kappa,
567 unsigned int num_old_coins)
568{
569 unsigned int i;
570
571 for (i=0;i<kappa;i++)
572 {
573 if (NULL == commit_link[i])
574 break;
575 GNUNET_free (commit_link[i]);
576 }
577}
578
579
580
581/**
582 * Handle a "/refresh/commit" request. We have the individual JSON
583 * arrays, now we need to parse their contents and verify the
584 * commit signature. Then we can commit the data to the database.
585 *
586 * @param connection the MHD connection to handle
587 * @param refresh_session_pub public key of the refresh session
588 * @param commit_signature signature over the commit
589 * @param kappa security parameter for cut and choose
590 * @param num_oldcoins number of coins that are being melted
591 * @param transfer_pubs @a kappa-dimensional array of @a num_oldcoins transfer keys
592 * @param secret_encs @a kappa-dimensional array of @a num_oldcoins secrets
593 * @param num_newcoins number of coins that the refresh will generate
594 * @param coin_envs @a kappa-dimensional array of @a num_newcoins envelopes to sign
595 * @param link_encs @a kappa-dimensional array of @a num_newcoins encrypted links
596 * @return MHD result code
597 */
598static int
599handle_refresh_commit_json (struct MHD_Connection *connection,
600 const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
601 const json_t *commit_signature,
602 unsigned int kappa,
603 unsigned int num_oldcoins,
604 const json_t *transfer_pubs,
605 const json_t *secret_encs,
606 unsigned int num_newcoins,
607 const json_t *coin_evs,
608 const json_t *link_encs)
609{
610 struct GNUNET_HashCode commit_hash;
611 struct GNUNET_HashContext *hash_context;
612 struct RefreshCommitSignatureBody body;
613 struct RefreshCommitCoin *commit_coin[kappa];
614 struct RefreshCommitLink *commit_link[kappa];
615 unsigned int i;
616 unsigned int j;
617 int res;
618 540
619 /* parse JSON arrays into 2d binary arrays and hash everything 541 /* parse JSON arrays into 2d binary arrays and hash everything
620 together for the signature check */ 542 together for the signature check */
@@ -721,7 +643,7 @@ handle_refresh_commit_json (struct MHD_Connection *connection,
721 GNUNET_CRYPTO_hash_context_finish (hash_context, &commit_hash); 643 GNUNET_CRYPTO_hash_context_finish (hash_context, &commit_hash);
722 644
723 /* verify commit signature */ 645 /* verify commit signature */
724 body.purpose.purpose = htonl (TALER_SIGNATURE_REFRESH_COMMIT); 646 body.purpose.purpose = htonl (TALER_SIGNATURE_REFRESH_MELT);
725 body.purpose.size = htonl (sizeof (struct RefreshCommitSignatureBody)); 647 body.purpose.size = htonl (sizeof (struct RefreshCommitSignatureBody));
726 body.commit_hash = commit_hash; 648 body.commit_hash = commit_hash;
727 649
@@ -738,29 +660,43 @@ handle_refresh_commit_json (struct MHD_Connection *connection,
738 660
739 /* execute commit */ 661 /* execute commit */
740 /* FIXME: we must also store the signature! (#3635) */ 662 /* FIXME: we must also store the signature! (#3635) */
741 res = TALER_MINT_db_execute_refresh_commit (connection, 663 res = handle_refresh_melt_binary (connection,
742 refresh_session_pub, 664 refresh_session_pub,
743 NULL /* FIXME: 3635! */, 665 num_new_denoms,
744 kappa, 666 denom_pubs,
745 num_oldcoins, 667 coin_count,
746 num_newcoins, 668 coin_public_infos,
747 commit_coin, 669 coin_melt_details,
748 commit_link); 670 melt_sig_json,
671 NULL /* FIXME: 3635! */,
672 kappa,
673 num_oldcoins,
674 num_newcoins,
675 commit_coin,
676 commit_link);
749 free_commit_coins (commit_coin, kappa, num_newcoins); 677 free_commit_coins (commit_coin, kappa, num_newcoins);
750 free_commit_links (commit_link, kappa, num_oldcoins); 678 free_commit_links (commit_link, kappa, num_oldcoins);
751 679 for (j=0;j<coin_count;j++)
680 {
681 GNUNET_CRYPTO_rsa_public_key_free (coin_public_infos[j].denom_pub);
682 GNUNET_CRYPTO_rsa_signature_free (coin_public_infos[j].denom_sig);
683 }
684 GNUNET_free (coin_public_infos);
685 for (j=0;j<num_new_denoms;j++)
686 {
687 GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j]);
688 }
689 GNUNET_free (coin_melt_details);
690 GNUNET_free (denom_pubs);
752 return res; 691 return res;
753} 692}
754 693
755 694
756/** 695/**
757 * Handle a "/refresh/commit" request. Parses the top-level JSON to 696 * Handle a "/refresh/melt" request. Parses the request into the JSON
758 * determine the dimensions of the problem and then handles handing 697 * components and then hands things of to #handle_referesh_melt_json()
759 * off to #handle_refresh_commit_json() to parse the details of the 698 * to validate the melted coins, the signature and execute the melt
760 * JSON arguments. Once the signature has been verified, the 699 * using TALER_MINT_db_execute_refresh_melt().
761 * commit data is written to the database via
762 * #TALER_MINT_db_execute_refresh_commit() and the reveal parameter
763 * is then returned to the client.
764 * 700 *
765 * @param rh context of the handler 701 * @param rh context of the handler
766 * @param connection the MHD connection to handle 702 * @param connection the MHD connection to handle
@@ -768,28 +704,34 @@ handle_refresh_commit_json (struct MHD_Connection *connection,
768 * @param upload_data upload data 704 * @param upload_data upload data
769 * @param[IN|OUT] upload_data_size number of bytes (left) in @a upload_data 705 * @param[IN|OUT] upload_data_size number of bytes (left) in @a upload_data
770 * @return MHD result code 706 * @return MHD result code
771 */ 707 */
772int 708int
773TALER_MINT_handler_refresh_commit (struct RequestHandler *rh, 709TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
774 struct MHD_Connection *connection, 710 struct MHD_Connection *connection,
775 void **connection_cls, 711 void **connection_cls,
776 const char *upload_data, 712 const char *upload_data,
777 size_t *upload_data_size) 713 size_t *upload_data_size)
778{ 714{
779 struct GNUNET_CRYPTO_EddsaPublicKey refresh_session_pub;
780 int res;
781 unsigned int kappa;
782 unsigned int num_oldcoins;
783 unsigned int num_newcoins;
784 json_t *root; 715 json_t *root;
716 json_t *new_denoms;
717 json_t *melt_coins;
718 json_t *melt_sig_json;
785 json_t *coin_evs; 719 json_t *coin_evs;
786 json_t *link_encs; 720 json_t *link_encs;
787 json_t *transfer_pubs; 721 json_t *transfer_pubs;
788 json_t *secret_encs; 722 json_t *secret_encs;
789 json_t *coin_detail;
790 json_t *commit_sig_json; 723 json_t *commit_sig_json;
724 unsigned int kappa;
725 unsigned int num_oldcoins;
726 unsigned int num_newcoins;
727 json_t *coin_detail;
728 struct GNUNET_CRYPTO_EddsaPublicKey refresh_session_pub;
729 int res;
791 struct GNUNET_MINT_ParseFieldSpec spec[] = { 730 struct GNUNET_MINT_ParseFieldSpec spec[] = {
792 TALER_MINT_PARSE_FIXED ("session_pub", &refresh_session_pub), 731 TALER_MINT_PARSE_FIXED ("session_pub", &refresh_session_pub),
732 TALER_MINT_PARSE_ARRAY ("new_denoms", &new_denoms),
733 TALER_MINT_PARSE_ARRAY ("melt_coins", &melt_coins),
734 TALER_MINT_PARSE_ARRAY ("melt_signature", &melt_sig_json),
793 TALER_MINT_PARSE_ARRAY ("coin_evs", &coin_evs), 735 TALER_MINT_PARSE_ARRAY ("coin_evs", &coin_evs),
794 TALER_MINT_PARSE_ARRAY ("link_encs", &link_encs), 736 TALER_MINT_PARSE_ARRAY ("link_encs", &link_encs),
795 TALER_MINT_PARSE_ARRAY ("transfer_pubs", &transfer_pubs), 737 TALER_MINT_PARSE_ARRAY ("transfer_pubs", &transfer_pubs),
@@ -852,16 +794,21 @@ TALER_MINT_handler_refresh_commit (struct RequestHandler *rh,
852 return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; 794 return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
853 } 795 }
854 num_oldcoins = json_array_size (coin_detail); 796 num_oldcoins = json_array_size (coin_detail);
855 res = handle_refresh_commit_json (connection, 797
856 &refresh_session_pub, 798 res = handle_refresh_melt_json (connection,
857 commit_sig_json, 799 &refresh_session_pub,
858 kappa, 800 new_denoms,
859 num_oldcoins, 801 melt_coins,
860 transfer_pubs, 802 melt_sig_json,
861 secret_encs, 803 commit_sig_json,
862 num_newcoins, 804 kappa,
863 coin_evs, 805 num_oldcoins,
864 link_encs); 806 transfer_pubs,
807 secret_encs,
808 num_newcoins,
809 coin_evs,
810 link_encs);
811
865 TALER_MINT_release_parsed_data (spec); 812 TALER_MINT_release_parsed_data (spec);
866 return res; 813 return res;
867} 814}
@@ -931,7 +878,7 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
931/** 878/**
932 * Handle a "/refresh/reveal" request. This time, the client reveals 879 * Handle a "/refresh/reveal" request. This time, the client reveals
933 * the private transfer keys except for the cut-and-choose value 880 * the private transfer keys except for the cut-and-choose value
934 * returned from "/refresh/commit". This function parses the revealed 881 * returned from "/refresh/melt". This function parses the revealed
935 * keys and secrets and ultimately passes everything to 882 * keys and secrets and ultimately passes everything to
936 * #TALER_MINT_db_execute_refresh_reveal() which will verify that the 883 * #TALER_MINT_db_execute_refresh_reveal() which will verify that the
937 * revealed information is valid then returns the signed refreshed 884 * revealed information is valid then returns the signed refreshed