fix
[oweals/gnunet.git] / src / rest-plugins / 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
19 /**
20  * @file rest-plugins/json_reclaim.c
21  * @brief JSON handling of reclaim data
22  * @author Martin Schanzenbach
23  */
24 #include "platform.h"
25 #include "gnunet_util_lib.h"
26 #include "gnunet_json_lib.h"
27 #include "gnunet_reclaim_service.h"
28 #include "gnunet_reclaim_attribute_lib.h"
29
30 /**
31  * Parse given JSON object to a claim
32  *
33  * @param cls closure, NULL
34  * @param root the json object representing data
35  * @param spec where to write the data
36  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
37  */
38 static int
39 parse_attr (void *cls,
40               json_t *root,
41               struct GNUNET_JSON_Specification *spec)
42 {
43   struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
44   const char* name_str;
45   const char* val_str;
46   const char* type_str;
47   char *data;
48   int unpack_state;
49   uint32_t type;
50   size_t data_size;
51
52   GNUNET_assert(NULL != root);
53
54   if(!json_is_object(root))
55   {
56     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
57                 "Error json is not array nor object!\n");
58     return GNUNET_SYSERR;
59   }
60   //interpret single attribute
61   unpack_state = json_unpack(root,
62                              "{s:s, s:s, s:s!}",
63                              "name", &name_str,
64                              "type", &type_str,
65                              "value", &val_str);
66   if (0 != unpack_state)
67   {
68     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
69                "Error json object has a wrong format!\n");
70     return GNUNET_SYSERR;
71   }
72   type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str);
73   if (GNUNET_SYSERR == (GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,
74                                                                   val_str,
75                                                                   (void**)&data,
76                                                                   &data_size)))
77   {
78     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
79                "Attribute value invalid!\n");
80     return GNUNET_SYSERR;
81   }
82   attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (name_str,
83                                              type,
84                                              data,
85                                              data_size);
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   {
103     GNUNET_free(*attr);
104     *attr = NULL;
105   }
106 }
107
108 /**
109  * JSON Specification for Reclaim claims.
110  *
111  * @param ticket struct of GNUNET_RECLAIM_ATTRIBUTE_Claim to fill
112  * @return JSON Specification
113  */
114 struct GNUNET_JSON_Specification
115 GNUNET_RECLAIM_JSON_spec_claim (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr)
116 {
117   struct GNUNET_JSON_Specification ret = {
118     .parser = &parse_attr,
119     .cleaner = &clean_attr,
120     .cls = NULL,
121     .field = NULL,
122     .ptr = attr,
123     .ptr_size = 0,
124     .size_ptr = NULL
125   };
126   *attr = NULL;
127   return ret;
128 }
129 /**
130  * Parse given JSON object to a ticket
131  *
132  * @param cls closure, NULL
133  * @param root the json object representing data
134  * @param spec where to write the data
135  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
136  */
137 static int
138 parse_ticket (void *cls,
139               json_t *root,
140               struct GNUNET_JSON_Specification *spec)
141 {
142   struct GNUNET_RECLAIM_Ticket *ticket;
143   const char* rnd_str;
144   const char* aud_str;
145   const char* id_str;
146   int unpack_state;
147
148   GNUNET_assert(NULL != root);
149
150   if(!json_is_object(root))
151   {
152     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
153                 "Error json is not array nor object!\n");
154     return GNUNET_SYSERR;
155   }
156   //interpret single ticket
157   unpack_state = json_unpack(root,
158                              "{s:s, s:s, s:s!}",
159                              "rnd", &rnd_str,
160                              "audience", &aud_str,
161                              "identity", &id_str);
162   if (0 != unpack_state)
163   {
164     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
165                "Error json object has a wrong format!\n");
166     return GNUNET_SYSERR;
167   }
168   ticket = GNUNET_new (struct GNUNET_RECLAIM_Ticket);
169   if (GNUNET_OK != GNUNET_STRINGS_string_to_data (rnd_str,
170                                                   strlen (rnd_str),
171                                                   &ticket->rnd,
172                                                   sizeof (uint64_t)))
173   {
174     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Rnd invalid\n");
175     GNUNET_free(ticket);
176     return GNUNET_SYSERR;
177   }
178   GNUNET_STRINGS_string_to_data (id_str,
179                                  strlen (id_str),
180                                  &ticket->identity,
181                                  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
182   {
183     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Identity invalid\n");
184     GNUNET_free(ticket);
185     return GNUNET_SYSERR;
186   }
187
188   GNUNET_STRINGS_string_to_data (aud_str,
189                                  strlen (aud_str),
190                                  &ticket->audience,
191                                  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
192   {
193     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Audience invalid\n");
194     GNUNET_free(ticket);
195     return GNUNET_SYSERR;
196   }
197
198   *(struct GNUNET_RECLAIM_Ticket **) spec->ptr = ticket;
199   return GNUNET_OK;
200 }
201
202 /**
203  * Cleanup data left from parsing RSA public key.
204  *
205  * @param cls closure, NULL
206  * @param[out] spec where to free the data
207  */
208 static void
209 clean_ticket (void *cls, struct GNUNET_JSON_Specification *spec)
210 {
211   struct GNUNET_RECLAIM_Ticket **ticket;
212   ticket = (struct GNUNET_RECLAIM_Ticket **) spec->ptr;
213   if (NULL != *ticket)
214   {
215     GNUNET_free(*ticket);
216     *ticket = NULL;
217   }
218 }
219
220 /**
221  * JSON Specification for Reclaim tickets.
222  *
223  * @param ticket struct of GNUNET_RECLAIM_Ticket to fill
224  * @return JSON Specification
225  */
226 struct GNUNET_JSON_Specification
227 GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket)
228 {
229   struct GNUNET_JSON_Specification ret = {
230     .parser = &parse_ticket,
231     .cleaner = &clean_ticket,
232     .cls = NULL,
233     .field = NULL,
234     .ptr = ticket,
235     .ptr_size = 0,
236     .size_ptr = NULL
237   };
238   *ticket = NULL;
239   return ret;
240 }