add changelog
[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   {
60     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
61                 "Error json is not array nor object!\n");
62     return GNUNET_SYSERR;
63   }
64   // interpret single attribute
65   unpack_state = json_unpack (root,
66                               "{s:s, s?s, s:s, s:s!}",
67                               "name",
68                               &name_str,
69                               "id",
70                               &id_str,
71                               "type",
72                               &type_str,
73                               "value",
74                               &val_str);
75   if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) ||
76       (NULL == type_str))
77   {
78     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
79                 "Error json object has a wrong format!\n");
80     return GNUNET_SYSERR;
81   }
82   type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str);
83   if (GNUNET_SYSERR ==
84       (GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,
85                                                  val_str,
86                                                  (void **) &data,
87                                                  &data_size)))
88   {
89     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attribute value invalid!\n");
90     return GNUNET_SYSERR;
91   }
92   attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (name_str, type, data, data_size);
93   if ((NULL == id_str) || (0 == strlen (id_str)))
94     attr->id = 0;
95   else
96     GNUNET_STRINGS_string_to_data (id_str,
97                                    strlen (id_str),
98                                    &attr->id,
99                                    sizeof(uint64_t));
100
101   *(struct GNUNET_RECLAIM_ATTRIBUTE_Claim **) spec->ptr = attr;
102   return GNUNET_OK;
103 }
104
105
106 /**
107  * Cleanup data left from parsing RSA public key.
108  *
109  * @param cls closure, NULL
110  * @param[out] spec where to free the data
111  */
112 static void
113 clean_attr (void *cls, struct GNUNET_JSON_Specification *spec)
114 {
115   struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr;
116
117   attr = (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **) spec->ptr;
118   if (NULL != *attr)
119   {
120     GNUNET_free (*attr);
121     *attr = NULL;
122   }
123 }
124
125
126 /**
127  * JSON Specification for Reclaim claims.
128  *
129  * @param ticket struct of GNUNET_RECLAIM_ATTRIBUTE_Claim to fill
130  * @return JSON Specification
131  */
132 struct GNUNET_JSON_Specification
133 GNUNET_RECLAIM_JSON_spec_claim (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr)
134 {
135   struct GNUNET_JSON_Specification ret = { .parser = &parse_attr,
136                                            .cleaner = &clean_attr,
137                                            .cls = NULL,
138                                            .field = NULL,
139                                            .ptr = attr,
140                                            .ptr_size = 0,
141                                            .size_ptr = NULL };
142
143   *attr = NULL;
144   return ret;
145 }
146
147
148 /**
149  * Parse given JSON object to a ticket
150  *
151  * @param cls closure, NULL
152  * @param root the json object representing data
153  * @param spec where to write the data
154  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
155  */
156 static int
157 parse_ticket (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
158 {
159   struct GNUNET_RECLAIM_Ticket *ticket;
160   const char *rnd_str;
161   const char *aud_str;
162   const char *id_str;
163   int unpack_state;
164
165   GNUNET_assert (NULL != root);
166
167   if (! json_is_object (root))
168   {
169     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
170                 "Error json is not array nor object!\n");
171     return GNUNET_SYSERR;
172   }
173   // interpret single ticket
174   unpack_state = json_unpack (root,
175                               "{s:s, s:s, s:s!}",
176                               "rnd",
177                               &rnd_str,
178                               "audience",
179                               &aud_str,
180                               "issuer",
181                               &id_str);
182   if (0 != unpack_state)
183   {
184     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
185                 "Error json object has a wrong format!\n");
186     return GNUNET_SYSERR;
187   }
188   ticket = GNUNET_new (struct GNUNET_RECLAIM_Ticket);
189   if (GNUNET_OK != GNUNET_STRINGS_string_to_data (rnd_str,
190                                                   strlen (rnd_str),
191                                                   &ticket->rnd,
192                                                   sizeof(uint64_t)))
193   {
194     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Rnd invalid\n");
195     GNUNET_free (ticket);
196     return GNUNET_SYSERR;
197   }
198   if (GNUNET_OK !=
199       GNUNET_STRINGS_string_to_data (id_str,
200                                      strlen (id_str),
201                                      &ticket->identity,
202                                      sizeof(
203                                        struct GNUNET_CRYPTO_EcdsaPublicKey)))
204   {
205     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Identity invalid\n");
206     GNUNET_free (ticket);
207     return GNUNET_SYSERR;
208   }
209
210   if (GNUNET_OK !=
211       GNUNET_STRINGS_string_to_data (aud_str,
212                                      strlen (aud_str),
213                                      &ticket->audience,
214                                      sizeof(struct
215                                             GNUNET_CRYPTO_EcdsaPublicKey)))
216   {
217     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Audience invalid\n");
218     GNUNET_free (ticket);
219     return GNUNET_SYSERR;
220   }
221
222   *(struct GNUNET_RECLAIM_Ticket **) spec->ptr = ticket;
223   return GNUNET_OK;
224 }
225
226
227 /**
228  * Cleanup data left from parsing RSA public key.
229  *
230  * @param cls closure, NULL
231  * @param[out] spec where to free the data
232  */
233 static void
234 clean_ticket (void *cls, struct GNUNET_JSON_Specification *spec)
235 {
236   struct GNUNET_RECLAIM_Ticket **ticket;
237
238   ticket = (struct GNUNET_RECLAIM_Ticket **) spec->ptr;
239   if (NULL != *ticket)
240   {
241     GNUNET_free (*ticket);
242     *ticket = NULL;
243   }
244 }
245
246
247 /**
248  * JSON Specification for Reclaim tickets.
249  *
250  * @param ticket struct of GNUNET_RECLAIM_Ticket to fill
251  * @return JSON Specification
252  */
253 struct GNUNET_JSON_Specification
254 GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket)
255 {
256   struct GNUNET_JSON_Specification ret = { .parser = &parse_ticket,
257                                            .cleaner = &clean_ticket,
258                                            .cls = NULL,
259                                            .field = NULL,
260                                            .ptr = ticket,
261                                            .ptr_size = 0,
262                                            .size_ptr = NULL };
263
264   *ticket = NULL;
265   return ret;
266 }