summaryrefslogtreecommitdiff
path: root/src/lib/anastasis_recovery.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/anastasis_recovery.c')
-rw-r--r--src/lib/anastasis_recovery.c211
1 files changed, 117 insertions, 94 deletions
diff --git a/src/lib/anastasis_recovery.c b/src/lib/anastasis_recovery.c
index c9f8c0e..41f35a5 100644
--- a/src/lib/anastasis_recovery.c
+++ b/src/lib/anastasis_recovery.c
@@ -612,23 +612,22 @@ ANASTASIS_challenge_abort (struct ANASTASIS_Challenge *c)
* Function called with the results of a #ANASTASIS_policy_lookup()
*
* @param cls closure
- * @param http_status HTTp status code.
* @param dd details about the lookup operation
*/
static void
policy_lookup_cb (void *cls,
- unsigned int http_status,
const struct ANASTASIS_DownloadDetails *dd)
{
struct ANASTASIS_Recovery *r = cls;
void *plaintext;
size_t size_plaintext;
json_error_t json_error;
- json_t *dec_policies;
- json_t *esc_methods;
+ const json_t *dec_policies;
+ const json_t *esc_methods;
+ json_t *recovery_document;
r->plo = NULL;
- switch (http_status)
+ switch (dd->http_status)
{
case MHD_HTTP_OK:
break;
@@ -660,7 +659,7 @@ policy_lookup_cb (void *cls,
default:
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u in %s:%u\n",
- http_status,
+ dd->http_status,
__FILE__,
__LINE__);
r->csc (r->csc_cls,
@@ -670,7 +669,7 @@ policy_lookup_cb (void *cls,
ANASTASIS_recovery_abort (r);
return;
}
- if (NULL == dd->policy)
+ if (NULL == dd->details.ok.policy)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"No recovery data available");
@@ -682,8 +681,8 @@ policy_lookup_cb (void *cls,
return;
}
ANASTASIS_CRYPTO_recovery_document_decrypt (&r->id,
- dd->policy,
- dd->policy_size,
+ dd->details.ok.policy,
+ dd->details.ok.policy_size,
&plaintext,
&size_plaintext);
if (size_plaintext < sizeof (uint32_t))
@@ -698,7 +697,6 @@ policy_lookup_cb (void *cls,
return;
}
{
- json_t *recovery_document;
uint32_t be_size;
uLongf pt_size;
char *pt;
@@ -761,10 +759,10 @@ policy_lookup_cb (void *cls,
{
const char *secret_name = NULL;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_json ("policies",
- &dec_policies),
- GNUNET_JSON_spec_json ("escrow_methods",
- &esc_methods),
+ GNUNET_JSON_spec_array_const ("policies",
+ &dec_policies),
+ GNUNET_JSON_spec_array_const ("escrow_methods",
+ &esc_methods),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("secret_name",
&secret_name),
@@ -784,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,22 +795,39 @@ policy_lookup_cb (void *cls,
r->ri.secret_name = r->secret_name;
}
}
- json_decref (recovery_document);
}
- r->ri.version = dd->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);
+ 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
+ = (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];
@@ -824,7 +837,7 @@ policy_lookup_cb (void *cls,
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("uuid",
&cs->ci.uuid),
- GNUNET_JSON_spec_string ("url",
+ TALER_JSON_spec_web_url ("url",
&url),
GNUNET_JSON_spec_string ("instructions",
&instructions),
@@ -848,14 +861,11 @@ policy_lookup_cb (void *cls,
NULL, NULL))
{
GNUNET_break_op (0);
- json_decref (esc_methods);
- json_decref (dec_policies);
r->csc (r->csc_cls,
ANASTASIS_RS_POLICY_MALFORMED_JSON,
NULL,
0);
- ANASTASIS_recovery_abort (r);
- return;
+ goto cleanup;
}
cs->url = GNUNET_strdup (url);
cs->type = GNUNET_strdup (escrow_type);
@@ -864,13 +874,11 @@ policy_lookup_cb (void *cls,
cs->instructions = GNUNET_strdup (instructions);
cs->ci.instructions = cs->instructions;
}
- json_decref (esc_methods);
for (unsigned int j = 0; j < r->ri.dps_len; j++)
{
struct DecryptionPolicy *dp = &r->dps[j];
-
- json_t *uuids = NULL;
+ const json_t *uuids;
json_t *uuid;
size_t n_index;
struct GNUNET_JSON_Specification spec[] = {
@@ -879,34 +887,40 @@ policy_lookup_cb (void *cls,
&dp->emk_size),
GNUNET_JSON_spec_fixed_auto ("master_salt",
&dp->master_salt),
- GNUNET_JSON_spec_json ("uuids",
- &uuids),
+ GNUNET_JSON_spec_array_const ("uuids",
+ &uuids),
GNUNET_JSON_spec_end ()
};
r->ri.dps[j] = &r->dps[j].pub_details;
- if ( (GNUNET_OK !=
- GNUNET_JSON_parse (json_array_get (dec_policies,
- j),
- spec,
- NULL, NULL)) ||
- (! json_is_array (uuids)) )
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (json_array_get (dec_policies,
+ j),
+ spec,
+ NULL, NULL))
{
GNUNET_break_op (0);
- json_decref (uuids);
- json_decref (dec_policies);
r->csc (r->csc_cls,
ANASTASIS_RS_POLICY_MALFORMED_JSON,
NULL,
0);
- ANASTASIS_recovery_abort (r);
- 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 *);
@@ -925,14 +939,11 @@ policy_lookup_cb (void *cls,
sizeof (uuid))) )
{
GNUNET_break_op (0);
- json_decref (dec_policies);
- json_decref (uuids);
r->csc (r->csc_cls,
ANASTASIS_RS_POLICY_MALFORMED_JSON,
NULL,
0);
- ANASTASIS_recovery_abort (r);
- return;
+ goto cleanup;
}
for (unsigned int i = 0; i<r->ri.cs_len; i++)
{
@@ -947,21 +958,21 @@ policy_lookup_cb (void *cls,
if (! found)
{
GNUNET_break_op (0);
- json_decref (dec_policies);
- json_decref (uuids);
r->csc (r->csc_cls,
ANASTASIS_RS_POLICY_MALFORMED_JSON,
NULL,
0);
- ANASTASIS_recovery_abort (r);
- return;
+ goto cleanup;
}
}
- json_decref (uuids);
}
- json_decref (dec_policies);
r->pc (r->pc_cls,
&r->ri);
+ json_decref (recovery_document);
+ return;
+cleanup:
+ ANASTASIS_recovery_abort (r);
+ json_decref (recovery_document);
}
@@ -1134,19 +1145,26 @@ ANASTASIS_recovery_serialize (const struct ANASTASIS_Recovery *r)
*/
static enum GNUNET_GenericReturnValue
parse_cs_array (struct ANASTASIS_Recovery *r,
- json_t *cs_arr)
+ 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,
@@ -1161,7 +1179,7 @@ parse_cs_array (struct ANASTASIS_Recovery *r,
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("uuid",
&c->ci.uuid),
- GNUNET_JSON_spec_string ("url",
+ TALER_JSON_spec_web_url ("url",
&url),
GNUNET_JSON_spec_string ("instructions",
&instructions),
@@ -1220,17 +1238,23 @@ parse_cs_array (struct ANASTASIS_Recovery *r,
*/
static enum GNUNET_GenericReturnValue
parse_dps_array (struct ANASTASIS_Recovery *r,
- json_t *dps_arr)
+ 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,
@@ -1239,15 +1263,15 @@ parse_dps_array (struct ANASTASIS_Recovery *r,
json_array_foreach (dps_arr, n_index, dps)
{
struct DecryptionPolicy *dp = &r->dps[n_index];
- json_t *challenges;
+ const json_t *challenges;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_varsize ("encrypted_master_key",
&dp->emk,
&dp->emk_size),
GNUNET_JSON_spec_fixed_auto ("master_salt",
&dp->master_salt),
- GNUNET_JSON_spec_json ("challenges",
- &challenges),
+ GNUNET_JSON_spec_array_const ("challenges",
+ &challenges),
GNUNET_JSON_spec_end ()
};
const char *err_json_name;
@@ -1270,20 +1294,20 @@ parse_dps_array (struct ANASTASIS_Recovery *r,
}
GNUNET_assert (NULL != dp->emk);
GNUNET_assert (dp->emk_size > 0);
- if (! json_is_array (challenges))
+ if (json_array_size (challenges) > UINT_MAX)
{
GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
- dp->pub_details.challenges_length = json_array_size (challenges);
- dp->pub_details.challenges = GNUNET_new_array (
- dp->pub_details.challenges_length,
- struct ANASTASIS_Challenge *);
+ 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;
@@ -1320,8 +1344,7 @@ parse_dps_array (struct ANASTASIS_Recovery *r,
}
}
}
- /* We don't free the spec, since we're still using dp->ems. */
- json_decref (challenges);
+ /* Do NOT free the spec: we are still using dp->ems. */
}
return GNUNET_OK;
}
@@ -1363,9 +1386,9 @@ ANASTASIS_recovery_deserialize (struct GNUNET_CURL_Context *ctx,
const char *err_json_name;
unsigned int err_line;
uint32_t version;
- json_t *dps_arr;
- json_t *cs_arr;
- json_t *id_data;
+ const json_t *dps_arr;
+ const json_t *cs_arr;
+ const json_t *id_data;
const char *provider_url;
const char *secret_name;
void *ecs;
@@ -1373,7 +1396,7 @@ ANASTASIS_recovery_deserialize (struct GNUNET_CURL_Context *ctx,
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("id",
&r->id),
- GNUNET_JSON_spec_string ("provider_url",
+ TALER_JSON_spec_web_url ("provider_url",
&provider_url),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("secret_name",
@@ -1381,12 +1404,12 @@ ANASTASIS_recovery_deserialize (struct GNUNET_CURL_Context *ctx,
NULL),
GNUNET_JSON_spec_uint32 ("version",
&version),
- GNUNET_JSON_spec_json ("decryption_policies",
- &dps_arr),
- GNUNET_JSON_spec_json ("challenges",
- &cs_arr),
- GNUNET_JSON_spec_json ("id_data",
- &id_data),
+ GNUNET_JSON_spec_array_const ("decryption_policies",
+ &dps_arr),
+ GNUNET_JSON_spec_array_const ("challenges",
+ &cs_arr),
+ GNUNET_JSON_spec_object_const ("id_data",
+ &id_data),
GNUNET_JSON_spec_varsize ("encrypted_core_secret",
&ecs,
&ecs_size),
@@ -1420,7 +1443,7 @@ ANASTASIS_recovery_deserialize (struct GNUNET_CURL_Context *ctx,
GNUNET_JSON_parse_free (spec);
return NULL;
}
- r->id_data = json_incref (id_data);
+ r->id_data = json_incref ((json_t *) id_data);
r->provider_url = GNUNET_strdup (provider_url);
if (NULL != secret_name)
r->secret_name = GNUNET_strdup (secret_name);