-finish first implementaation of exchange_api_contracts_get.c

This commit is contained in:
Christian Grothoff 2022-04-11 19:22:30 +02:00
parent 78cf27aaac
commit b91a406525
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
3 changed files with 65 additions and 58 deletions

View File

@ -3999,57 +3999,19 @@ struct TALER_EXCHANGE_ContractGetResponse
{ {
/** /**
* What is the type of the transaction? * Public key of the purse.
*/ */
enum struct TALER_PurseContractPublicKeyP purse_pub;
{
/**
* This is a request for payment.
*/
TALER_EXCHANGE_CONTRACT_PAYMENT_REQUEST = 0,
/**
* This is a payment, the receiver needs to
* accepts the terms.
*/
TALER_EXCHANGE_CONTRACT_PAYMENT_OFFER = 1
} type;
/** /**
* Key material, depending on @e type. * Private key of the merge capability.
*/ */
union struct TALER_PurseMergePrivateKeyP merge_priv;
{
/**
* Set if @e type is #TALER_EXCHANGE_CONTRACT_PAYMENT_REQUEST.
*/
struct TALER_PurseContractPublicKeyP purse_pub;
/**
* Set if @e type is #TALER_EXCHANGE_CONTRACT_PAYMENT_OFFER.
*/
struct TALER_PurseMergePrivateKeyP merge_priv;
} keys;
/**
* Total value of the contract/purse.
*/
struct TALER_Amount amount;
/** /**
* Contract terms. * Contract terms.
*/ */
json_t *contract_terms; const json_t *contract_terms;
/**
* Minimum age required to pay for the contract.
*/
uint8_t min_age;
/**
* When will the purse expire?
*/
struct GNUNET_TIME_Timestamp purse_expiration;
} success; } success;

View File

@ -68,6 +68,11 @@ struct TALER_EXCHANGE_ContractsGetHandle
*/ */
struct TALER_ContractDiffiePrivateP contract_priv; struct TALER_ContractDiffiePrivateP contract_priv;
/**
* Public key matching @e contract_priv.
*/
struct TALER_ContractDiffiePublicP cpub;
}; };
@ -101,11 +106,11 @@ handle_contract_get_finished (void *cls,
{ {
void *econtract; void *econtract;
size_t econtract_size; size_t econtract_size;
struct TALER_PurseContractPublicKeyP purse_pub; json_t *contract;
struct TALER_PurseContractSignatureP econtract_sig; struct TALER_PurseContractSignatureP econtract_sig;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("purse_pub", GNUNET_JSON_spec_fixed_auto ("purse_pub",
&purse_pub), &dr.details.success.purse_pub),
GNUNET_JSON_spec_fixed_auto ("econtract_sig", GNUNET_JSON_spec_fixed_auto ("econtract_sig",
&econtract_sig), &econtract_sig),
GNUNET_JSON_spec_varsize ("econtract", GNUNET_JSON_spec_varsize ("econtract",
@ -124,11 +129,38 @@ handle_contract_get_finished (void *cls,
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
break; break;
} }
// FIXME: verify econtract_sig! if (GNUNET_OK !=
// FIXME: decrypt, build up 'dr'! TALER_wallet_econtract_upload_verify (
econtract,
econtract_size,
&cgh->cpub,
&dr.details.success.purse_pub,
&econtract_sig))
{
GNUNET_break (0);
dr.hr.http_status = 0;
dr.hr.ec = TALER_EC_EXCHANGE_CONTRACTS_SIGNATURE_INVALID;
GNUNET_JSON_parse_free (spec);
break;
}
contract = TALER_CRYPTO_contract_decrypt_for_merge (
&cgh->contract_priv,
&dr.details.success.purse_pub,
econtract,
econtract_size,
&dr.details.success.merge_priv);
GNUNET_JSON_parse_free (spec);
if (NULL == contract)
{
GNUNET_break (0);
dr.hr.http_status = 0;
dr.hr.ec = TALER_EC_EXCHANGE_CONTRACTS_DECRYPTION_FAILED;
break;
}
dr.details.success.contract_terms = contract;
cgh->cb (cgh->cb_cls, cgh->cb (cgh->cb_cls,
&dr); &dr);
GNUNET_JSON_parse_free (spec); json_decref (contract);
TALER_EXCHANGE_contract_get_cancel (cgh); TALER_EXCHANGE_contract_get_cancel (cgh);
return; return;
} }
@ -183,8 +215,7 @@ TALER_EXCHANGE_contract_get (
{ {
struct TALER_EXCHANGE_ContractsGetHandle *cgh; struct TALER_EXCHANGE_ContractsGetHandle *cgh;
CURL *eh; CURL *eh;
struct TALER_ContractDiffiePublicP cpub; char arg_str[sizeof (cgh->cpub) * 2 + 48];
char arg_str[sizeof (cpub) * 2 + 48];
if (GNUNET_YES != if (GNUNET_YES !=
TEAH_handle_is_ready (exchange)) TEAH_handle_is_ready (exchange))
@ -192,14 +223,18 @@ TALER_EXCHANGE_contract_get (
GNUNET_break (0); GNUNET_break (0);
return NULL; return NULL;
} }
cgh = GNUNET_new (struct TALER_EXCHANGE_ContractsGetHandle);
cgh->exchange = exchange;
cgh->cb = cb;
cgh->cb_cls = cb_cls;
GNUNET_CRYPTO_ecdhe_key_get_public (&contract_priv->ecdhe_priv, GNUNET_CRYPTO_ecdhe_key_get_public (&contract_priv->ecdhe_priv,
&cpub.ecdhe_pub); &cgh->cpub.ecdhe_pub);
{ {
char cpub_str[sizeof (cpub) * 2]; char cpub_str[sizeof (cgh->cpub) * 2];
char *end; char *end;
end = GNUNET_STRINGS_data_to_string (&cpub, end = GNUNET_STRINGS_data_to_string (&cgh->cpub,
sizeof (cpub), sizeof (cgh->cpub),
cpub_str, cpub_str,
sizeof (cpub_str)); sizeof (cpub_str));
*end = '\0'; *end = '\0';
@ -209,10 +244,6 @@ TALER_EXCHANGE_contract_get (
cpub_str); cpub_str);
} }
cgh = GNUNET_new (struct TALER_EXCHANGE_ContractsGetHandle);
cgh->exchange = exchange;
cgh->cb = cb;
cgh->cb_cls = cb_cls;
cgh->url = TEAH_path_to_url (exchange, cgh->url = TEAH_path_to_url (exchange,
arg_str); arg_str);
if (NULL == cgh->url) if (NULL == cgh->url)

View File

@ -24,6 +24,20 @@
#include "taler_exchange_service.h" #include "taler_exchange_service.h"
/**
* Different types of contracts supported.
*/
enum ContractFormats
{
/**
* The encrypted contract represents a payment offer. The receiver
* can merge it into a reserve/account to accept the contract and
* obtain the payment.
*/
TALER_EXCHANGE_CONTRACT_PAYMENT_OFFER = 0
};
/** /**
* Nonce used for encryption, 24 bytes. * Nonce used for encryption, 24 bytes.
*/ */