REST/NAMESTORE: rework API
[oweals/gnunet.git] / src / reclaim / json_reclaim.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009-2018 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21 /**
22  * @file rest-plugins/json_reclaim.c
23  * @brief JSON handling of reclaim data
24  * @author Martin Schanzenbach
25  */
26 #include "platform.h"
27
28 #include "gnunet_util_lib.h"
29
30 #include "gnunet_json_lib.h"
31 #include "gnunet_reclaim_attribute_lib.h"
32 #include "gnunet_reclaim_service.h"
33
34
35 /**
36  * Parse given JSON object to a claim
37  *
38  * @param cls closure, NULL
39  * @param root the json object representing data
40  * @param spec where to write the data
41  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
42  */
43 static int
44 parse_attr (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
45 {
46   struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
47   const char *name_str = NULL;
48   const char *val_str = NULL;
49   const char *type_str = NULL;
50   const char *id_str = NULL;
51   char *data;
52   int unpack_state;
53   uint32_t type;
54   size_t data_size;
55
56   GNUNET_assert (NULL != root);
57
58   if (!json_is_object (root)) {
59     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
60                 "Error json is not array nor object!\n");
61     return GNUNET_SYSERR;
62   }
63   // interpret single attribute
64   unpack_state =
65       json_unpack (root, "{s:s, s?s, s:s, s:s!}", "name", &name_str, "id",
66                    &id_str, "type", &type_str, "value", &val_str);
67   if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) ||
68       (NULL == type_str)) {
69     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
70                 "Error json object has a wrong format!\n");
71     return GNUNET_SYSERR;
72   }
73   type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str);
74   if (GNUNET_SYSERR == (GNUNET_RECLAIM_ATTRIBUTE_string_to_value (
75                            type, val_str, (void **)&data, &data_size))) {
76     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attribute value invalid!\n");
77     return GNUNET_SYSERR;
78   }
79   attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (name_str, type, data, data_size);
80   if ((NULL == id_str) || (0 == strlen (id_str)))
81     attr->id = 0;
82   else
83     GNUNET_STRINGS_string_to_data (id_str, strlen (id_str), &attr->id,
84                                    sizeof (uint64_t));
85
86   *(struct GNUNET_RECLAIM_ATTRIBUTE_Claim **)spec->ptr = attr;
87   return GNUNET_OK;
88 }
89
90 /**
91  * Cleanup data left from parsing RSA public key.
92  *
93  * @param cls closure, NULL
94  * @param[out] spec where to free the data
95  */
96 static void
97 clean_attr (void *cls, struct GNUNET_JSON_Specification *spec)
98 {
99   struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr;
100   attr = (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **)spec->ptr;
101   if (NULL != *attr) {
102     GNUNET_free (*attr);
103     *attr = NULL;
104   }
105 }
106
107 /**
108  * JSON Specification for Reclaim claims.
109  *
110  * @param ticket struct of GNUNET_RECLAIM_ATTRIBUTE_Claim to fill
111  * @return JSON Specification
112  */
113 struct GNUNET_JSON_Specification
114 GNUNET_RECLAIM_JSON_spec_claim (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr)
115 {
116   struct GNUNET_JSON_Specification ret = {.parser = &parse_attr,
117                                           .cleaner = &clean_attr,
118                                           .cls = NULL,
119                                           .field = NULL,
120                                           .ptr = attr,
121                                           .ptr_size = 0,
122                                           .size_ptr = NULL};
123   *attr = NULL;
124   return ret;
125 }
126 /**
127  * Parse given JSON object to a ticket
128  *
129  * @param cls closure, NULL
130  * @param root the json object representing data
131  * @param spec where to write the data
132  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
133  */
134 static int
135 parse_ticket (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
136 {
137   struct GNUNET_RECLAIM_Ticket *ticket;
138   const char *rnd_str;
139   const char *aud_str;
140   const char *id_str;
141   int unpack_state;
142
143   GNUNET_assert (NULL != root);
144
145   if (!json_is_object (root)) {
146     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
147                 "Error json is not array nor object!\n");
148     return GNUNET_SYSERR;
149   }
150   // interpret single ticket
151   unpack_state = json_unpack (root, "{s:s, s:s, s:s!}", "rnd", &rnd_str,
152                               "audience", &aud_str, "identity", &id_str);
153   if (0 != unpack_state) {
154     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
155                 "Error json object has a wrong format!\n");
156     return GNUNET_SYSERR;
157   }
158   ticket = GNUNET_new (struct GNUNET_RECLAIM_Ticket);
159   if (GNUNET_OK != GNUNET_STRINGS_string_to_data (rnd_str, strlen (rnd_str),
160                                                   &ticket->rnd,
161                                                   sizeof (uint64_t))) {
162     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Rnd invalid\n");
163     GNUNET_free (ticket);
164     return GNUNET_SYSERR;
165   }
166   GNUNET_STRINGS_string_to_data (id_str, strlen (id_str), &ticket->identity,
167                                  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
168   {
169     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Identity invalid\n");
170     GNUNET_free (ticket);
171     return GNUNET_SYSERR;
172   }
173
174   GNUNET_STRINGS_string_to_data (aud_str, strlen (aud_str), &ticket->audience,
175                                  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
176   {
177     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Audience invalid\n");
178     GNUNET_free (ticket);
179     return GNUNET_SYSERR;
180   }
181
182   *(struct GNUNET_RECLAIM_Ticket **)spec->ptr = ticket;
183   return GNUNET_OK;
184 }
185
186 /**
187  * Cleanup data left from parsing RSA public key.
188  *
189  * @param cls closure, NULL
190  * @param[out] spec where to free the data
191  */
192 static void
193 clean_ticket (void *cls, struct GNUNET_JSON_Specification *spec)
194 {
195   struct GNUNET_RECLAIM_Ticket **ticket;
196   ticket = (struct GNUNET_RECLAIM_Ticket **)spec->ptr;
197   if (NULL != *ticket) {
198     GNUNET_free (*ticket);
199     *ticket = NULL;
200   }
201 }
202
203 /**
204  * JSON Specification for Reclaim tickets.
205  *
206  * @param ticket struct of GNUNET_RECLAIM_Ticket to fill
207  * @return JSON Specification
208  */
209 struct GNUNET_JSON_Specification
210 GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket)
211 {
212   struct GNUNET_JSON_Specification ret = {.parser = &parse_ticket,
213                                           .cleaner = &clean_ticket,
214                                           .cls = NULL,
215                                           .field = NULL,
216                                           .ptr = ticket,
217                                           .ptr_size = 0,
218                                           .size_ptr = NULL};
219   *ticket = NULL;
220   return ret;
221 }