From 41e1dd9738a58ffce765d5f837c32962907707df Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 29 Jan 2015 17:34:37 +0100 Subject: finish cleanup of /refresh/commit parsing --- src/include/taler_crypto_lib.h | 12 ++ src/mint/mint_db.c | 10 +- src/mint/taler-mint-httpd_refresh.c | 362 +++++++++++++++++++++++------------- src/util/crypto.c | 26 +++ 4 files changed, 273 insertions(+), 137 deletions(-) (limited to 'src') diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 597c85cd..3b4f0d8c 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -204,5 +204,17 @@ TALER_refresh_encrypt (const struct TALER_RefreshLinkDecrypted *input, const struct TALER_LinkSecret *secret); +/** + * Decode encrypted refresh link information from buffer. + * + * @param buf buffer with refresh link data + * @param buf_len number of bytes in @a buf + * @return NULL on error (@a buf_len too small) + */ +struct TALER_RefreshLinkEncrypted * +TALER_refresh_link_encrypted_decode (const char *buf, + size_t buf_len); + + #endif diff --git a/src/mint/mint_db.c b/src/mint/mint_db.c index 0e448bf0..5c52948e 100644 --- a/src/mint/mint_db.c +++ b/src/mint/mint_db.c @@ -1109,14 +1109,8 @@ TALER_MINT_DB_get_refresh_commit_coin (PGconn *db_conn, GNUNET_free (rl_buf); return GNUNET_SYSERR; } - - rl = GNUNET_malloc (sizeof (struct TALER_RefreshLinkEncrypted) + - rl_buf_size - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); - rl->blinding_key_enc = (const char *) &rl[1]; - rl->blinding_key_enc_size = rl_buf_size - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey); - memcpy (rl->coin_priv_enc, - rl_buf, - rl_buf_size); + rl = TALER_refresh_link_encrypted_decode (rl_buf, + rl_buf_size); GNUNET_free (rl_buf); cc->refresh_link = rl; cc->coin_ev = c_buf; diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c index 0abc82eb..98db2054 100644 --- a/src/mint/taler-mint-httpd_refresh.c +++ b/src/mint/taler-mint-httpd_refresh.c @@ -242,14 +242,13 @@ get_and_verify_coin_public_info (struct MHD_Connection *connection, struct RefreshMeltConfirmSignRequestBody body; struct MintKeyState *key_state; struct TALER_MINT_DenomKeyIssuePriv *dki; - struct GNUNET_MINT_ParseFieldSpec spec[] = - { - TALER_MINT_PARSE_FIXED ("coin_pub", &r_public_info->coin_pub), - TALER_MINT_PARSE_RSA_SIGNATURE ("denom_sig", &sig), - TALER_MINT_PARSE_RSA_PUBLIC_KEY ("denom_pub", &pk), - TALER_MINT_PARSE_FIXED ("confirm_sig", &melt_sig), - TALER_MINT_PARSE_END - }; + struct GNUNET_MINT_ParseFieldSpec spec[] = { + TALER_MINT_PARSE_FIXED ("coin_pub", &r_public_info->coin_pub), + TALER_MINT_PARSE_RSA_SIGNATURE ("denom_sig", &sig), + TALER_MINT_PARSE_RSA_PUBLIC_KEY ("denom_pub", &pk), + TALER_MINT_PARSE_FIXED ("confirm_sig", &melt_sig), + TALER_MINT_PARSE_END + }; ret = TALER_MINT_parse_json_data (connection, coin_info, @@ -463,108 +462,101 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh, /** - * Handle a "/refresh/commit" request + * Release memory from the @a commit_coin array. * - * @param rh context of the handler - * @param connection the MHD connection to handle - * @param[IN|OUT] connection_cls the connection's closure (can be updated) - * @param upload_data upload data - * @param[IN|OUT] upload_data_size number of bytes (left) in @a upload_data - * @return MHD result code - */ -int -TALER_MINT_handler_refresh_commit (struct RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size) + * @param commit_coin array to release + * @param kappa size of 1st dimension + * @param num_new_coins size of 2nd dimension + */ +static void +free_commit_coins (struct RefreshCommitCoin **commit_coin, + unsigned int kappa, + unsigned int num_new_coins) { - struct GNUNET_CRYPTO_EddsaPublicKey refresh_session_pub; - int res; unsigned int i; unsigned int j; - unsigned int kappa; - unsigned int num_oldcoins; - unsigned int num_newcoins; - struct GNUNET_HashCode commit_hash; - struct GNUNET_HashContext *hash_context; - json_t *root; - struct RefreshCommitSignatureBody body; - json_t *commit_sig_json; - struct RefreshCommitCoin **commit_coin; - struct RefreshCommitLink **commit_link; - json_t *coin_evs; - json_t *transfer_pubs; - json_t *coin_detail; - - res = TALER_MINT_parse_post_json (connection, - connection_cls, - upload_data, - upload_data_size, - &root); - if (GNUNET_SYSERR == res) - return MHD_NO; - if ( (GNUNET_NO == res) || (NULL == root) ) - return MHD_YES; - res = GNUNET_MINT_parse_navigate_json (connection, root, - JNAV_FIELD, "session_pub", - JNAV_RET_DATA, - &refresh_session_pub, - sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); - if (GNUNET_OK != res) + for (i=0;i kappa) - { - GNUNET_break_op (0); - // FIXME: generate error message - return MHD_NO; - } - res = GNUNET_MINT_parse_navigate_json (connection, root, - JNAV_FIELD, "coin_evs", - JNAV_INDEX, (int) 0, - JNAV_RET_DATA, - JSON_ARRAY, &coin_detail); - if (GNUNET_OK != res) - return res; - num_newcoins = json_array_size (coin_detail); - res = GNUNET_MINT_parse_navigate_json (connection, root, - JNAV_FIELD, "transfer_pubs", - JNAV_RET_TYPED_JSON, JSON_ARRAY, &transfer_pubs); - if (GNUNET_OK != res) - return res; - if (json_array_size (transfer_pubs) != kappa) +/** + * Release memory from the @a commit_link array. + * + * @param commit_coin array to release + * @param kappa size of 1st dimension + * @param num_old_coins size of 2nd dimension + */ +static void +free_commit_links (struct RefreshCommitLink **commit_link, + unsigned int kappa, + unsigned int num_old_coins) +{ + unsigned int i; + + for (i=0;i kappa) + { + GNUNET_break_op (0); + json_decref (root); + TALER_MINT_release_parsed_data (spec); + return TALER_MINT_reply_arg_invalid (connection, + "coin_evs"); + } + if (json_array_size (transfer_pubs) != kappa) + { + GNUNET_break_op (0); + json_decref (root); + TALER_MINT_release_parsed_data (spec); + return TALER_MINT_reply_arg_invalid (connection, + "transfer_pubs"); + } + res = GNUNET_MINT_parse_navigate_json (connection, coin_evs, + JNAV_INDEX, (int) 0, + JNAV_RET_DATA, + JSON_ARRAY, &coin_detail); + if (GNUNET_OK != res) + { + json_decref (root); + TALER_MINT_release_parsed_data (spec); + return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; + } + num_newcoins = json_array_size (coin_detail); + res = GNUNET_MINT_parse_navigate_json (connection, root, + JNAV_FIELD, "transfer_pubs", + JNAV_INDEX, (int) 0, + JNAV_RET_DATA, + JSON_ARRAY, &coin_detail); + if (GNUNET_OK != res) + { + json_decref (root); + TALER_MINT_release_parsed_data (spec); + return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; + } + num_oldcoins = json_array_size (coin_detail); + res = handle_refresh_commit_json (connection, + &refresh_session_pub, + commit_sig_json, + kappa, + num_oldcoins, + transfer_pubs, + secret_encs, + num_newcoins, + coin_evs, + link_encs); + TALER_MINT_release_parsed_data (spec); + json_decref (root); return res; } diff --git a/src/util/crypto.c b/src/util/crypto.c index 12f45208..25f951e8 100644 --- a/src/util/crypto.c +++ b/src/util/crypto.c @@ -268,6 +268,32 @@ TALER_refresh_encrypt (const struct TALER_RefreshLinkDecrypted *input, } +/** + * Decode encrypted refresh link information from buffer. + * + * @param buf buffer with refresh link data + * @param buf_len number of bytes in @a buf + * @return NULL on error (@a buf_len too small) + */ +struct TALER_RefreshLinkEncrypted * +TALER_refresh_link_encrypted_decode (const char *buf, + size_t buf_len) +{ + struct TALER_RefreshLinkEncrypted *rle; + + if (buf_len < sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)) + return NULL; + rle = GNUNET_malloc (sizeof (struct TALER_RefreshLinkEncrypted) + + buf_len - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); + rle->blinding_key_enc = (const char *) &rle[1]; + rle->blinding_key_enc_size = buf_len - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey); + memcpy (rle->coin_priv_enc, + buf, + buf_len); + return rle; +} + + /** * Check if a coin is valid; that is, whether the denomination key exists, * is not expired, and the signature is correct. -- cgit v1.2.3