/* This file is part of GNUnet. Copyright (C) 2009-2018 GNUnet e.V. GNUnet is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . SPDX-License-Identifier: AGPL3.0-or-later */ /** * @file rest-plugins/json_reclaim.c * @brief JSON handling of reclaim data * @author Martin Schanzenbach */ #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_json_lib.h" #include "gnunet_reclaim_service.h" #include "gnunet_reclaim_attribute_lib.h" /** * Parse given JSON object to a claim * * @param cls closure, NULL * @param root the json object representing data * @param spec where to write the data * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error */ static int parse_attr (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec) { struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr; const char* name_str; const char* val_str; const char* type_str; char *data; int unpack_state; uint32_t type; size_t data_size; GNUNET_assert(NULL != root); if(!json_is_object(root)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error json is not array nor object!\n"); return GNUNET_SYSERR; } //interpret single attribute unpack_state = json_unpack(root, "{s:s, s:s, s:s!}", "name", &name_str, "type", &type_str, "value", &val_str); if (0 != unpack_state) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Error json object has a wrong format!\n"); return GNUNET_SYSERR; } type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str); if (GNUNET_SYSERR == (GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type, val_str, (void**)&data, &data_size))) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Attribute value invalid!\n"); return GNUNET_SYSERR; } attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (name_str, type, data, data_size); *(struct GNUNET_RECLAIM_ATTRIBUTE_Claim **) spec->ptr = attr; return GNUNET_OK; } /** * Cleanup data left from parsing RSA public key. * * @param cls closure, NULL * @param[out] spec where to free the data */ static void clean_attr (void *cls, struct GNUNET_JSON_Specification *spec) { struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr; attr = (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **) spec->ptr; if (NULL != *attr) { GNUNET_free(*attr); *attr = NULL; } } /** * JSON Specification for Reclaim claims. * * @param ticket struct of GNUNET_RECLAIM_ATTRIBUTE_Claim to fill * @return JSON Specification */ struct GNUNET_JSON_Specification GNUNET_RECLAIM_JSON_spec_claim (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr) { struct GNUNET_JSON_Specification ret = { .parser = &parse_attr, .cleaner = &clean_attr, .cls = NULL, .field = NULL, .ptr = attr, .ptr_size = 0, .size_ptr = NULL }; *attr = NULL; return ret; } /** * Parse given JSON object to a ticket * * @param cls closure, NULL * @param root the json object representing data * @param spec where to write the data * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error */ static int parse_ticket (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec) { struct GNUNET_RECLAIM_Ticket *ticket; const char* rnd_str; const char* aud_str; const char* id_str; int unpack_state; GNUNET_assert(NULL != root); if(!json_is_object(root)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error json is not array nor object!\n"); return GNUNET_SYSERR; } //interpret single ticket unpack_state = json_unpack(root, "{s:s, s:s, s:s!}", "rnd", &rnd_str, "audience", &aud_str, "identity", &id_str); if (0 != unpack_state) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Error json object has a wrong format!\n"); return GNUNET_SYSERR; } ticket = GNUNET_new (struct GNUNET_RECLAIM_Ticket); if (GNUNET_OK != GNUNET_STRINGS_string_to_data (rnd_str, strlen (rnd_str), &ticket->rnd, sizeof (uint64_t))) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Rnd invalid\n"); GNUNET_free(ticket); return GNUNET_SYSERR; } GNUNET_STRINGS_string_to_data (id_str, strlen (id_str), &ticket->identity, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Identity invalid\n"); GNUNET_free(ticket); return GNUNET_SYSERR; } GNUNET_STRINGS_string_to_data (aud_str, strlen (aud_str), &ticket->audience, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Audience invalid\n"); GNUNET_free(ticket); return GNUNET_SYSERR; } *(struct GNUNET_RECLAIM_Ticket **) spec->ptr = ticket; return GNUNET_OK; } /** * Cleanup data left from parsing RSA public key. * * @param cls closure, NULL * @param[out] spec where to free the data */ static void clean_ticket (void *cls, struct GNUNET_JSON_Specification *spec) { struct GNUNET_RECLAIM_Ticket **ticket; ticket = (struct GNUNET_RECLAIM_Ticket **) spec->ptr; if (NULL != *ticket) { GNUNET_free(*ticket); *ticket = NULL; } } /** * JSON Specification for Reclaim tickets. * * @param ticket struct of GNUNET_RECLAIM_Ticket to fill * @return JSON Specification */ struct GNUNET_JSON_Specification GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket) { struct GNUNET_JSON_Specification ret = { .parser = &parse_ticket, .cleaner = &clean_ticket, .cls = NULL, .field = NULL, .ptr = ticket, .ptr_size = 0, .size_ptr = NULL }; *ticket = NULL; return ret; }