diff options
author | Christian Grothoff <christian@grothoff.org> | 2022-03-02 23:39:26 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2022-03-02 23:39:26 +0100 |
commit | cf4b6ebd6de3370da4b16d2f1ef19a2a3d3d0b12 (patch) | |
tree | eeec41a888f4f9cbdb77d6f01844ef20fccc2a43 /src/lib | |
parent | 81311476b804c054e4ee19c9b182f3b34357f88f (diff) | |
download | anastasis-cf4b6ebd6de3370da4b16d2f1ef19a2a3d3d0b12.tar.gz anastasis-cf4b6ebd6de3370da4b16d2f1ef19a2a3d3d0b12.tar.bz2 anastasis-cf4b6ebd6de3370da4b16d2f1ef19a2a3d3d0b12.zip |
push new /truth/ API through the entire implementation
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/anastasis_recovery.c | 375 |
1 files changed, 200 insertions, 175 deletions
diff --git a/src/lib/anastasis_recovery.c b/src/lib/anastasis_recovery.c index 9e5d1ca..a450392 100644 --- a/src/lib/anastasis_recovery.c +++ b/src/lib/anastasis_recovery.c @@ -63,16 +63,27 @@ struct ANASTASIS_Challenge /** * Callback which gives back the instructions and a status code of - * the request to the user when answering a challenge was initiated. + * the request to the user when answering a challenge. */ ANASTASIS_AnswerFeedback af; /** - * Closure for the challenge callback + * Closure for @e af. */ void *af_cls; /** + * Callback which gives back the instructions and a status code of + * the request to the user when initiating a challenge. + */ + ANASTASIS_ChallengeStartFeedback csf; + + /** + * Closure for @e csf. + */ + void *csf_cls; + + /** * Defines the base URL of the Anastasis provider used for the challenge. */ char *url; @@ -99,9 +110,14 @@ struct ANASTASIS_Challenge struct ANASTASIS_Recovery *recovery; /** - * keyshare lookup operation + * Handle for the /truth/$TID/challenge request. + */ + struct ANASTASIS_TruthChallengeOperation *tco; + + /** + * Handle for the /truth/$TID/solve request. */ - struct ANASTASIS_KeyShareLookupOperation *kslo; + struct ANASTASIS_TruthSolveOperation *tso; }; @@ -238,165 +254,137 @@ struct ANASTASIS_Recovery /** - * Function called with the results of a #ANASTASIS_keyshare_lookup(). + * Function called with the results of a #ANASTASIS_challenge_start(). * * @param cls closure * @param dd details about the lookup operation */ static void -keyshare_lookup_cb (void *cls, - const struct ANASTASIS_KeyShareDownloadDetails *dd) +truth_challenge_cb (void *cls, + const struct ANASTASIS_TruthChallengeDetails *tcd) { struct ANASTASIS_Challenge *c = cls; - struct ANASTASIS_Recovery *recovery = c->recovery; - struct ANASTASIS_CRYPTO_UserIdentifierP id; - struct DecryptionPolicy *rdps; - - c->kslo = NULL; - switch (dd->status) + struct ANASTASIS_ChallengeStartResponse csr = { + .challenge = c, + .ec = tcd->ec, + .http_status = tcd->http_status + }; + + c->tco = NULL; + switch (tcd->http_status) { - case ANASTASIS_KSD_SUCCESS: - break; - case ANASTASIS_KSD_PAYMENT_REQUIRED: - { - struct ANASTASIS_ChallengeStartResponse csr = { - .cs = ANASTASIS_CHALLENGE_STATUS_PAYMENT_REQUIRED, - .challenge = c, - .details.payment_required.taler_pay_uri - = dd->details.payment_required.taler_pay_uri, - .details.payment_required.payment_secret - = dd->details.payment_required.payment_secret - }; - - c->af (c->af_cls, - &csr); - return; - } - case ANASTASIS_KSD_INVALID_ANSWER: - { - struct ANASTASIS_ChallengeStartResponse csr = { - .cs = ANASTASIS_CHALLENGE_STATUS_INSTRUCTIONS, - .challenge = c, - .details.open_challenge.body - = dd->details.open_challenge.body, - .details.open_challenge.content_type - = dd->details.open_challenge.content_type, - .details.open_challenge.body_size - = dd->details.open_challenge.body_size, - .details.open_challenge.http_status - = dd->details.open_challenge.http_status - }; - - c->af (c->af_cls, - &csr); - return; - } - case ANASTASIS_KSD_REDIRECT_FOR_AUTHENTICATION: - { - struct ANASTASIS_ChallengeStartResponse csr = { - .cs = ANASTASIS_CHALLENGE_STATUS_REDIRECT_FOR_AUTHENTICATION, - .challenge = c, - .details.redirect_url - = dd->details.redirect_url - }; - - c->af (c->af_cls, - &csr); - return; - } - case ANASTASIS_KSD_TRUTH_UNKNOWN: + case MHD_HTTP_OK: + switch (tcd->details.success.cs) { - struct ANASTASIS_ChallengeStartResponse csr = { - .cs = ANASTASIS_CHALLENGE_STATUS_TRUTH_UNKNOWN, - .challenge = c - }; - - c->af (c->af_cls, - &csr); - return; + case ANASTASIS_CS_FILE_WRITTEN: + csr.cs = ANASTASIS_CHALLENGE_START_STATUS_FILENAME_PROVIDED; + csr.details.tan_filename + = tcd->details.success.details.challenge_filename; + break; + case ANASTASIS_CS_TAN_SENT: + csr.cs = ANASTASIS_CHALLENGE_START_STATUS_TAN_SENT_HINT_PROVIDED; + csr.details.tan_address_hint + = tcd->details.success.details.tan_address_hint; + break; + case ANASTASIS_CS_WIRE_FUNDS: + csr.cs = ANASTASIS_CHALLENGE_START_STATUS_BANK_TRANSFER_REQUIRED; + csr.details.bank_transfer_required + = tcd->details.success.details.wire_funds; + break; } - case ANASTASIS_KSD_RATE_LIMIT_EXCEEDED: - { - struct ANASTASIS_ChallengeStartResponse csr = { - .cs = ANASTASIS_CHALLENGE_STATUS_RATE_LIMIT_EXCEEDED, - .challenge = c, - .details.rate_limit_exceeded.request_limit - = dd->details.rate_limit_exceeded.request_limit, - .details.rate_limit_exceeded.request_frequency - = dd->details.rate_limit_exceeded.request_frequency - }; + break; + case MHD_HTTP_PAYMENT_REQUIRED: + csr.cs = ANASTASIS_CHALLENGE_START_STATUS_PAYMENT_REQUIRED; + csr.details.payment_required.taler_pay_uri + = tcd->details.payment_required.payment_request; + csr.details.payment_required.payment_secret + = tcd->details.payment_required.ps; + break; + case MHD_HTTP_NOT_FOUND: + csr.cs = ANASTASIS_CHALLENGE_START_STATUS_TRUTH_UNKNOWN; + break; + default: + csr.cs = ANASTASIS_CHALLENGE_START_STATUS_SERVER_FAILURE; + break; + } + c->csf (c->csf_cls, + &csr); +} - c->af (c->af_cls, - &csr); - return; - } - case ANASTASIS_KSD_SERVER_ERROR: - case ANASTASIS_KSD_CLIENT_FAILURE: - { - struct ANASTASIS_ChallengeStartResponse csr = { - .cs = ANASTASIS_CHALLENGE_STATUS_SERVER_FAILURE, - .challenge = c, - .details.server_failure.ec - = dd->details.server_failure.ec, - .details.server_failure.http_status - = dd->details.server_failure.http_status - }; - c->af (c->af_cls, - &csr); - return; - } - case ANASTASIS_KSD_AUTHENTICATION_TIMEOUT: - { - struct ANASTASIS_ChallengeStartResponse csr = { - .cs = ANASTASIS_CHALLENGE_STATUS_AUTH_TIMEOUT, - .challenge = c, - .details.server_failure.ec - = dd->details.server_failure.ec, - .details.server_failure.http_status - = dd->details.server_failure.http_status - }; +/** + * Function called with the results of a #ANASTASIS_truth_solve(). + * + * @param cls closure + * @param tsr details about the solution response + */ +static void +truth_solve_cb (void *cls, + const struct ANASTASIS_TruthSolveReply *tsr) +{ + struct ANASTASIS_Challenge *c = cls; + struct ANASTASIS_Recovery *recovery = c->recovery; + struct ANASTASIS_CRYPTO_UserIdentifierP id; + struct DecryptionPolicy *rdps; + struct ANASTASIS_ChallengeAnswerResponse csr = { + .challenge = c, + .ec = tsr->ec, + .http_status = tsr->http_status + }; - c->ci.async = true; - c->af (c->af_cls, - &csr); - return; - } - case ANASTASIS_KSD_EXTERNAL_CHALLENGE_INSTRUCTIONS: - { - struct ANASTASIS_ChallengeStartResponse csr = { - .cs = ANASTASIS_CHALLENGE_STATUS_EXTERNAL_INSTRUCTIONS, - .challenge = c, - .details.external_challenge = dd->details.external_challenge - }; - c->af (c->af_cls, - &csr); - return; - } + c->tso = NULL; + switch (tsr->http_status) + { + case MHD_HTTP_OK: + break; + case MHD_HTTP_PAYMENT_REQUIRED: + csr.cs = ANASTASIS_CHALLENGE_ANSWER_STATUS_PAYMENT_REQUIRED; + csr.details.payment_required.taler_pay_uri + = tsr->details.payment_required.payment_request; + csr.details.payment_required.payment_secret + = tsr->details.payment_required.ps; + c->af (c->af_cls, + &csr); + return; + case MHD_HTTP_FORBIDDEN: + csr.cs = ANASTASIS_CHALLENGE_ANSWER_STATUS_INVALID_ANSWER; + c->af (c->af_cls, + &csr); + return; + case MHD_HTTP_NOT_FOUND: + csr.cs = ANASTASIS_CHALLENGE_ANSWER_STATUS_TRUTH_UNKNOWN; + c->af (c->af_cls, + &csr); + return; + case MHD_HTTP_TOO_MANY_REQUESTS: + csr.cs = ANASTASIS_CHALLENGE_ANSWER_STATUS_RATE_LIMIT_EXCEEDED; + csr.details.rate_limit_exceeded.request_limit + = tsr->details.too_many_requests.request_limit; + csr.details.rate_limit_exceeded.request_frequency + = tsr->details.too_many_requests.request_frequency; + c->af (c->af_cls, + &csr); + return; + default: + csr.cs = ANASTASIS_CHALLENGE_ANSWER_STATUS_SERVER_FAILURE; + c->af (c->af_cls, + &csr); + return; } - GNUNET_assert (NULL != dd); ANASTASIS_CRYPTO_user_identifier_derive (recovery->id_data, &c->provider_salt, &id); - ANASTASIS_CRYPTO_keyshare_decrypt (&dd->details.eks, + ANASTASIS_CRYPTO_keyshare_decrypt (&tsr->details.success.eks, &id, c->answer, &c->key_share); recovery->solved_challenges[recovery->solved_challenge_pos++] = c; - - { - struct ANASTASIS_ChallengeStartResponse csr = { - .cs = ANASTASIS_CHALLENGE_STATUS_SOLVED, - .challenge = c - }; - - c->ci.solved = true; - c->af (c->af_cls, - &csr); - } - + c->ci.solved = true; + csr.cs = ANASTASIS_CHALLENGE_ANSWER_STATUS_SOLVED; + c->af (c->af_cls, + &csr); /* Check if there is a policy for which all challenges have been satisfied, if so, store it in 'rdps'. */ @@ -477,33 +465,67 @@ ANASTASIS_challenge_get_details (struct ANASTASIS_Challenge *challenge) enum GNUNET_GenericReturnValue ANASTASIS_challenge_start (struct ANASTASIS_Challenge *c, const struct ANASTASIS_PaymentSecretP *psp, - struct GNUNET_TIME_Relative timeout, - const struct GNUNET_HashCode *hashed_answer, - ANASTASIS_AnswerFeedback af, - void *af_cls) + ANASTASIS_ChallengeStartFeedback csf, + void *csf_cls) { if (c->ci.solved) { GNUNET_break (0); return GNUNET_NO; /* already solved */ } - if (NULL != c->kslo) + if (NULL != c->tco) + { + GNUNET_break (0); + return GNUNET_NO; /* already solving */ + } + c->csf = csf; + c->csf_cls = csf_cls; + c->tco = ANASTASIS_truth_challenge (c->recovery->ctx, + c->url, + &c->ci.uuid, + &c->truth_key, + psp, + &truth_challenge_cb, + c); + if (NULL == c->tco) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +enum GNUNET_GenericReturnValue +ANASTASIS_challenge_answer3 (struct ANASTASIS_Challenge *c, + const struct ANASTASIS_PaymentSecretP *psp, + struct GNUNET_TIME_Relative timeout, + const struct GNUNET_HashCode *hashed_answer, + ANASTASIS_AnswerFeedback af, + void *af_cls) +{ + if (c->ci.solved) + { + GNUNET_break (0); + return GNUNET_NO; /* already solved */ + } + if (NULL != c->tso) { GNUNET_break (0); return GNUNET_NO; /* already solving */ } c->af = af; c->af_cls = af_cls; - c->kslo = ANASTASIS_keyshare_lookup (c->recovery->ctx, - c->url, - &c->ci.uuid, - &c->truth_key, - psp, - timeout, - hashed_answer, - &keyshare_lookup_cb, - c); - if (NULL == c->kslo) + c->tso = ANASTASIS_truth_solve (c->recovery->ctx, + c->url, + &c->ci.uuid, + &c->truth_key, + psp, + timeout, + hashed_answer, + &truth_solve_cb, + c); + if (NULL == c->tso) { GNUNET_break (0); return GNUNET_SYSERR; @@ -529,12 +551,12 @@ ANASTASIS_challenge_answer ( &c->ci.uuid, &c->salt, &hashed_answer); - return ANASTASIS_challenge_start (c, - psp, - timeout, - &hashed_answer, - af, - af_cls); + return ANASTASIS_challenge_answer3 (c, + psp, + timeout, + &hashed_answer, + af, + af_cls); } @@ -550,25 +572,28 @@ ANASTASIS_challenge_answer2 (struct ANASTASIS_Challenge *c, ANASTASIS_hash_answer (answer, &answer_s); - return ANASTASIS_challenge_start (c, - psp, - timeout, - &answer_s, - af, - af_cls); + return ANASTASIS_challenge_answer3 (c, + psp, + timeout, + &answer_s, + af, + af_cls); } void ANASTASIS_challenge_abort (struct ANASTASIS_Challenge *c) { - if (NULL == c->kslo) + if (NULL != c->tso) { - GNUNET_break (0); - return; + ANASTASIS_truth_solve_cancel (c->tso); + c->tso = NULL; + } + if (NULL != c->tco) + { + ANASTASIS_truth_challenge_cancel (c->tco); + c->tco = NULL; } - ANASTASIS_keyshare_lookup_cancel (c->kslo); - c->kslo = NULL; c->af = NULL; c->af_cls = NULL; } @@ -1461,10 +1486,10 @@ ANASTASIS_recovery_abort (struct ANASTASIS_Recovery *r) { struct ANASTASIS_Challenge *cs = &r->cs[i]; - if (NULL != cs->kslo) + if (NULL != cs->tso) { - ANASTASIS_keyshare_lookup_cancel (cs->kslo); - cs->kslo = NULL; + ANASTASIS_truth_solve_cancel (cs->tso); + cs->tso = NULL; } GNUNET_free (cs->url); GNUNET_free (cs->type); |