anastasis

Credential backup and recovery protocol and service
Log | Files | Refs | Submodules | README | LICENSE

commit 75695e6416dce7f4eb2ba42d78e87e7f79e41c51
parent e0175bb4e1f0980deeffc24f575210c40ca0e2c3
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun, 21 Apr 2024 09:28:33 +0200

fix #8659 in anastasis.git

Diffstat:
Msrc/authorization/libanastasiseufin/lae_credit.c | 2+-
Msrc/lib/anastasis_recovery.c | 119+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/reducer/anastasis_api_backup_redux.c | 32++++++++++++++++++++++++--------
Msrc/restclient/anastasis_api_config.c | 15+++++++++++----
4 files changed, 116 insertions(+), 52 deletions(-)

diff --git a/src/authorization/libanastasiseufin/lae_credit.c b/src/authorization/libanastasiseufin/lae_credit.c @@ -82,7 +82,7 @@ parse_account_history (struct ANASTASIS_EUFIN_CreditHistoryHandle *hh, GNUNET_break_op (0); return GNUNET_SYSERR; } - for (unsigned int i = 0; i<json_array_size (history_array); i++) + for (size_t i = 0; i<json_array_size (history_array); i++) { struct ANASTASIS_EUFIN_CreditDetails td; uint64_t row_id; diff --git a/src/lib/anastasis_recovery.c b/src/lib/anastasis_recovery.c @@ -782,13 +782,11 @@ policy_lookup_cb (void *cls, json_dumpf (recovery_document, stderr, 0); - json_decref (recovery_document); r->csc (r->csc_cls, ANASTASIS_RS_POLICY_MALFORMED_JSON, NULL, 0); - ANASTASIS_recovery_abort (r); - return; + goto cleanup; } if (NULL != secret_name) { @@ -799,19 +797,37 @@ policy_lookup_cb (void *cls, } } + if ( (json_array_size (esc_methods) > UINT_MAX) || + (json_array_size (dec_policies) > UINT_MAX) ) + { + GNUNET_break_op (0); + r->csc (r->csc_cls, + ANASTASIS_RS_POLICY_DOWNLOAD_TOO_BIG, + NULL, + 0); + goto cleanup; + } + r->ri.version = dd->details.ok.version; - r->ri.cs_len = json_array_size (esc_methods); - r->ri.dps_len = json_array_size (dec_policies); - r->ri.dps = GNUNET_new_array (r->ri.dps_len, - struct ANASTASIS_DecryptionPolicy *); - r->dps = GNUNET_new_array (r->ri.dps_len, - struct DecryptionPolicy); - r->solved_challenges = GNUNET_new_array (r->ri.cs_len, - struct ANASTASIS_Challenge *); - r->ri.cs = GNUNET_new_array (r->ri.cs_len, - struct ANASTASIS_Challenge *); - r->cs = GNUNET_new_array (r->ri.cs_len, - struct ANASTASIS_Challenge); + r->ri.cs_len + = (unsigned int) json_array_size (esc_methods); + r->ri.dps_len + = (unsigned int) json_array_size (dec_policies); + r->ri.dps + = GNUNET_new_array (r->ri.dps_len, + struct ANASTASIS_DecryptionPolicy *); + r->dps + = GNUNET_new_array (r->ri.dps_len, + struct DecryptionPolicy); + r->solved_challenges + = GNUNET_new_array (r->ri.cs_len, + struct ANASTASIS_Challenge *); + r->ri.cs + = GNUNET_new_array (r->ri.cs_len, + struct ANASTASIS_Challenge *); + r->cs + = GNUNET_new_array (r->ri.cs_len, + struct ANASTASIS_Challenge); for (unsigned int i = 0; i < r->ri.cs_len; i++) { struct ANASTASIS_Challenge *cs = &r->cs[i]; @@ -849,9 +865,7 @@ policy_lookup_cb (void *cls, ANASTASIS_RS_POLICY_MALFORMED_JSON, NULL, 0); - ANASTASIS_recovery_abort (r); - json_decref (recovery_document); - return; + goto cleanup; } cs->url = GNUNET_strdup (url); cs->type = GNUNET_strdup (escrow_type); @@ -890,15 +904,23 @@ policy_lookup_cb (void *cls, ANASTASIS_RS_POLICY_MALFORMED_JSON, NULL, 0); - ANASTASIS_recovery_abort (r); - json_decref (recovery_document); - return; + goto cleanup; } GNUNET_assert (NULL != dp->emk); GNUNET_assert (dp->emk_size > 0); - dp->pub_details.challenges_length = json_array_size (uuids); + if (json_array_size (uuids) > UINT_MAX) + { + GNUNET_break_op (0); + r->csc (r->csc_cls, + ANASTASIS_RS_POLICY_MALFORMED_JSON, + NULL, + 0); + goto cleanup; + } + dp->pub_details.challenges_length + = (unsigned int) json_array_size (uuids); dp->pub_details.challenges = GNUNET_new_array (dp->pub_details.challenges_length, struct ANASTASIS_Challenge *); @@ -921,9 +943,7 @@ policy_lookup_cb (void *cls, ANASTASIS_RS_POLICY_MALFORMED_JSON, NULL, 0); - ANASTASIS_recovery_abort (r); - json_decref (recovery_document); - return; + goto cleanup; } for (unsigned int i = 0; i<r->ri.cs_len; i++) { @@ -942,15 +962,17 @@ policy_lookup_cb (void *cls, ANASTASIS_RS_POLICY_MALFORMED_JSON, NULL, 0); - ANASTASIS_recovery_abort (r); - json_decref (recovery_document); - return; + goto cleanup; } } } r->pc (r->pc_cls, &r->ri); json_decref (recovery_document); + return; +cleanup: + ANASTASIS_recovery_abort (r); + json_decref (recovery_document); } @@ -1126,16 +1148,23 @@ parse_cs_array (struct ANASTASIS_Recovery *r, const json_t *cs_arr) { json_t *cs; - unsigned int n_index; + size_t n_index; if (! json_is_array (cs_arr)) { GNUNET_break_op (0); return GNUNET_SYSERR; } - r->ri.cs_len = json_array_size (cs_arr); - r->solved_challenges = GNUNET_new_array (r->ri.cs_len, - struct ANASTASIS_Challenge *); + if (json_array_size (cs_arr) > UINT_MAX) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + r->ri.cs_len + = (unsigned int) json_array_size (cs_arr); + r->solved_challenges + = GNUNET_new_array (r->ri.cs_len, + struct ANASTASIS_Challenge *); r->ri.cs = GNUNET_new_array (r->ri.cs_len, struct ANASTASIS_Challenge *); r->cs = GNUNET_new_array (r->ri.cs_len, @@ -1212,14 +1241,20 @@ parse_dps_array (struct ANASTASIS_Recovery *r, const json_t *dps_arr) { json_t *dps; - unsigned int n_index; + size_t n_index; if (! json_is_array (dps_arr)) { GNUNET_break_op (0); return GNUNET_SYSERR; } - r->ri.dps_len = json_array_size (dps_arr); + if (json_array_size (dps_arr) > UINT_MAX) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + r->ri.dps_len + = (unsigned int) json_array_size (dps_arr); r->dps = GNUNET_new_array (r->ri.dps_len, struct DecryptionPolicy); r->ri.dps = GNUNET_new_array (r->ri.dps_len, @@ -1259,14 +1294,20 @@ parse_dps_array (struct ANASTASIS_Recovery *r, } GNUNET_assert (NULL != dp->emk); GNUNET_assert (dp->emk_size > 0); - dp->pub_details.challenges_length = json_array_size (challenges); - dp->pub_details.challenges = GNUNET_new_array ( - dp->pub_details.challenges_length, - struct ANASTASIS_Challenge *); + if (json_array_size (challenges) > UINT_MAX) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + dp->pub_details.challenges_length + = (unsigned int) json_array_size (challenges); + dp->pub_details.challenges + = GNUNET_new_array (dp->pub_details.challenges_length, + struct ANASTASIS_Challenge *); { json_t *challenge; - unsigned int c_index; + size_t c_index; json_array_foreach (challenges, c_index, challenge) { struct ANASTASIS_CRYPTO_TruthUUIDP uuid; diff --git a/src/reducer/anastasis_api_backup_redux.c b/src/reducer/anastasis_api_backup_redux.c @@ -32,7 +32,7 @@ * anastasis-httpd.h. */ #define ANASTASIS_FREE_STORAGE GNUNET_TIME_relative_multiply ( \ - GNUNET_TIME_UNIT_YEARS, 5) + GNUNET_TIME_UNIT_YEARS, 5) /** * CPU limiter: do not evaluate more than 16k @@ -1665,7 +1665,8 @@ done_authentication (json_t *state, pb.methods = json_object_get (state, "authentication_methods"); if ( (NULL == pb.methods) || - (! json_is_array (pb.methods)) ) + (! json_is_array (pb.methods)) || + (json_array_size (pb.methods) > UINT_MAX) ) { ANASTASIS_redux_fail_ (cb, cb_cls, @@ -1673,7 +1674,8 @@ done_authentication (json_t *state, "'authentication_methods' must be provided"); return NULL; } - pb.num_methods = json_array_size (pb.methods); + pb.num_methods + = (unsigned int) json_array_size (pb.methods); switch (pb.num_methods) { case 0: @@ -3036,7 +3038,8 @@ secret_share_result_cb (void *cls, json_array_foreach (providers, off, provider) { const char *purl = json_string_value (json_object_get (provider, - "provider_url")); + "provider_url") + ); if (NULL == purl) { @@ -3194,7 +3197,18 @@ share_secret (struct UploadContext *uc) return; } - pds_len = json_array_size (providers); + if (json_array_size (providers) > UINT_MAX) + { + GNUNET_break_op (0); + ANASTASIS_redux_fail_ (uc->cb, + uc->cb_cls, + TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, + "provider array excessively long"); + upload_cancel_cb (uc); + return; + } + pds_len + = (unsigned int) json_array_size (providers); if (0 == pds_len) { ANASTASIS_redux_fail_ (uc->cb, @@ -3223,17 +3237,19 @@ share_secret (struct UploadContext *uc) unsigned int methods_len; if ( (! json_is_array (jmethods)) || - (0 == json_array_size (jmethods)) ) + (0 == json_array_size (jmethods)) || + (json_array_size (jmethods) > UINT_MAX) ) { GNUNET_break (0); ANASTASIS_redux_fail_ (uc->cb, uc->cb_cls, TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, - "'methods' must be an array"); + "'methods' must be an array of sane length"); upload_cancel_cb (uc); return; } - methods_len = json_array_size (jmethods); + methods_len + = (unsigned int) json_array_size (jmethods); { struct ANASTASIS_Policy *p; struct ANASTASIS_Truth *truths[methods_len]; diff --git a/src/restclient/anastasis_api_config.c b/src/restclient/anastasis_api_config.c @@ -169,11 +169,18 @@ handle_config_finished (void *cls, acfg.ec = TALER_EC_GENERIC_VERSION_MALFORMED; break; } - acfg.details.ok.methods_length = json_array_size (methods); + acfg.details.ok.methods_length = (unsigned int) json_array_size (methods); + if (((size_t) acfg.details.ok.methods_length) != + json_array_size (methods)) { - struct ANASTASIS_AuthorizationMethodConfig mcfg[GNUNET_NZL ( - acfg.details.ok. - methods_length)]; + GNUNET_break_op (0); + acfg.http_status = 0; + acfg.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } + { + struct ANASTASIS_AuthorizationMethodConfig mcfg[ + GNUNET_NZL (acfg.details.ok.methods_length)]; for (unsigned int i = 0; i<acfg.details.ok.methods_length; i++) {