aboutsummaryrefslogtreecommitdiff
path: root/src/service/revocation/revocation_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/revocation/revocation_api.c')
-rw-r--r--src/service/revocation/revocation_api.c334
1 files changed, 334 insertions, 0 deletions
diff --git a/src/service/revocation/revocation_api.c b/src/service/revocation/revocation_api.c
new file mode 100644
index 000000000..0e3641af8
--- /dev/null
+++ b/src/service/revocation/revocation_api.c
@@ -0,0 +1,334 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2013, 2016 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 * @file revocation/revocation_api.c
22 * @brief API to perform and access key revocations
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include "gnunet_revocation_service.h"
27#include "gnunet_signatures.h"
28#include "gnunet_protocols.h"
29#include "revocation.h"
30#include <inttypes.h>
31
32/**
33 * Handle for the key revocation query.
34 */
35struct GNUNET_REVOCATION_Query
36{
37 /**
38 * Message queue to the service.
39 */
40 struct GNUNET_MQ_Handle *mq;
41
42 /**
43 * Function to call with the result.
44 */
45 GNUNET_REVOCATION_Callback func;
46
47 /**
48 * Closure for @e func.
49 */
50 void *func_cls;
51};
52
53
54/**
55 * Generic error handler, called with the appropriate
56 * error code and the same closure specified at the creation of
57 * the message queue.
58 * Not every message queue implementation supports an error handler.
59 *
60 * @param cls closure with the `struct GNUNET_NSE_Handle *`
61 * @param error error code
62 */
63static void
64query_mq_error_handler (void *cls,
65 enum GNUNET_MQ_Error error)
66{
67 struct GNUNET_REVOCATION_Query *q = cls;
68
69 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
70 "Revocation query MQ error\n");
71 q->func (q->func_cls,
72 GNUNET_SYSERR);
73 GNUNET_REVOCATION_query_cancel (q);
74}
75
76
77/**
78 * Handle response to our revocation query.
79 *
80 * @param cls our `struct GNUNET_REVOCATION_Query` handle
81 * @param qrm response we got
82 */
83static void
84handle_revocation_query_response (void *cls,
85 const struct QueryResponseMessage *qrm)
86{
87 struct GNUNET_REVOCATION_Query *q = cls;
88
89 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
90 "Revocation query result: %d\n",
91 (uint32_t) ntohl (qrm->is_valid));
92 q->func (q->func_cls,
93 ntohl (qrm->is_valid));
94 GNUNET_REVOCATION_query_cancel (q);
95}
96
97
98/**
99 * Check if a key was revoked.
100 *
101 * @param cfg the configuration to use
102 * @param key key to check for revocation
103 * @param func function to call with the result of the check
104 * @param func_cls closure to pass to @a func
105 * @return handle to use in #GNUNET_REVOCATION_query_cancel to stop REVOCATION from invoking the callback
106 */
107struct GNUNET_REVOCATION_Query *
108GNUNET_REVOCATION_query (const struct GNUNET_CONFIGURATION_Handle *cfg,
109 const struct GNUNET_CRYPTO_PublicKey *key,
110 GNUNET_REVOCATION_Callback func,
111 void *func_cls)
112{
113 struct GNUNET_REVOCATION_Query *q
114 = GNUNET_new (struct GNUNET_REVOCATION_Query);
115 struct GNUNET_MQ_MessageHandler handlers[] = {
116 GNUNET_MQ_hd_fixed_size (revocation_query_response,
117 GNUNET_MESSAGE_TYPE_REVOCATION_QUERY_RESPONSE,
118 struct QueryResponseMessage,
119 q),
120 GNUNET_MQ_handler_end ()
121 };
122 struct QueryMessage *qm;
123 struct GNUNET_MQ_Envelope *env;
124 size_t key_len;
125
126 q->mq = GNUNET_CLIENT_connect (cfg,
127 "revocation",
128 handlers,
129 &query_mq_error_handler,
130 q);
131 if (NULL == q->mq)
132 {
133 GNUNET_free (q);
134 return NULL;
135 }
136 q->func = func;
137 q->func_cls = func_cls;
138 key_len = GNUNET_CRYPTO_public_key_get_length (key);
139 env = GNUNET_MQ_msg_extra (qm, key_len,
140 GNUNET_MESSAGE_TYPE_REVOCATION_QUERY);
141 GNUNET_CRYPTO_write_public_key_to_buffer (key, &qm[1], key_len);
142 qm->key_len = htonl (key_len);
143 GNUNET_MQ_send (q->mq,
144 env);
145 return q;
146}
147
148
149/**
150 * Cancel key revocation check.
151 *
152 * @param q query to cancel
153 */
154void
155GNUNET_REVOCATION_query_cancel (struct GNUNET_REVOCATION_Query *q)
156{
157 if (NULL != q->mq)
158 {
159 GNUNET_MQ_destroy (q->mq);
160 q->mq = NULL;
161 }
162 GNUNET_free (q);
163}
164
165
166/**
167 * Handle for the key revocation operation.
168 */
169struct GNUNET_REVOCATION_Handle
170{
171 /**
172 * Message queue to the service.
173 */
174 struct GNUNET_MQ_Handle *mq;
175
176 /**
177 * Function to call once we are done.
178 */
179 GNUNET_REVOCATION_Callback func;
180
181 /**
182 * Closure for @e func.
183 */
184 void *func_cls;
185};
186
187
188/**
189 * Generic error handler, called with the appropriate
190 * error code and the same closure specified at the creation of
191 * the message queue.
192 * Not every message queue implementation supports an error handler.
193 *
194 * @param cls closure with the `struct GNUNET_NSE_Handle *`
195 * @param error error code
196 */
197static void
198revocation_mq_error_handler (void *cls,
199 enum GNUNET_MQ_Error error)
200{
201 struct GNUNET_REVOCATION_Handle *h = cls;
202
203 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
204 "Revocation MQ error\n");
205 h->func (h->func_cls,
206 GNUNET_SYSERR);
207 GNUNET_REVOCATION_revoke_cancel (h);
208}
209
210
211/**
212 * Handle response to our revocation query.
213 *
214 * @param cls our `struct GNUNET_REVOCATION_Handle` handle
215 * @param rrm response we got
216 */
217static void
218handle_revocation_response (void *cls,
219 const struct RevocationResponseMessage *rrm)
220{
221 struct GNUNET_REVOCATION_Handle *h = cls;
222
223 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
224 "Revocation transmission result: %d\n",
225 (uint32_t) ntohl (rrm->is_valid));
226 h->func (h->func_cls,
227 ntohl (rrm->is_valid));
228 GNUNET_REVOCATION_revoke_cancel (h);
229}
230
231
232/**
233 * Perform key revocation.
234 *
235 * @param cfg the configuration to use
236 * @param key public key of the key to revoke
237 * @param sig signature to use on the revocation (should have been
238 * created using #GNUNET_REVOCATION_sign_revocation).
239 * @param ts revocation timestamp
240 * @param pow proof of work to use (should have been created by
241 * iteratively calling #GNUNET_REVOCATION_check_pow)
242 * @param func function to call with the result of the check
243 * (called with `is_valid` being #GNUNET_NO if
244 * the revocation worked).
245 * @param func_cls closure to pass to @a func
246 * @return handle to use in #GNUNET_REVOCATION_revoke_cancel to stop REVOCATION from invoking the callback
247 */
248struct GNUNET_REVOCATION_Handle *
249GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg,
250 const struct GNUNET_GNSRECORD_PowP *pow,
251 GNUNET_REVOCATION_Callback func,
252 void *func_cls)
253{
254 struct GNUNET_REVOCATION_Handle *h
255 = GNUNET_new (struct GNUNET_REVOCATION_Handle);
256 struct GNUNET_MQ_MessageHandler handlers[] = {
257 GNUNET_MQ_hd_fixed_size (revocation_response,
258 GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE_RESPONSE,
259 struct RevocationResponseMessage,
260 h),
261 GNUNET_MQ_handler_end ()
262 };
263 unsigned long long matching_bits;
264 struct GNUNET_TIME_Relative epoch_duration;
265 struct RevokeMessage *rm;
266 struct GNUNET_MQ_Envelope *env;
267
268 if ((GNUNET_OK !=
269 GNUNET_CONFIGURATION_get_value_number (cfg,
270 "REVOCATION",
271 "WORKBITS",
272 &matching_bits)))
273 {
274 GNUNET_break (0);
275 GNUNET_free (h);
276 return NULL;
277 }
278 if ((GNUNET_OK !=
279 GNUNET_CONFIGURATION_get_value_time (cfg,
280 "REVOCATION",
281 "EPOCH_DURATION",
282 &epoch_duration)))
283 {
284 GNUNET_break (0);
285 GNUNET_free (h);
286 return NULL;
287 }
288 if (GNUNET_YES != GNUNET_GNSRECORD_check_pow (pow,
289 (unsigned int) matching_bits,
290 epoch_duration))
291 {
292 GNUNET_break (0);
293 GNUNET_free (h);
294 return NULL;
295 }
296
297
298 h->mq = GNUNET_CLIENT_connect (cfg,
299 "revocation",
300 handlers,
301 &revocation_mq_error_handler,
302 h);
303 if (NULL == h->mq)
304 {
305 GNUNET_free (h);
306 return NULL;
307 }
308 h->func = func;
309 h->func_cls = func_cls;
310 size_t extra_len = GNUNET_GNSRECORD_proof_get_size (pow);
311 env = GNUNET_MQ_msg_extra (rm,
312 extra_len,
313 GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE);
314 rm->pow_size = htonl (extra_len);
315 memcpy (&rm[1], pow, extra_len);
316 GNUNET_MQ_send (h->mq,
317 env);
318 return h;
319}
320
321
322void
323GNUNET_REVOCATION_revoke_cancel (struct GNUNET_REVOCATION_Handle *h)
324{
325 if (NULL != h->mq)
326 {
327 GNUNET_MQ_destroy (h->mq);
328 h->mq = NULL;
329 }
330 GNUNET_free (h);
331}
332
333
334/* end of revocation_api.c */