-finish implemnetation of /kyc-check client library
This commit is contained in:
parent
df681b0d95
commit
8951abfc50
@ -1810,7 +1810,7 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
* were set,
|
||||
* #GNUNET_SYSERR if there was a protocol violation in @a history
|
||||
*/
|
||||
int
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_EXCHANGE_parse_reserve_history (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
const json_t *history,
|
||||
@ -1988,7 +1988,7 @@ typedef void
|
||||
struct TALER_EXCHANGE_KycCheckHandle *
|
||||
TALER_EXCHANGE_kyc_check (struct TALER_EXCHANGE_Handle *eh,
|
||||
uint64_t payment_target,
|
||||
const struct GNUNET_HashCode *h_wire,
|
||||
const struct GNUNET_HashCode *h_payto,
|
||||
struct GNUNET_TIME_Relative timeout,
|
||||
TALER_EXCHANGE_KycStatusCallback cb,
|
||||
void *cb_cls);
|
||||
|
@ -167,6 +167,12 @@
|
||||
*/
|
||||
#define TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED 1043
|
||||
|
||||
/**
|
||||
* Signature by which an exchange affirms that an account
|
||||
* successfully passed the KYC checks.
|
||||
*/
|
||||
#define TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS 1044
|
||||
|
||||
|
||||
/**********************/
|
||||
/* Auditor signatures */
|
||||
@ -818,6 +824,31 @@ struct TALER_ExchangeKeySetPS
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Signature by which an exchange affirms that an account
|
||||
* successfully passed the KYC checks.
|
||||
*/
|
||||
struct TALER_ExchangeAccountSetupSuccessPS
|
||||
{
|
||||
/**
|
||||
* Purpose is #TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS. Signed by a
|
||||
* `struct TALER_ExchangePublicKeyP` using EdDSA.
|
||||
*/
|
||||
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
||||
|
||||
/**
|
||||
* Hash over the payto for which the signature was
|
||||
* made.
|
||||
*/
|
||||
struct GNUNET_HashCode h_payto;
|
||||
|
||||
/**
|
||||
* When was the signature made.
|
||||
*/
|
||||
struct GNUNET_TIME_AbsoluteNBO timestamp;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Signature made by the exchange offline key over the information of
|
||||
* an auditor to be added to the exchange's set of auditors.
|
||||
|
@ -42,7 +42,7 @@
|
||||
* were set,
|
||||
* #GNUNET_SYSERR if there was a protocol violation in @a history
|
||||
*/
|
||||
int
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_EXCHANGE_parse_reserve_history (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
const json_t *history,
|
||||
|
@ -188,7 +188,7 @@ auditor_cb (void *cls,
|
||||
* @param[out] exchange_pub set to the exchange's public key
|
||||
* @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
verify_deposit_signature_ok (struct TALER_EXCHANGE_DepositHandle *dh,
|
||||
const json_t *json,
|
||||
struct TALER_ExchangeSignatureP *exchange_sig,
|
||||
@ -245,7 +245,7 @@ verify_deposit_signature_ok (struct TALER_EXCHANGE_DepositHandle *dh,
|
||||
* @param json json reply with the signature(s) and transaction history
|
||||
* @return #GNUNET_OK if the signature(s) is valid, #GNUNET_SYSERR if not
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
verify_deposit_signature_conflict (
|
||||
const struct TALER_EXCHANGE_DepositHandle *dh,
|
||||
const json_t *json)
|
||||
@ -441,7 +441,7 @@ handle_deposit_finished (void *cls,
|
||||
* @param coin_sig the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_DEPOSIT made by the customer with the coin’s private key.
|
||||
* @return #GNUNET_OK if signatures are OK, #GNUNET_SYSERR if not
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki,
|
||||
const struct TALER_Amount *amount,
|
||||
const struct GNUNET_HashCode *h_wire,
|
||||
|
@ -257,7 +257,7 @@ free_keys_request (struct KeysRequest *kr)
|
||||
* @return #GNUNET_OK if all is fine, #GNUNET_SYSERR if the signature is
|
||||
* invalid or the json malformed.
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
parse_json_signkey (struct TALER_EXCHANGE_SigningPublicKey *sign_key,
|
||||
int check_sigs,
|
||||
json_t *sign_key_obj,
|
||||
@ -317,7 +317,7 @@ parse_json_signkey (struct TALER_EXCHANGE_SigningPublicKey *sign_key,
|
||||
* @return #GNUNET_OK if all is fine, #GNUNET_SYSERR if the signature is
|
||||
* invalid or the json malformed.
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key,
|
||||
int check_sigs,
|
||||
json_t *denom_key_obj,
|
||||
@ -402,7 +402,7 @@ EXITIF_exit:
|
||||
* @return #GNUNET_OK if all is fine, #GNUNET_SYSERR if the signature is
|
||||
* invalid or the json malformed.
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
parse_json_auditor (struct TALER_EXCHANGE_AuditorInformation *auditor,
|
||||
int check_sigs,
|
||||
json_t *auditor_obj,
|
||||
@ -670,7 +670,7 @@ denoms_cmp (struct TALER_EXCHANGE_DenomPublicKey *denom1,
|
||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
||||
* (malformed JSON)
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
decode_keys_json (const json_t *resp_obj,
|
||||
bool check_sig,
|
||||
struct TALER_EXCHANGE_Keys *key_data,
|
||||
@ -1314,7 +1314,7 @@ TEAH_handle_to_context (struct TALER_EXCHANGE_Handle *h)
|
||||
* @param h the exchange handle to query
|
||||
* @return #GNUNET_YES if we are ready, #GNUNET_NO if not
|
||||
*/
|
||||
int
|
||||
enum GNUNET_GenericReturnValue
|
||||
TEAH_handle_is_ready (struct TALER_EXCHANGE_Handle *h)
|
||||
{
|
||||
return (MHS_CERT == h->state) ? GNUNET_YES : GNUNET_NO;
|
||||
@ -1352,7 +1352,7 @@ TEAH_path_to_url (struct TALER_EXCHANGE_Handle *h,
|
||||
* @param at where to write the result
|
||||
* @return #GNUNET_OK on success
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
parse_date_string (const char *dateline,
|
||||
struct GNUNET_TIME_Absolute *at)
|
||||
{
|
||||
|
@ -229,7 +229,7 @@ TEAH_handle_to_context (struct TALER_EXCHANGE_Handle *h);
|
||||
* @param h the exchange handle to query
|
||||
* @return #GNUNET_YES if we are ready, #GNUNET_NO if not
|
||||
*/
|
||||
int
|
||||
enum GNUNET_GenericReturnValue
|
||||
TEAH_handle_is_ready (struct TALER_EXCHANGE_Handle *h);
|
||||
|
||||
/**
|
||||
@ -238,7 +238,7 @@ TEAH_handle_is_ready (struct TALER_EXCHANGE_Handle *h);
|
||||
* @param h the exchange handle to query
|
||||
* @return #GNUNET_YES if we are ready, #GNUNET_NO if not
|
||||
*/
|
||||
int
|
||||
enum GNUNET_GenericReturnValue
|
||||
TEAH_handle_is_ready (struct TALER_EXCHANGE_Handle *h);
|
||||
|
||||
|
||||
|
@ -61,6 +61,10 @@ struct TALER_EXCHANGE_KycCheckHandle
|
||||
*/
|
||||
void *cb_cls;
|
||||
|
||||
/**
|
||||
* Hash of the payto:// URL that is being KYC'ed.
|
||||
*/
|
||||
struct GNUNET_HashCode h_payto;
|
||||
};
|
||||
|
||||
|
||||
@ -90,30 +94,104 @@ handle_kyc_check_finished (void *cls,
|
||||
ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
GNUNET_break (0); // FIXME
|
||||
TALER_EXCHANGE_kyc_check_cancel (kch);
|
||||
return;
|
||||
{
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||
&ks.details.kyc_ok.exchange_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||
&ks.details.kyc_ok.exchange_pub),
|
||||
TALER_JSON_spec_absolute_time ("now",
|
||||
&ks.details.kyc_ok.timestamp),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
const struct TALER_EXCHANGE_Keys *key_state;
|
||||
struct TALER_ExchangeAccountSetupSuccessPS kyc_purpose = {
|
||||
.purpose.size = htonl (sizeof (kyc_purpose)),
|
||||
.purpose.purpose = htonl (
|
||||
TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS),
|
||||
.h_payto = kch->h_payto
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (j,
|
||||
spec,
|
||||
NULL, NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ks.http_status = 0;
|
||||
ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
}
|
||||
kyc_purpose.timestamp = GNUNET_TIME_absolute_hton (
|
||||
ks.details.kyc_ok.timestamp);
|
||||
key_state = TALER_EXCHANGE_get_keys (kch->exchange);
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_test_signing_key (key_state,
|
||||
&ks.details.kyc_ok.exchange_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ks.http_status = 0;
|
||||
ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
break;
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (
|
||||
TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS,
|
||||
&kyc_purpose,
|
||||
&ks.details.kyc_ok.exchange_sig.eddsa_signature,
|
||||
&ks.details.kyc_ok.exchange_pub.eddsa_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ks.http_status = 0;
|
||||
ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
break;
|
||||
}
|
||||
kch->cb (kch->cb_cls,
|
||||
&ks);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
TALER_EXCHANGE_kyc_check_cancel (kch);
|
||||
return;
|
||||
}
|
||||
case MHD_HTTP_ACCEPTED:
|
||||
GNUNET_break (0); // FIXME
|
||||
TALER_EXCHANGE_kyc_check_cancel (kch);
|
||||
return;
|
||||
{
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_string ("kyc_url",
|
||||
&ks.details.kyc_url),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (j,
|
||||
spec,
|
||||
NULL, NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
ks.http_status = 0;
|
||||
ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
}
|
||||
kch->cb (kch->cb_cls,
|
||||
&ks);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
TALER_EXCHANGE_kyc_check_cancel (kch);
|
||||
return;
|
||||
}
|
||||
case MHD_HTTP_NO_CONTENT:
|
||||
GNUNET_break (0); // FIXME
|
||||
TALER_EXCHANGE_kyc_check_cancel (kch);
|
||||
return;
|
||||
break;
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
ks.ec = TALER_JSON_get_error_code (j);
|
||||
/* This should never happen, either us or the exchange is buggy
|
||||
(or API version conflict); just pass JSON reply to the application */
|
||||
break;
|
||||
case MHD_HTTP_UNAUTHORIZED:
|
||||
GNUNET_break (0); // FIXME
|
||||
TALER_EXCHANGE_kyc_check_cancel (kch);
|
||||
return;
|
||||
ks.ec = TALER_JSON_get_error_code (j);
|
||||
break;
|
||||
case MHD_HTTP_NOT_FOUND:
|
||||
ks.ec = TALER_JSON_get_error_code (j);
|
||||
TALER_EXCHANGE_kyc_check_cancel (kch);
|
||||
return;
|
||||
break;
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
ks.ec = TALER_JSON_get_error_code (j);
|
||||
/* Server had an internal issue; we should retry, but this API
|
||||
@ -129,27 +207,16 @@ handle_kyc_check_finished (void *cls,
|
||||
(int) ks.ec);
|
||||
break;
|
||||
}
|
||||
kch->cb (kch->cb_cls,
|
||||
&ks);
|
||||
TALER_EXCHANGE_kyc_check_cancel (kch);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Submit a kyc_check request to the exchange and get the exchange's response.
|
||||
*
|
||||
* This API is typically not used by anyone, it is more a threat against those
|
||||
* trying to receive a funds transfer by abusing the refresh protocol.
|
||||
*
|
||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||
* @param coin_priv private key to request kyc_check data for
|
||||
* @param kyc_check_cb the callback to call with the useful result of the
|
||||
* refresh operation the @a coin_priv was involved in (if any)
|
||||
* @param kyc_check_cb_cls closure for @a kyc_check_cb
|
||||
* @return a handle for this request
|
||||
*/
|
||||
struct TALER_EXCHANGE_KycCheckHandle *
|
||||
TALER_EXCHANGE_kyc_check (struct TALER_EXCHANGE_Handle *exchange,
|
||||
uint64_t payment_target,
|
||||
const struct GNUNET_HashCode *h_wire,
|
||||
const struct GNUNET_HashCode *h_payto,
|
||||
struct GNUNET_TIME_Relative timeout,
|
||||
TALER_EXCHANGE_KycStatusCallback cb,
|
||||
void *cb_cls)
|
||||
@ -157,6 +224,7 @@ TALER_EXCHANGE_kyc_check (struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct TALER_EXCHANGE_KycCheckHandle *kch;
|
||||
CURL *eh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
char *arg_str;
|
||||
|
||||
if (GNUNET_YES !=
|
||||
TEAH_handle_is_ready (exchange))
|
||||
@ -164,13 +232,33 @@ TALER_EXCHANGE_kyc_check (struct TALER_EXCHANGE_Handle *exchange,
|
||||
GNUNET_break (0);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
char payto_str[sizeof (*h_payto) * 2];
|
||||
char *end;
|
||||
unsigned long long timeout_ms;
|
||||
|
||||
end = GNUNET_STRINGS_data_to_string (
|
||||
h_payto,
|
||||
sizeof (*h_payto),
|
||||
payto_str,
|
||||
sizeof (payto_str) - 1);
|
||||
*end = '\0';
|
||||
timeout_ms = timeout.rel_value_us
|
||||
/ GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us;
|
||||
GNUNET_asprintf (&arg_str,
|
||||
"/kyc-check/%llu?h_payto=%s&timeout_ms=%llu",
|
||||
(unsigned long long) payment_target,
|
||||
payto_str,
|
||||
timeout_ms);
|
||||
}
|
||||
kch = GNUNET_new (struct TALER_EXCHANGE_KycCheckHandle);
|
||||
kch->exchange = exchange;
|
||||
kch->h_payto = *h_payto;
|
||||
kch->cb = cb;
|
||||
kch->cb_cls = cb_cls;
|
||||
kch->url = TEAH_path_to_url (exchange,
|
||||
"FIXME");
|
||||
arg_str);
|
||||
GNUNET_free (arg_str);
|
||||
if (NULL == kch->url)
|
||||
{
|
||||
GNUNET_free (kch);
|
||||
@ -193,12 +281,6 @@ TALER_EXCHANGE_kyc_check (struct TALER_EXCHANGE_Handle *exchange,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cancel a kyc_check request. This function cannot be used
|
||||
* on a request handle if the callback was already invoked.
|
||||
*
|
||||
* @param kch the kyc_check handle
|
||||
*/
|
||||
void
|
||||
TALER_EXCHANGE_kyc_check_cancel (struct TALER_EXCHANGE_KycCheckHandle *kch)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user