diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_refreshes_reveal.c')
-rw-r--r-- | src/exchange/taler-exchange-httpd_refreshes_reveal.c | 232 |
1 files changed, 122 insertions, 110 deletions
diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c index bbccd5688..5630051cf 100644 --- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c +++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c @@ -111,9 +111,6 @@ struct RevealContext /** * Array of information about fresh coins being revealed. */ - /* FIXME: const would be nicer here, but we initalize - the 'alg_values' in the verification - routine; suboptimal to be fixed... */ struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrcs; /** @@ -159,14 +156,17 @@ check_commitment (struct RevealContext *rctx, struct MHD_Connection *connection, MHD_RESULT *mhd_ret) { - struct TALER_CsNonce nonces[rctx->num_fresh_coins]; - unsigned int aoff = 0; + const union GNUNET_CRYPTO_BlindSessionNonce *nonces[rctx->num_fresh_coins]; + memset (nonces, + 0, + sizeof (nonces)); for (unsigned int j = 0; j<rctx->num_fresh_coins; j++) { const struct TALER_DenominationPublicKey *dk = &rctx->dks[j]->denom_pub; - if (dk->cipher != rctx->rcds[j].blinded_planchet.cipher) + if (dk->bsign_pub_key->cipher != + rctx->rcds[j].blinded_planchet.blinded_message->cipher) { GNUNET_break (0); *mhd_ret = TALER_MHD_reply_with_error ( @@ -176,9 +176,9 @@ check_commitment (struct RevealContext *rctx, NULL); return GNUNET_SYSERR; } - switch (dk->cipher) + switch (dk->bsign_pub_key->cipher) { - case TALER_DENOMINATION_INVALID: + case GNUNET_CRYPTO_BSA_INVALID: GNUNET_break (0); *mhd_ret = TALER_MHD_reply_with_error ( connection, @@ -186,40 +186,48 @@ check_commitment (struct RevealContext *rctx, TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, NULL); return GNUNET_SYSERR; - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: continue; - case TALER_DENOMINATION_CS: - nonces[aoff] - = rctx->rcds[j].blinded_planchet.details.cs_blinded_planchet.nonce; - aoff++; + case GNUNET_CRYPTO_BSA_CS: + nonces[j] + = (const union GNUNET_CRYPTO_BlindSessionNonce *) + &rctx->rcds[j].blinded_planchet.blinded_message->details. + cs_blinded_message.nonce; break; } } // OPTIMIZE: do this in batch later! - aoff = 0; for (unsigned int j = 0; j<rctx->num_fresh_coins; j++) { const struct TALER_DenominationPublicKey *dk = &rctx->dks[j]->denom_pub; struct TALER_ExchangeWithdrawValues *alg_values = &rctx->rrcs[j].exchange_vals; + struct GNUNET_CRYPTO_BlindingInputValues *bi; - alg_values->cipher = dk->cipher; - switch (dk->cipher) + bi = GNUNET_new (struct GNUNET_CRYPTO_BlindingInputValues); + alg_values->blinding_inputs = bi; + bi->rc = 1; + bi->cipher = dk->bsign_pub_key->cipher; + switch (dk->bsign_pub_key->cipher) { - case TALER_DENOMINATION_INVALID: + case GNUNET_CRYPTO_BSA_INVALID: GNUNET_assert (0); return GNUNET_SYSERR; - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: continue; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { enum TALER_ErrorCode ec; - - ec = TEH_keys_denomination_cs_r_pub_melt ( - &rctx->rrcs[j].h_denom_pub, - &nonces[aoff], - &alg_values->details.cs_values); + const struct TEH_CsDeriveData cdd = { + .h_denom_pub = &rctx->rrcs[j].h_denom_pub, + .nonce = &nonces[j]->cs_nonce + }; + + ec = TEH_keys_denomination_cs_r_pub ( + &cdd, + true, + &bi->details.cs_values); if (TALER_EC_NONE != ec) { *mhd_ret = TALER_MHD_reply_with_error (connection, @@ -228,7 +236,6 @@ check_commitment (struct RevealContext *rctx, NULL); return GNUNET_SYSERR; } - aoff++; } } } @@ -259,6 +266,8 @@ check_commitment (struct RevealContext *rctx, const struct TALER_TransferPrivateKeyP *tpriv = &rctx->transfer_privs[i - off]; struct TALER_TransferSecretP ts; + struct TALER_AgeCommitmentHash h = {0}; + struct TALER_AgeCommitmentHash *hac = NULL; GNUNET_CRYPTO_ecdhe_key_get_public (&tpriv->ecdhe_priv, &rce->transfer_pub.ecdhe_pub); @@ -268,18 +277,14 @@ check_commitment (struct RevealContext *rctx, &ts); rce->new_coins = GNUNET_new_array (rctx->num_fresh_coins, struct TALER_RefreshCoinData); - aoff = 0; for (unsigned int j = 0; j<rctx->num_fresh_coins; j++) { - const struct TALER_DenominationPublicKey *dk - = &rctx->dks[j]->denom_pub; struct TALER_RefreshCoinData *rcd = &rce->new_coins[j]; struct TALER_CoinSpendPrivateKeyP coin_priv; - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; const struct TALER_ExchangeWithdrawValues *alg_value = &rctx->rrcs[j].exchange_vals; struct TALER_PlanchetDetail pd = {0}; - struct TALER_AgeCommitmentHash *hac = NULL; struct TALER_CoinPubHashP c_hash; struct TALER_PlanchetMasterSecretP ps; @@ -303,15 +308,15 @@ check_commitment (struct RevealContext *rctx, .commitment = *(rctx->old_age_commitment) }; struct TALER_AgeCommitmentProof nacp = {0}; - struct TALER_AgeCommitmentHash h = {0}; GNUNET_assert (GNUNET_OK == TALER_age_commitment_derive ( &acp, &ts.key, &nacp)); - - TALER_age_commitment_hash (&nacp.commitment, &h); + TALER_age_commitment_hash (&nacp.commitment, + &h); + TALER_age_commitment_proof_free (&nacp); hac = &h; } @@ -319,16 +324,11 @@ check_commitment (struct RevealContext *rctx, TALER_planchet_prepare (rcd->dk, alg_value, &bks, + nonces[j], &coin_priv, hac, &c_hash, &pd)); - if (TALER_DENOMINATION_CS == dk->cipher) - { - pd.blinded_planchet.details.cs_blinded_planchet.nonce = - nonces[aoff]; - aoff++; - } rcd->blinded_planchet = pd.blinded_planchet; } } @@ -428,12 +428,13 @@ check_commitment (struct RevealContext *rctx, * @return MHD result code */ static MHD_RESULT -resolve_refreshes_reveal_denominations (struct MHD_Connection *connection, - struct RevealContext *rctx, - const json_t *link_sigs_json, - const json_t *new_denoms_h_json, - const json_t *old_age_commitment_json, - const json_t *coin_evs) +resolve_refreshes_reveal_denominations ( + struct MHD_Connection *connection, + struct RevealContext *rctx, + const json_t *link_sigs_json, + const json_t *new_denoms_h_json, + const json_t *old_age_commitment_json, + const json_t *coin_evs) { unsigned int num_fresh_coins = json_array_size (new_denoms_h_json); /* We know num_fresh_coins is bounded by #TALER_MAX_FRESH_COINS, so this is safe */ @@ -506,6 +507,13 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection, } } + old_dk = TEH_keys_denomination_by_hash_from_state ( + ksh, + &rctx->melt.session.coin.denom_pub_hash, + connection, + &ret); + if (NULL == old_dk) + return ret; /* Parse denomination key hashes */ for (unsigned int i = 0; i<num_fresh_coins; i++) @@ -524,20 +532,14 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection, -1); if (GNUNET_OK != res) return (GNUNET_NO == res) ? MHD_YES : MHD_NO; - dks[i] = TEH_keys_denomination_by_hash2 (ksh, - &rrcs[i].h_denom_pub, - connection, - &ret); + dks[i] = TEH_keys_denomination_by_hash_from_state (ksh, + &rrcs[i].h_denom_pub, + connection, + &ret); if (NULL == dks[i]) return ret; - old_dk = TEH_keys_denomination_by_hash2 (ksh, - &rctx->melt.session.coin. - denom_pub_hash, - connection, - &ret); - if (NULL == old_dk) - return ret; - if ( (TALER_DENOMINATION_CS == dks[i]->denom_pub.cipher) && + if ( (GNUNET_CRYPTO_BSA_CS == + dks[i]->denom_pub.bsign_pub_key->cipher) && (rctx->no_rms) ) { return TALER_MHD_reply_with_error ( @@ -622,8 +624,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection, bool failed = true; /* Has been checked in handle_refreshes_reveal_json() */ - GNUNET_assert (ng == - TALER_extensions_age_restriction_num_groups ()); + GNUNET_assert (ng == TEH_age_restriction_config.num_groups); rctx->old_age_commitment = GNUNET_new (struct TALER_AgeCommitment); oac = rctx->old_age_commitment; @@ -720,7 +721,8 @@ clean_age: rcd->blinded_planchet = rrc->blinded_planchet; rcd->dk = &dks[i]->denom_pub; - if (rcd->blinded_planchet.cipher != rcd->dk->cipher) + if (rcd->blinded_planchet.blinded_message->cipher != + rcd->dk->bsign_pub_key->cipher) { GNUNET_break_op (0); ret = TALER_MHD_REPLY_JSON_PACK ( @@ -746,16 +748,21 @@ clean_age: (unsigned int) rctx->num_fresh_coins); /* create fresh coin signatures */ - for (unsigned int i = 0; i<rctx->num_fresh_coins; i++) { + struct TEH_CoinSignData csds[rctx->num_fresh_coins]; + struct TALER_BlindedDenominationSignature bss[rctx->num_fresh_coins]; enum TALER_ErrorCode ec; - // FIXME: replace with a batch call that - // passes all coins in once go! - ec = TEH_keys_denomination_sign_melt ( - &rrcs[i].h_denom_pub, - &rcds[i].blinded_planchet, - &rrcs[i].coin_sig); + for (unsigned int i = 0; i<rctx->num_fresh_coins; i++) + { + csds[i].h_denom_pub = &rrcs[i].h_denom_pub; + csds[i].bp = &rcds[i].blinded_planchet; + } + ec = TEH_keys_denomination_batch_sign ( + rctx->num_fresh_coins, + csds, + true, + bss); if (TALER_EC_NONE != ec) { GNUNET_break (0); @@ -764,13 +771,21 @@ clean_age: NULL); goto cleanup; } - } + for (unsigned int i = 0; i<rctx->num_fresh_coins; i++) + { + rrcs[i].coin_sig = bss[i]; + rrcs[i].blinded_planchet = rcds[i].blinded_planchet; + } + } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Signatures ready, starting DB interaction\n"); + for (unsigned int r = 0; r<MAX_TRANSACTION_COMMIT_RETRIES; r++) { + bool changed; + /* Persist operation result in DB */ if (GNUNET_OK != TEH_plugin->start (TEH_plugin->cls, @@ -783,19 +798,15 @@ clean_age: NULL); goto cleanup; } - for (unsigned int i = 0; i<rctx->num_fresh_coins; i++) - { - struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrc = &rrcs[i]; - rrc->blinded_planchet = rcds[i].blinded_planchet; - } - qs = TEH_plugin->insert_refresh_reveal (TEH_plugin->cls, - melt_serial_id, - num_fresh_coins, - rrcs, - TALER_CNC_KAPPA - 1, - rctx->transfer_privs, - &rctx->gamma_tp); + qs = TEH_plugin->insert_refresh_reveal ( + TEH_plugin->cls, + melt_serial_id, + num_fresh_coins, + rrcs, + TALER_CNC_KAPPA - 1, + rctx->transfer_privs, + &rctx->gamma_tp); if (GNUNET_DB_STATUS_SOFT_ERROR == qs) { TEH_plugin->rollback (TEH_plugin->cls); @@ -812,9 +823,14 @@ clean_age: "insert_refresh_reveal"); goto cleanup; } + changed = (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs); qs = TEH_plugin->commit (TEH_plugin->cls); if (qs >= 0) + { + if (changed) + TEH_METRICS_num_success[TEH_MT_SUCCESS_REFRESH_REVEAL]++; break; /* success */ + } if (GNUNET_DB_STATUS_HARD_ERROR == qs) { GNUNET_break (0); @@ -847,7 +863,10 @@ cleanup: for (unsigned int i = 0; i<num_fresh_coins; i++) { struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrc = &rrcs[i]; + struct TALER_ExchangeWithdrawValues *alg_values + = &rrcs[i].exchange_vals; + GNUNET_free (alg_values->blinding_inputs); TALER_blinded_denom_sig_free (&rrc->coin_sig); TALER_blinded_planchet_free (&rrc->blinded_planchet); } @@ -922,7 +941,7 @@ handle_refreshes_reveal_json (struct MHD_Connection *connection, /* Sanity check of age commitment: If it was provided, it _must_ be an array * of the size the # of age groups */ if (NULL != old_age_commitment_json - && TALER_extensions_age_restriction_num_groups () != + && TEH_age_restriction_config.num_groups != json_array_size (old_age_commitment_json)) { GNUNET_break_op (0); @@ -965,26 +984,26 @@ TEH_handler_reveal (struct TEH_RequestContext *rc, const json_t *root, const char *const args[2]) { - json_t *coin_evs; - json_t *transfer_privs; - json_t *link_sigs; - json_t *new_denoms_h; - json_t *old_age_commitment; + const json_t *coin_evs; + const json_t *transfer_privs; + const json_t *link_sigs; + const json_t *new_denoms_h; + const json_t *old_age_commitment; struct RevealContext rctx; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("transfer_pub", &rctx.gamma_tp), - GNUNET_JSON_spec_json ("transfer_privs", - &transfer_privs), - GNUNET_JSON_spec_json ("link_sigs", - &link_sigs), - GNUNET_JSON_spec_json ("coin_evs", - &coin_evs), - GNUNET_JSON_spec_json ("new_denoms_h", - &new_denoms_h), + GNUNET_JSON_spec_array_const ("transfer_privs", + &transfer_privs), + GNUNET_JSON_spec_array_const ("link_sigs", + &link_sigs), + GNUNET_JSON_spec_array_const ("coin_evs", + &coin_evs), + GNUNET_JSON_spec_array_const ("new_denoms_h", + &new_denoms_h), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_json ("old_age_commitment", - &old_age_commitment), + GNUNET_JSON_spec_array_const ("old_age_commitment", + &old_age_commitment), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_fixed_auto ("rms", @@ -1035,7 +1054,6 @@ TEH_handler_reveal (struct TEH_RequestContext *rc, /* Note we do +1 as 1 row (cut-and-choose!) is missing! */ if (TALER_CNC_KAPPA != json_array_size (transfer_privs) + 1) { - GNUNET_JSON_parse_free (spec); GNUNET_break_op (0); return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_BAD_REQUEST, @@ -1043,19 +1061,13 @@ TEH_handler_reveal (struct TEH_RequestContext *rc, NULL); } - { - MHD_RESULT res; - - res = handle_refreshes_reveal_json (rc->connection, - &rctx, - transfer_privs, - link_sigs, - new_denoms_h, - old_age_commitment, - coin_evs); - GNUNET_JSON_parse_free (spec); - return res; - } + return handle_refreshes_reveal_json (rc->connection, + &rctx, + transfer_privs, + link_sigs, + new_denoms_h, + old_age_commitment, + coin_evs); } |