-more work on purse creation for reserve

This commit is contained in:
Christian Grothoff 2022-04-21 20:24:53 +02:00
parent 061c4f72bd
commit f5eef0c816
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
2 changed files with 94 additions and 21 deletions

View File

@ -46,9 +46,9 @@ struct ReservePurseContext
const struct TALER_ReservePublicKeyP *reserve_pub; const struct TALER_ReservePublicKeyP *reserve_pub;
/** /**
* Public key of the purse we are creating. * Signature of the reserve affirming the merge.
*/ */
struct TALER_PurseContractPublicKeyP purse_pub; struct TALER_ReserveSignatureP reserve_sig;
/** /**
* Total amount to be put into the purse. * Total amount to be put into the purse.
@ -70,11 +70,21 @@ struct ReservePurseContext
*/ */
struct TALER_PurseMergePublicKeyP merge_pub; struct TALER_PurseMergePublicKeyP merge_pub;
/**
* Merge affirmation by the @e merge_pub.
*/
struct TALER_PurseMergeSignatureP merge_sig;
/** /**
* Contract decryption key for the purse. * Contract decryption key for the purse.
*/ */
struct TALER_ContractDiffiePublicP contract_pub; struct TALER_ContractDiffiePublicP contract_pub;
/**
* Public key of the purse we are creating.
*/
struct TALER_PurseContractPublicKeyP purse_pub;
/** /**
* Signature of the client affiming this request. * Signature of the client affiming this request.
*/ */
@ -252,7 +262,7 @@ purse_transaction (void *cls,
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
/* 2) merge purse with reserve (and debit reserve) */ /* 2) merge purse with reserve (and debit reserve for purse creation!) */
/* 3) if present, persist contract */ /* 3) if present, persist contract */
@ -337,7 +347,7 @@ TEH_handler_reserves_purse (
json_t *deposit; json_t *deposit;
unsigned int idx; unsigned int idx;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TALER_JSON_spec_amount ("amount", TALER_JSON_spec_amount ("purse_value",
TEH_currency, TEH_currency,
&rpc.amount), &rpc.amount),
GNUNET_JSON_spec_uint32 ("min_age", GNUNET_JSON_spec_uint32 ("min_age",
@ -357,14 +367,20 @@ TEH_handler_reserves_purse (
NULL), NULL),
GNUNET_JSON_spec_fixed_auto ("merge_pub", GNUNET_JSON_spec_fixed_auto ("merge_pub",
&rpc.merge_pub), &rpc.merge_pub),
GNUNET_JSON_spec_fixed_auto ("merge_sig",
&rpc.merge_sig),
GNUNET_JSON_spec_fixed_auto ("reserve_sig",
&rpc.reserve_sig),
GNUNET_JSON_spec_fixed_auto ("purse_pub",
&rpc.purse_pub),
GNUNET_JSON_spec_fixed_auto ("purse_sig", GNUNET_JSON_spec_fixed_auto ("purse_sig",
&rpc.purse_sig), &rpc.purse_sig),
GNUNET_JSON_spec_fixed_auto ("h_contract_terms", GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
&rpc.h_contract_terms), &rpc.h_contract_terms),
GNUNET_JSON_spec_timestamp ("purse_expiration",
&rpc.purse_expiration),
GNUNET_JSON_spec_timestamp ("merge_timestamp", GNUNET_JSON_spec_timestamp ("merge_timestamp",
&rpc.merge_timestamp), &rpc.merge_timestamp),
GNUNET_JSON_spec_timestamp ("purse_expiration",
&rpc.purse_expiration),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()
}; };
const struct TEH_GlobalFee *gf; const struct TEH_GlobalFee *gf;
@ -423,20 +439,53 @@ TEH_handler_reserves_purse (
TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
if (GNUNET_OK != if (GNUNET_OK !=
TALER_wallet_purse_purse_verify (rpc.purse_expiration, TALER_wallet_purse_create_verify (rpc.purse_expiration,
&rpc.h_contract_terms, &rpc.h_contract_terms,
&rpc.merge_pub, &rpc.merge_pub,
rpc.min_age, rpc.min_age,
&rpc.amount, &rpc.amount,
rpc.purse_pub, rpc.purse_pub,
&rpc.purse_sig)) &rpc.purse_sig))
{ {
TALER_LOG_WARNING ("Invalid signature on /reserves/$PID/purse request\n"); GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
GNUNET_free (rpc.coins); GNUNET_free (rpc.coins);
return TALER_MHD_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
MHD_HTTP_UNAUTHORIZED, MHD_HTTP_UNAUTHORIZED,
TALER_EC_EXCHANGE_PURSE_PURSE_SIGNATURE_INVALID, TALER_EC_EXCHANGE_PURSE_CREATE_SIGNATURE_INVALID,
NULL);
}
if (GNUNET_OK !=
TALER_wallet_purse_merge_verify ("FIXME exchange_url",
rpc.merge_timestamp,
&rpc.purse_pub,
&rpc.merge_pub,
&rpc.merge_sig))
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
GNUNET_free (rpc.coins);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_UNAUTHORIZED,
TALER_EC_EXCHANGE_PURSE_MERGE_SIGNATURE_INVALID,
NULL);
}
if (GNUNET_OK !=
TALER_wallet_account_merge_verify (rpc.merge_timestamp,
&rpc.purse_pub,
rpc.purse_expiration,
&rpc.h_contract_terms,
&rpc.purse_value,
rpc.min_age,
rpc.reserve_pub,
&rpc.reserve_sig))
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
GNUNET_free (rpc.coins);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_UNAUTHORIZED,
TALER_EC_EXCHANGE_RESERVE_MERGE_SIGNATURE_INVALID,
NULL); NULL);
} }
if ( (NULL != rpc.econtract) && if ( (NULL != rpc.econtract) &&

View File

@ -266,6 +266,8 @@ TALER_EXCHANGE_purse_create_with_merge (
uint32_t min_age = 0; uint32_t min_age = 0;
struct TALER_PurseMergePublicKeyP merge_pub; struct TALER_PurseMergePublicKeyP merge_pub;
struct TALER_PurseMergeSignatureP merge_sig; struct TALER_PurseMergeSignatureP merge_sig;
struct TALER_ContractDiffiePublicP contract_pub;
struct TALER_PurseContractSignatureP contract_sig;
void *econtract = NULL; void *econtract = NULL;
size_t econtract_size = 0; size_t econtract_size = 0;
@ -291,6 +293,8 @@ TALER_EXCHANGE_purse_create_with_merge (
&pcm->reserve_pub.eddsa_pub); &pcm->reserve_pub.eddsa_pub);
GNUNET_CRYPTO_eddsa_key_get_public (&merge_priv->eddsa_priv, GNUNET_CRYPTO_eddsa_key_get_public (&merge_priv->eddsa_priv,
&merge_pub.eddsa_pub); &merge_pub.eddsa_pub);
GNUNET_CRYPTO_ecdhe_key_get_public (&contract_priv->ecdhe_priv,
&contract_pub.ecdhe_pub);
// FIXME: extract min_age from contract_terms! // FIXME: extract min_age from contract_terms!
@ -347,26 +351,46 @@ TALER_EXCHANGE_purse_create_with_merge (
contract_terms, contract_terms,
&econtract, &econtract,
&econtract_size); &econtract_size);
TALER_wallet_econtract_upload_sign (
econtract,
econtract_size,
&contract_pub,
purse_priv,
&contract_sig);
} }
create_with_merge_obj = GNUNET_JSON_PACK ( create_with_merge_obj = GNUNET_JSON_PACK (
TALER_JSON_pack_amount ("purse_value",
purse_value_after_fees),
GNUNET_JSON_pack_data_uint64 ("min_age",
min_age),
GNUNET_JSON_allow_null ( GNUNET_JSON_allow_null (
GNUNET_JSON_pack_data_varsize ("econtract", GNUNET_JSON_pack_data_varsize ("econtract",
econtract, econtract,
econtract_size)), econtract_size)),
GNUNET_JSON_allow_null (
upload_contract
? GNUNET_JSON_pack_data_auto ("econtract_sig",
&contract_sig),
: GNUNET_JSON_pack_string ("dummy",
NULL)),
GNUNET_JSON_allow_null (
upload_contract
? GNUNET_JSON_pack_data_auto ("contract_pub",
&contract_pub),
: GNUNET_JSON_pack_string ("dummy",
NULL)),
GNUNET_JSON_pack_data_auto ("merge_pub",
&merge_pub),
GNUNET_JSON_pack_data_auto ("merge_sig", GNUNET_JSON_pack_data_auto ("merge_sig",
&merge_sig), &merge_sig),
GNUNET_JSON_pack_data_auto ("reserve_sig", GNUNET_JSON_pack_data_auto ("reserve_sig",
&reserve_sig), &reserve_sig),
GNUNET_JSON_pack_data_auto ("purse_sig",
&purse_sig),
GNUNET_JSON_pack_data_auto ("merge_pub",
&merge_pub),
GNUNET_JSON_pack_data_auto ("purse_pub", GNUNET_JSON_pack_data_auto ("purse_pub",
&pcm->purse_pub), &pcm->purse_pub),
GNUNET_JSON_pack_data_auto ("purse_sig",
&purse_sig),
GNUNET_JSON_pack_data_auto ("h_contract_terms", GNUNET_JSON_pack_data_auto ("h_contract_terms",
&pcm->h_contract_terms), &pcm->h_contract_terms),
TALER_JSON_pack_amount ("purse_value",
purse_value_after_fees),
GNUNET_JSON_pack_timestamp ("merge_timestamp", GNUNET_JSON_pack_timestamp ("merge_timestamp",
merge_timestamp) merge_timestamp)
GNUNET_JSON_pack_timestamp ("purse_expiration", GNUNET_JSON_pack_timestamp ("purse_expiration",