Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2020, 2021, 2022 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file util/crypto_helper_cs.c
18 : * @brief utility functions for running out-of-process private key operations
19 : * @author Christian Grothoff
20 : */
21 : #include "taler/platform.h"
22 : #include "taler/taler_util.h"
23 : #include "taler/taler_signatures.h"
24 : #include "secmod_cs.h"
25 : #include <poll.h>
26 : #include "crypto_helper_common.h"
27 :
28 :
29 : struct TALER_CRYPTO_CsDenominationHelper
30 : {
31 : /**
32 : * Function to call with updates to available key material.
33 : */
34 : TALER_CRYPTO_CsDenominationKeyStatusCallback dkc;
35 :
36 : /**
37 : * Closure for @e dkc
38 : */
39 : void *dkc_cls;
40 :
41 : /**
42 : * Socket address of the denomination helper process.
43 : * Used to reconnect if the connection breaks.
44 : */
45 : struct sockaddr_un sa;
46 :
47 : /**
48 : * The UNIX domain socket, -1 if we are currently not connected.
49 : */
50 : int sock;
51 :
52 : /**
53 : * Have we ever been sync'ed?
54 : */
55 : bool synced;
56 : };
57 :
58 :
59 : /**
60 : * Disconnect from the helper process. Updates
61 : * @e sock field in @a dh.
62 : *
63 : * @param[in,out] dh handle to tear down connection of
64 : */
65 : static void
66 27 : do_disconnect (struct TALER_CRYPTO_CsDenominationHelper *dh)
67 : {
68 27 : GNUNET_break (0 == close (dh->sock));
69 27 : dh->sock = -1;
70 27 : dh->synced = false;
71 27 : }
72 :
73 :
74 : /**
75 : * Try to connect to the helper process. Updates
76 : * @e sock field in @a dh.
77 : *
78 : * @param[in,out] dh handle to establish connection for
79 : * @return #GNUNET_OK on success
80 : */
81 : static enum GNUNET_GenericReturnValue
82 1983 : try_connect (struct TALER_CRYPTO_CsDenominationHelper *dh)
83 : {
84 1983 : if (-1 != dh->sock)
85 1956 : return GNUNET_OK;
86 27 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
87 : "Establishing connection!\n");
88 27 : dh->sock = socket (AF_UNIX,
89 : SOCK_STREAM,
90 : 0);
91 27 : if (-1 == dh->sock)
92 : {
93 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
94 : "socket");
95 0 : return GNUNET_SYSERR;
96 : }
97 27 : if (0 !=
98 27 : connect (dh->sock,
99 27 : (const struct sockaddr *) &dh->sa,
100 : sizeof (dh->sa)))
101 : {
102 1 : GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
103 : "connect",
104 : dh->sa.sun_path);
105 1 : do_disconnect (dh);
106 1 : return GNUNET_SYSERR;
107 : }
108 26 : TALER_CRYPTO_helper_cs_poll (dh);
109 26 : return GNUNET_OK;
110 : }
111 :
112 :
113 : struct TALER_CRYPTO_CsDenominationHelper *
114 27 : TALER_CRYPTO_helper_cs_connect (
115 : const struct GNUNET_CONFIGURATION_Handle *cfg,
116 : const char *section,
117 : TALER_CRYPTO_CsDenominationKeyStatusCallback dkc,
118 : void *dkc_cls)
119 : {
120 : struct TALER_CRYPTO_CsDenominationHelper *dh;
121 : char *unixpath;
122 : char *secname;
123 :
124 27 : GNUNET_asprintf (&secname,
125 : "%s-secmod-cs",
126 : section);
127 27 : if (GNUNET_OK !=
128 27 : GNUNET_CONFIGURATION_get_value_filename (cfg,
129 : secname,
130 : "UNIXPATH",
131 : &unixpath))
132 : {
133 0 : GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
134 : secname,
135 : "UNIXPATH");
136 0 : GNUNET_free (secname);
137 0 : return NULL;
138 : }
139 : /* we use >= here because we want the sun_path to always
140 : be 0-terminated */
141 27 : if (strlen (unixpath) >= sizeof (dh->sa.sun_path))
142 : {
143 0 : GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
144 : secname,
145 : "UNIXPATH",
146 : "path too long");
147 0 : GNUNET_free (unixpath);
148 0 : GNUNET_free (secname);
149 0 : return NULL;
150 : }
151 27 : GNUNET_free (secname);
152 27 : dh = GNUNET_new (struct TALER_CRYPTO_CsDenominationHelper);
153 27 : dh->dkc = dkc;
154 27 : dh->dkc_cls = dkc_cls;
155 27 : dh->sa.sun_family = AF_UNIX;
156 27 : strncpy (dh->sa.sun_path,
157 : unixpath,
158 : sizeof (dh->sa.sun_path) - 1);
159 27 : GNUNET_free (unixpath);
160 27 : dh->sock = -1;
161 27 : if (GNUNET_OK !=
162 27 : try_connect (dh))
163 : {
164 1 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
165 : "Could not connect to %s. Will keep trying\n",
166 : "taler-exchange-helper-secmod-cs");
167 : }
168 27 : return dh;
169 : }
170 :
171 :
172 : /**
173 : * Handle a #TALER_HELPER_CS_MT_AVAIL message from the helper.
174 : *
175 : * @param dh helper context
176 : * @param hdr message that we received
177 : * @return #GNUNET_OK on success
178 : */
179 : static enum GNUNET_GenericReturnValue
180 2745 : handle_mt_avail (struct TALER_CRYPTO_CsDenominationHelper *dh,
181 : const struct GNUNET_MessageHeader *hdr)
182 : {
183 2745 : const struct TALER_CRYPTO_CsKeyAvailableNotification *kan
184 : = (const struct TALER_CRYPTO_CsKeyAvailableNotification *) hdr;
185 2745 : const char *buf = (const char *) &kan[1];
186 : const char *section_name;
187 : uint16_t snl;
188 :
189 2745 : if (sizeof (*kan) > ntohs (hdr->size))
190 : {
191 0 : GNUNET_break_op (0);
192 0 : return GNUNET_SYSERR;
193 : }
194 2745 : snl = ntohs (kan->section_name_len);
195 2745 : if (ntohs (hdr->size) != sizeof (*kan) + snl)
196 : {
197 0 : GNUNET_break_op (0);
198 0 : return GNUNET_SYSERR;
199 : }
200 2745 : if (0 == snl)
201 : {
202 0 : GNUNET_break_op (0);
203 0 : return GNUNET_SYSERR;
204 : }
205 2745 : section_name = buf;
206 2745 : if ('\0' != section_name[snl - 1])
207 : {
208 0 : GNUNET_break_op (0);
209 0 : return GNUNET_SYSERR;
210 : }
211 :
212 : {
213 : struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub;
214 : struct TALER_CsPubHashP h_cs;
215 :
216 2745 : bsign_pub = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey);
217 2745 : bsign_pub->cipher = GNUNET_CRYPTO_BSA_CS;
218 2745 : bsign_pub->rc = 1;
219 2745 : bsign_pub->details.cs_public_key = kan->denom_pub;
220 :
221 2745 : GNUNET_CRYPTO_hash (&bsign_pub->details.cs_public_key,
222 : sizeof (bsign_pub->details.cs_public_key),
223 : &bsign_pub->pub_key_hash);
224 2745 : h_cs.hash = bsign_pub->pub_key_hash;
225 2745 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
226 : "Received CS key %s (%s)\n",
227 : GNUNET_h2s (&h_cs.hash),
228 : section_name);
229 2745 : if (GNUNET_OK !=
230 2745 : TALER_exchange_secmod_cs_verify (
231 : &h_cs,
232 : section_name,
233 : GNUNET_TIME_timestamp_ntoh (kan->anchor_time),
234 : GNUNET_TIME_relative_ntoh (kan->duration_withdraw),
235 : &kan->secm_pub,
236 : &kan->secm_sig))
237 : {
238 0 : GNUNET_break_op (0);
239 0 : GNUNET_CRYPTO_blind_sign_pub_decref (bsign_pub);
240 0 : return GNUNET_SYSERR;
241 : }
242 2745 : dh->dkc (dh->dkc_cls,
243 : section_name,
244 : GNUNET_TIME_timestamp_ntoh (kan->anchor_time),
245 : GNUNET_TIME_relative_ntoh (kan->duration_withdraw),
246 : &h_cs,
247 : bsign_pub,
248 : &kan->secm_pub,
249 : &kan->secm_sig);
250 2745 : GNUNET_CRYPTO_blind_sign_pub_decref (bsign_pub);
251 : }
252 2745 : return GNUNET_OK;
253 : }
254 :
255 :
256 : /**
257 : * Handle a #TALER_HELPER_CS_MT_PURGE message from the helper.
258 : *
259 : * @param dh helper context
260 : * @param hdr message that we received
261 : * @return #GNUNET_OK on success
262 : */
263 : static enum GNUNET_GenericReturnValue
264 3 : handle_mt_purge (struct TALER_CRYPTO_CsDenominationHelper *dh,
265 : const struct GNUNET_MessageHeader *hdr)
266 : {
267 3 : const struct TALER_CRYPTO_CsKeyPurgeNotification *pn
268 : = (const struct TALER_CRYPTO_CsKeyPurgeNotification *) hdr;
269 :
270 3 : if (sizeof (*pn) != ntohs (hdr->size))
271 : {
272 0 : GNUNET_break_op (0);
273 0 : return GNUNET_SYSERR;
274 : }
275 3 : GNUNET_log (GNUNET_ERROR_TYPE_INFO,
276 : "Received revocation of denomination key %s\n",
277 : GNUNET_h2s (&pn->h_cs.hash));
278 3 : dh->dkc (dh->dkc_cls,
279 : NULL,
280 3 : GNUNET_TIME_UNIT_ZERO_TS,
281 3 : GNUNET_TIME_UNIT_ZERO,
282 : &pn->h_cs,
283 : NULL,
284 : NULL,
285 : NULL);
286 3 : return GNUNET_OK;
287 : }
288 :
289 :
290 : void
291 837 : TALER_CRYPTO_helper_cs_poll (struct TALER_CRYPTO_CsDenominationHelper *dh)
292 : {
293 : char buf[UINT16_MAX];
294 837 : size_t off = 0;
295 837 : unsigned int retry_limit = 3;
296 837 : const struct GNUNET_MessageHeader *hdr
297 : = (const struct GNUNET_MessageHeader *) buf;
298 :
299 837 : if (GNUNET_OK !=
300 837 : try_connect (dh))
301 0 : return; /* give up */
302 : while (1)
303 36 : {
304 : uint16_t msize;
305 : ssize_t ret;
306 :
307 873 : ret = recv (dh->sock,
308 : buf + off,
309 : sizeof (buf) - off,
310 873 : (dh->synced && (0 == off))
311 : ? MSG_DONTWAIT
312 : : 0);
313 873 : if (ret < 0)
314 : {
315 837 : if (EINTR == errno)
316 0 : continue;
317 837 : if (EAGAIN == errno)
318 : {
319 837 : GNUNET_assert (dh->synced);
320 837 : GNUNET_assert (0 == off);
321 837 : break;
322 : }
323 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
324 : "recv");
325 0 : do_disconnect (dh);
326 0 : if (0 == retry_limit)
327 0 : return; /* give up */
328 0 : if (GNUNET_OK !=
329 0 : try_connect (dh))
330 0 : return; /* give up */
331 0 : retry_limit--;
332 0 : continue;
333 : }
334 36 : if (0 == ret)
335 : {
336 0 : GNUNET_break (0 == off);
337 0 : return;
338 : }
339 36 : off += ret;
340 2810 : more:
341 2810 : if (off < sizeof (struct GNUNET_MessageHeader))
342 31 : continue;
343 2779 : msize = ntohs (hdr->size);
344 2779 : if (off < msize)
345 5 : continue;
346 2774 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
347 : "Received message of type %u and length %u\n",
348 : (unsigned int) ntohs (hdr->type),
349 : (unsigned int) msize);
350 2774 : switch (ntohs (hdr->type))
351 : {
352 2745 : case TALER_HELPER_CS_MT_AVAIL:
353 2745 : if (GNUNET_OK !=
354 2745 : handle_mt_avail (dh,
355 : hdr))
356 : {
357 0 : GNUNET_break_op (0);
358 0 : do_disconnect (dh);
359 0 : return;
360 : }
361 2745 : break;
362 3 : case TALER_HELPER_CS_MT_PURGE:
363 3 : if (GNUNET_OK !=
364 3 : handle_mt_purge (dh,
365 : hdr))
366 : {
367 0 : GNUNET_break_op (0);
368 0 : do_disconnect (dh);
369 0 : return;
370 : }
371 3 : break;
372 26 : case TALER_HELPER_CS_SYNCED:
373 26 : GNUNET_log (GNUNET_ERROR_TYPE_INFO,
374 : "Now synchronized with CS helper\n");
375 26 : dh->synced = true;
376 26 : break;
377 0 : default:
378 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
379 : "Received unexpected message of type %d (len: %u)\n",
380 : (unsigned int) ntohs (hdr->type),
381 : (unsigned int) msize);
382 0 : GNUNET_break_op (0);
383 0 : do_disconnect (dh);
384 0 : return;
385 : }
386 2774 : memmove (buf,
387 2774 : &buf[msize],
388 : off - msize);
389 2774 : off -= msize;
390 2774 : goto more;
391 : }
392 : }
393 :
394 :
395 : enum TALER_ErrorCode
396 902 : TALER_CRYPTO_helper_cs_sign (
397 : struct TALER_CRYPTO_CsDenominationHelper *dh,
398 : const struct TALER_CRYPTO_CsSignRequest *req,
399 : bool for_melt,
400 : struct TALER_BlindedDenominationSignature *bs)
401 : {
402 902 : enum TALER_ErrorCode ec = TALER_EC_INVALID;
403 902 : const struct TALER_CsPubHashP *h_cs = req->h_cs;
404 :
405 902 : memset (bs,
406 : 0,
407 : sizeof (*bs));
408 902 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
409 : "Starting signature process\n");
410 902 : if (GNUNET_OK !=
411 902 : try_connect (dh))
412 : {
413 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
414 : "Failed to connect to helper\n");
415 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
416 : }
417 :
418 902 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
419 : "Requesting signature\n");
420 : {
421 : char buf[sizeof (struct TALER_CRYPTO_CsSignRequestMessage)];
422 902 : struct TALER_CRYPTO_CsSignRequestMessage *sr
423 : = (struct TALER_CRYPTO_CsSignRequestMessage *) buf;
424 :
425 902 : sr->header.size = htons (sizeof (buf));
426 902 : sr->header.type = htons (TALER_HELPER_CS_MT_REQ_SIGN);
427 902 : sr->for_melt = htonl (for_melt ? 1 : 0);
428 902 : sr->h_cs = *h_cs;
429 902 : sr->message = *req->blinded_planchet;
430 902 : if (GNUNET_OK !=
431 902 : TALER_crypto_helper_send_all (dh->sock,
432 : buf,
433 : sizeof (buf)))
434 : {
435 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
436 : "send");
437 0 : do_disconnect (dh);
438 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
439 : }
440 : }
441 :
442 902 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
443 : "Awaiting reply\n");
444 : {
445 : char buf[UINT16_MAX];
446 902 : size_t off = 0;
447 902 : const struct GNUNET_MessageHeader *hdr
448 : = (const struct GNUNET_MessageHeader *) buf;
449 902 : bool finished = false;
450 :
451 : while (1)
452 902 : {
453 : uint16_t msize;
454 : ssize_t ret;
455 :
456 2706 : ret = recv (dh->sock,
457 1804 : &buf[off],
458 : sizeof (buf) - off,
459 902 : (finished && (0 == off))
460 : ? MSG_DONTWAIT
461 : : 0);
462 1804 : if (ret < 0)
463 : {
464 902 : if (EINTR == errno)
465 0 : continue;
466 902 : if (EAGAIN == errno)
467 : {
468 902 : GNUNET_assert (finished);
469 902 : GNUNET_assert (0 == off);
470 902 : return ec;
471 : }
472 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
473 : "recv");
474 0 : do_disconnect (dh);
475 0 : ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
476 0 : break;
477 : }
478 902 : if (0 == ret)
479 : {
480 0 : GNUNET_break (0 == off);
481 0 : if (! finished)
482 0 : ec = TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG;
483 0 : return ec;
484 : }
485 902 : off += ret;
486 1804 : more:
487 1804 : if (off < sizeof (struct GNUNET_MessageHeader))
488 902 : continue;
489 902 : msize = ntohs (hdr->size);
490 902 : if (off < msize)
491 0 : continue;
492 902 : switch (ntohs (hdr->type))
493 : {
494 901 : case TALER_HELPER_CS_MT_RES_SIGNATURE:
495 901 : if (msize != sizeof (struct TALER_CRYPTO_SignResponse))
496 : {
497 0 : GNUNET_break_op (0);
498 0 : do_disconnect (dh);
499 0 : ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
500 0 : goto end;
501 : }
502 901 : if (finished)
503 : {
504 0 : GNUNET_break_op (0);
505 0 : do_disconnect (dh);
506 0 : ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
507 0 : goto end;
508 : }
509 : {
510 901 : const struct TALER_CRYPTO_SignResponse *sr =
511 : (const struct TALER_CRYPTO_SignResponse *) buf;
512 : struct GNUNET_CRYPTO_BlindedSignature *blinded_sig;
513 :
514 901 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
515 : "Received signature\n");
516 901 : ec = TALER_EC_NONE;
517 901 : finished = true;
518 901 : blinded_sig = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature);
519 901 : blinded_sig->cipher = GNUNET_CRYPTO_BSA_CS;
520 901 : blinded_sig->rc = 1;
521 901 : blinded_sig->details.blinded_cs_answer.b = ntohl (sr->b);
522 901 : blinded_sig->details.blinded_cs_answer.s_scalar = sr->cs_answer;
523 901 : bs->blinded_sig = blinded_sig;
524 901 : break;
525 : }
526 1 : case TALER_HELPER_CS_MT_RES_SIGN_FAILURE:
527 1 : if (msize != sizeof (struct TALER_CRYPTO_SignFailure))
528 : {
529 0 : GNUNET_break_op (0);
530 0 : do_disconnect (dh);
531 0 : ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
532 0 : goto end;
533 : }
534 : {
535 1 : const struct TALER_CRYPTO_SignFailure *sf =
536 : (const struct TALER_CRYPTO_SignFailure *) buf;
537 :
538 1 : ec = (enum TALER_ErrorCode) (int) ntohl (sf->ec);
539 1 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
540 : "Signing failed with status %d!\n",
541 : ec);
542 1 : finished = true;
543 1 : break;
544 : }
545 0 : case TALER_HELPER_CS_MT_AVAIL:
546 0 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
547 : "Received new key!\n");
548 0 : if (GNUNET_OK !=
549 0 : handle_mt_avail (dh,
550 : hdr))
551 : {
552 0 : GNUNET_break_op (0);
553 0 : do_disconnect (dh);
554 0 : ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
555 0 : goto end;
556 : }
557 0 : break; /* while(1) loop ensures we recvfrom() again */
558 0 : case TALER_HELPER_CS_MT_PURGE:
559 0 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
560 : "Received revocation!\n");
561 0 : if (GNUNET_OK !=
562 0 : handle_mt_purge (dh,
563 : hdr))
564 : {
565 0 : GNUNET_break_op (0);
566 0 : do_disconnect (dh);
567 0 : ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
568 0 : goto end;
569 : }
570 0 : break; /* while(1) loop ensures we recvfrom() again */
571 0 : case TALER_HELPER_CS_SYNCED:
572 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
573 : "Synchronized add odd time with CS helper!\n");
574 0 : dh->synced = true;
575 0 : break;
576 0 : default:
577 0 : GNUNET_break_op (0);
578 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
579 : "Received unexpected message of type %u\n",
580 : ntohs (hdr->type));
581 0 : do_disconnect (dh);
582 0 : ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
583 0 : goto end;
584 : }
585 902 : memmove (buf,
586 902 : &buf[msize],
587 : off - msize);
588 902 : off -= msize;
589 902 : goto more;
590 : } /* while(1) */
591 0 : end:
592 0 : if (finished)
593 0 : TALER_blinded_denom_sig_free (bs);
594 0 : return ec;
595 : }
596 : }
597 :
598 :
599 : void
600 3 : TALER_CRYPTO_helper_cs_revoke (
601 : struct TALER_CRYPTO_CsDenominationHelper *dh,
602 : const struct TALER_CsPubHashP *h_cs)
603 : {
604 3 : struct TALER_CRYPTO_CsRevokeRequest rr = {
605 3 : .header.size = htons (sizeof (rr)),
606 3 : .header.type = htons (TALER_HELPER_CS_MT_REQ_REVOKE),
607 : .h_cs = *h_cs
608 : };
609 :
610 3 : if (GNUNET_OK !=
611 3 : try_connect (dh))
612 0 : return; /* give up */
613 3 : if (GNUNET_OK !=
614 3 : TALER_crypto_helper_send_all (dh->sock,
615 : &rr,
616 : sizeof (rr)))
617 : {
618 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
619 : "send");
620 0 : do_disconnect (dh);
621 0 : return;
622 : }
623 3 : GNUNET_log (GNUNET_ERROR_TYPE_INFO,
624 : "Requested revocation of denomination key %s\n",
625 : GNUNET_h2s (&h_cs->hash));
626 : }
627 :
628 :
629 : enum TALER_ErrorCode
630 22 : TALER_CRYPTO_helper_cs_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh,
631 : const struct TALER_CRYPTO_CsDeriveRequest *cdr,
632 : bool for_melt,
633 : struct GNUNET_CRYPTO_CSPublicRPairP *crp)
634 : {
635 22 : enum TALER_ErrorCode ec = TALER_EC_INVALID;
636 22 : const struct TALER_CsPubHashP *h_cs = cdr->h_cs;
637 22 : const struct GNUNET_CRYPTO_CsSessionNonce *nonce = cdr->nonce;
638 :
639 22 : memset (crp,
640 : 0,
641 : sizeof (*crp));
642 22 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
643 : "Starting R derivation process\n");
644 22 : if (GNUNET_OK !=
645 22 : try_connect (dh))
646 : {
647 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
648 : "Failed to connect to helper\n");
649 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
650 : }
651 :
652 22 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
653 : "Requesting R\n");
654 : {
655 22 : struct TALER_CRYPTO_CsRDeriveRequest rdr = {
656 22 : .header.size = htons (sizeof (rdr)),
657 22 : .header.type = htons (TALER_HELPER_CS_MT_REQ_RDERIVE),
658 22 : .for_melt = htonl (for_melt ? 1 : 0),
659 : .h_cs = *h_cs,
660 : .nonce = *nonce
661 : };
662 :
663 22 : if (GNUNET_OK !=
664 22 : TALER_crypto_helper_send_all (dh->sock,
665 : &rdr,
666 : sizeof (rdr)))
667 : {
668 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
669 : "send");
670 0 : do_disconnect (dh);
671 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
672 : }
673 : }
674 :
675 22 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
676 : "Awaiting reply\n");
677 : {
678 : char buf[UINT16_MAX];
679 22 : size_t off = 0;
680 22 : const struct GNUNET_MessageHeader *hdr
681 : = (const struct GNUNET_MessageHeader *) buf;
682 22 : bool finished = false;
683 :
684 : while (1)
685 22 : {
686 : uint16_t msize;
687 : ssize_t ret;
688 :
689 66 : ret = recv (dh->sock,
690 44 : &buf[off],
691 : sizeof (buf) - off,
692 22 : (finished && (0 == off))
693 : ? MSG_DONTWAIT
694 : : 0);
695 44 : if (ret < 0)
696 : {
697 22 : if (EINTR == errno)
698 0 : continue;
699 22 : if (EAGAIN == errno)
700 : {
701 22 : GNUNET_assert (finished);
702 22 : GNUNET_assert (0 == off);
703 22 : return ec;
704 : }
705 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
706 : "recv");
707 0 : do_disconnect (dh);
708 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
709 : }
710 22 : if (0 == ret)
711 : {
712 0 : GNUNET_break (0 == off);
713 0 : if (! finished)
714 0 : return TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG;
715 0 : return ec;
716 : }
717 22 : off += ret;
718 44 : more:
719 44 : if (off < sizeof (struct GNUNET_MessageHeader))
720 22 : continue;
721 22 : msize = ntohs (hdr->size);
722 22 : if (off < msize)
723 0 : continue;
724 22 : switch (ntohs (hdr->type))
725 : {
726 11 : case TALER_HELPER_CS_MT_RES_RDERIVE:
727 11 : if (msize != sizeof (struct TALER_CRYPTO_RDeriveResponse))
728 : {
729 0 : GNUNET_break_op (0);
730 0 : do_disconnect (dh);
731 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
732 : }
733 11 : if (finished)
734 : {
735 0 : GNUNET_break_op (0);
736 0 : do_disconnect (dh);
737 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
738 : }
739 : {
740 11 : const struct TALER_CRYPTO_RDeriveResponse *rdr =
741 : (const struct TALER_CRYPTO_RDeriveResponse *) buf;
742 :
743 11 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
744 : "Received R\n");
745 11 : finished = true;
746 11 : ec = TALER_EC_NONE;
747 11 : *crp = rdr->r_pub;
748 11 : break;
749 : }
750 11 : case TALER_HELPER_CS_MT_RES_RDERIVE_FAILURE:
751 11 : if (msize != sizeof (struct TALER_CRYPTO_RDeriveFailure))
752 : {
753 0 : GNUNET_break_op (0);
754 0 : do_disconnect (dh);
755 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
756 : }
757 : {
758 11 : const struct TALER_CRYPTO_RDeriveFailure *rdf =
759 : (const struct TALER_CRYPTO_RDeriveFailure *) buf;
760 :
761 11 : ec = (enum TALER_ErrorCode) (int) ntohl (rdf->ec);
762 11 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
763 : "R derivation failed!\n");
764 11 : finished = true;
765 11 : break;
766 : }
767 0 : case TALER_HELPER_CS_MT_AVAIL:
768 0 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
769 : "Received new key!\n");
770 0 : if (GNUNET_OK !=
771 0 : handle_mt_avail (dh,
772 : hdr))
773 : {
774 0 : GNUNET_break_op (0);
775 0 : do_disconnect (dh);
776 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
777 : }
778 0 : break; /* while(1) loop ensures we recvfrom() again */
779 0 : case TALER_HELPER_CS_MT_PURGE:
780 0 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
781 : "Received revocation!\n");
782 0 : if (GNUNET_OK !=
783 0 : handle_mt_purge (dh,
784 : hdr))
785 : {
786 0 : GNUNET_break_op (0);
787 0 : do_disconnect (dh);
788 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
789 : }
790 0 : break; /* while(1) loop ensures we recvfrom() again */
791 0 : case TALER_HELPER_CS_SYNCED:
792 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
793 : "Synchronized add odd time with CS helper!\n");
794 0 : dh->synced = true;
795 0 : break;
796 0 : default:
797 0 : GNUNET_break_op (0);
798 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
799 : "Received unexpected message of type %u\n",
800 : ntohs (hdr->type));
801 0 : do_disconnect (dh);
802 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
803 : }
804 22 : memmove (buf,
805 22 : &buf[msize],
806 : off - msize);
807 22 : off -= msize;
808 22 : goto more;
809 : } /* while(1) */
810 : }
811 : }
812 :
813 :
814 : enum TALER_ErrorCode
815 57 : TALER_CRYPTO_helper_cs_batch_sign (
816 : struct TALER_CRYPTO_CsDenominationHelper *dh,
817 : unsigned int reqs_length,
818 : const struct TALER_CRYPTO_CsSignRequest reqs[static reqs_length],
819 : bool for_melt,
820 : struct TALER_BlindedDenominationSignature bss[static reqs_length])
821 57 : {
822 57 : enum TALER_ErrorCode ec = TALER_EC_INVALID;
823 : unsigned int rpos;
824 : unsigned int rend;
825 : unsigned int wpos;
826 :
827 57 : memset (bss,
828 : 0,
829 : sizeof (*bss) * reqs_length);
830 57 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
831 : "Starting signature process\n");
832 57 : if (GNUNET_OK !=
833 57 : try_connect (dh))
834 : {
835 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
836 : "Failed to connect to helper\n");
837 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
838 : }
839 :
840 57 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
841 : "Requesting %u signatures\n",
842 : reqs_length);
843 57 : rpos = 0;
844 57 : rend = 0;
845 57 : wpos = 0;
846 114 : while (rpos < reqs_length)
847 : {
848 57 : unsigned int mlen = sizeof (struct TALER_CRYPTO_BatchSignRequest);
849 :
850 307 : while ( (rend < reqs_length) &&
851 250 : (mlen + sizeof (struct TALER_CRYPTO_CsSignRequestMessage)
852 : < UINT16_MAX) )
853 : {
854 250 : mlen += sizeof (struct TALER_CRYPTO_CsSignRequestMessage);
855 250 : rend++;
856 : }
857 57 : {
858 57 : char obuf[mlen] GNUNET_ALIGN;
859 57 : struct TALER_CRYPTO_BatchSignRequest *bsr
860 : = (struct TALER_CRYPTO_BatchSignRequest *) obuf;
861 : void *wbuf;
862 :
863 57 : bsr->header.type = htons (TALER_HELPER_CS_MT_REQ_BATCH_SIGN);
864 57 : bsr->header.size = htons (mlen);
865 57 : bsr->batch_size = htonl (rend - rpos);
866 57 : wbuf = &bsr[1];
867 307 : for (unsigned int i = rpos; i<rend; i++)
868 : {
869 250 : struct TALER_CRYPTO_CsSignRequestMessage *csm = wbuf;
870 250 : const struct TALER_CRYPTO_CsSignRequest *csr = &reqs[i];
871 :
872 250 : csm->header.size = htons (sizeof (*csm));
873 250 : csm->header.type = htons (TALER_HELPER_CS_MT_REQ_SIGN);
874 250 : csm->for_melt = htonl (for_melt ? 1 : 0);
875 250 : csm->h_cs = *csr->h_cs;
876 250 : csm->message = *csr->blinded_planchet;
877 250 : wbuf += sizeof (*csm);
878 : }
879 57 : GNUNET_assert (wbuf == &obuf[mlen]);
880 57 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
881 : "Sending batch request [%u-%u)\n",
882 : rpos,
883 : rend);
884 57 : if (GNUNET_OK !=
885 57 : TALER_crypto_helper_send_all (dh->sock,
886 : obuf,
887 57 : sizeof (obuf)))
888 : {
889 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
890 : "send");
891 0 : do_disconnect (dh);
892 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
893 : }
894 : } /* end of obuf scope */
895 57 : rpos = rend;
896 : {
897 : char buf[UINT16_MAX];
898 57 : size_t off = 0;
899 57 : const struct GNUNET_MessageHeader *hdr
900 : = (const struct GNUNET_MessageHeader *) buf;
901 57 : bool finished = false;
902 :
903 : while (1)
904 149 : {
905 : uint16_t msize;
906 : ssize_t ret;
907 :
908 206 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
909 : "Awaiting reply at %u (up to %u)\n",
910 : wpos,
911 : rend);
912 263 : ret = recv (dh->sock,
913 206 : &buf[off],
914 : sizeof (buf) - off,
915 57 : (finished && (0 == off))
916 : ? MSG_DONTWAIT
917 : : 0);
918 206 : if (ret < 0)
919 : {
920 57 : if (EINTR == errno)
921 0 : continue;
922 57 : if (EAGAIN == errno)
923 : {
924 57 : GNUNET_assert (finished);
925 57 : GNUNET_assert (0 == off);
926 57 : break;
927 : }
928 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
929 : "recv");
930 0 : do_disconnect (dh);
931 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
932 : }
933 149 : if (0 == ret)
934 : {
935 0 : GNUNET_break (0 == off);
936 0 : if (! finished)
937 0 : return TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG;
938 0 : if (TALER_EC_NONE == ec)
939 0 : break;
940 0 : return ec;
941 : }
942 149 : off += ret;
943 399 : more:
944 399 : if (off < sizeof (struct GNUNET_MessageHeader))
945 149 : continue;
946 250 : msize = ntohs (hdr->size);
947 250 : if (off < msize)
948 0 : continue;
949 250 : switch (ntohs (hdr->type))
950 : {
951 248 : case TALER_HELPER_CS_MT_RES_SIGNATURE:
952 248 : if (msize != sizeof (struct TALER_CRYPTO_SignResponse))
953 : {
954 0 : GNUNET_break_op (0);
955 0 : do_disconnect (dh);
956 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
957 : }
958 248 : if (finished)
959 : {
960 0 : GNUNET_break_op (0);
961 0 : do_disconnect (dh);
962 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
963 : }
964 : {
965 248 : const struct TALER_CRYPTO_SignResponse *sr =
966 : (const struct TALER_CRYPTO_SignResponse *) buf;
967 : struct GNUNET_CRYPTO_BlindedSignature *blinded_sig;
968 248 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
969 : "Received %u signature\n",
970 : wpos);
971 248 : blinded_sig = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature);
972 248 : blinded_sig->cipher = GNUNET_CRYPTO_BSA_CS;
973 248 : blinded_sig->rc = 1;
974 248 : blinded_sig->details.blinded_cs_answer.b = ntohl (sr->b);
975 248 : blinded_sig->details.blinded_cs_answer.s_scalar = sr->cs_answer;
976 :
977 248 : bss[wpos].blinded_sig = blinded_sig;
978 248 : wpos++;
979 248 : if (wpos == rend)
980 : {
981 55 : if (TALER_EC_INVALID == ec)
982 55 : ec = TALER_EC_NONE;
983 55 : finished = true;
984 : }
985 248 : break;
986 : }
987 :
988 2 : case TALER_HELPER_CS_MT_RES_SIGN_FAILURE:
989 2 : if (msize != sizeof (struct TALER_CRYPTO_SignFailure))
990 : {
991 0 : GNUNET_break_op (0);
992 0 : do_disconnect (dh);
993 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
994 : }
995 : {
996 2 : const struct TALER_CRYPTO_SignFailure *sf =
997 : (const struct TALER_CRYPTO_SignFailure *) buf;
998 :
999 2 : ec = (enum TALER_ErrorCode) (int) ntohl (sf->ec);
1000 2 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1001 : "Signing %u failed with status %d!\n",
1002 : wpos,
1003 : ec);
1004 2 : wpos++;
1005 2 : if (wpos == rend)
1006 : {
1007 2 : finished = true;
1008 : }
1009 2 : break;
1010 : }
1011 0 : case TALER_HELPER_CS_MT_AVAIL:
1012 0 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1013 : "Received new key!\n");
1014 0 : if (GNUNET_OK !=
1015 0 : handle_mt_avail (dh,
1016 : hdr))
1017 : {
1018 0 : GNUNET_break_op (0);
1019 0 : do_disconnect (dh);
1020 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
1021 : }
1022 0 : break; /* while(1) loop ensures we recvfrom() again */
1023 0 : case TALER_HELPER_CS_MT_PURGE:
1024 0 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1025 : "Received revocation!\n");
1026 0 : if (GNUNET_OK !=
1027 0 : handle_mt_purge (dh,
1028 : hdr))
1029 : {
1030 0 : GNUNET_break_op (0);
1031 0 : do_disconnect (dh);
1032 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
1033 : }
1034 0 : break; /* while(1) loop ensures we recvfrom() again */
1035 0 : case TALER_HELPER_CS_SYNCED:
1036 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1037 : "Synchronized add odd time with CS helper!\n");
1038 0 : dh->synced = true;
1039 0 : break;
1040 0 : default:
1041 0 : GNUNET_break_op (0);
1042 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1043 : "Received unexpected message of type %u\n",
1044 : ntohs (hdr->type));
1045 0 : do_disconnect (dh);
1046 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
1047 : }
1048 250 : memmove (buf,
1049 250 : &buf[msize],
1050 : off - msize);
1051 250 : off -= msize;
1052 250 : goto more;
1053 : } /* while(1) */
1054 : } /* scope */
1055 : } /* while (rpos < cdrs_length) */
1056 57 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1057 : "Existing with %u signatures and status %d\n",
1058 : wpos,
1059 : ec);
1060 57 : return ec;
1061 : }
1062 :
1063 :
1064 : enum TALER_ErrorCode
1065 135 : TALER_CRYPTO_helper_cs_r_batch_derive (
1066 : struct TALER_CRYPTO_CsDenominationHelper *dh,
1067 : unsigned int cdrs_length,
1068 : const struct TALER_CRYPTO_CsDeriveRequest cdrs[static cdrs_length],
1069 : bool for_melt,
1070 : struct GNUNET_CRYPTO_CSPublicRPairP crps[static cdrs_length])
1071 135 : {
1072 135 : enum TALER_ErrorCode ec = TALER_EC_INVALID;
1073 : unsigned int rpos;
1074 : unsigned int rend;
1075 : unsigned int wpos;
1076 :
1077 135 : memset (crps,
1078 : 0,
1079 : sizeof (*crps) * cdrs_length);
1080 135 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1081 : "Starting R derivation process\n");
1082 135 : if (GNUNET_OK !=
1083 135 : try_connect (dh))
1084 : {
1085 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1086 : "Failed to connect to helper\n");
1087 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
1088 : }
1089 :
1090 135 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1091 : "Requesting %u R pairs\n",
1092 : cdrs_length);
1093 135 : rpos = 0;
1094 135 : rend = 0;
1095 135 : wpos = 0;
1096 270 : while (rpos < cdrs_length)
1097 : {
1098 135 : unsigned int mlen = sizeof (struct TALER_CRYPTO_BatchDeriveRequest);
1099 :
1100 1236 : while ( (rend < cdrs_length) &&
1101 1101 : (mlen + sizeof (struct TALER_CRYPTO_CsRDeriveRequest)
1102 : < UINT16_MAX) )
1103 : {
1104 1101 : mlen += sizeof (struct TALER_CRYPTO_CsRDeriveRequest);
1105 1101 : rend++;
1106 : }
1107 135 : {
1108 135 : char obuf[mlen] GNUNET_ALIGN;
1109 135 : struct TALER_CRYPTO_BatchDeriveRequest *bdr
1110 : = (struct TALER_CRYPTO_BatchDeriveRequest *) obuf;
1111 : void *wbuf;
1112 :
1113 135 : bdr->header.type = htons (TALER_HELPER_CS_MT_REQ_BATCH_RDERIVE);
1114 135 : bdr->header.size = htons (mlen);
1115 135 : bdr->batch_size = htonl (rend - rpos);
1116 135 : wbuf = &bdr[1];
1117 1236 : for (unsigned int i = rpos; i<rend; i++)
1118 : {
1119 1101 : struct TALER_CRYPTO_CsRDeriveRequest *rdr = wbuf;
1120 1101 : const struct TALER_CRYPTO_CsDeriveRequest *cdr = &cdrs[i];
1121 :
1122 1101 : rdr->header.size = htons (sizeof (*rdr));
1123 1101 : rdr->header.type = htons (TALER_HELPER_CS_MT_REQ_RDERIVE);
1124 1101 : rdr->for_melt = htonl (for_melt ? 1 : 0);
1125 1101 : rdr->h_cs = *cdr->h_cs;
1126 1101 : rdr->nonce = *cdr->nonce;
1127 1101 : wbuf += sizeof (*rdr);
1128 : }
1129 135 : GNUNET_assert (wbuf == &obuf[mlen]);
1130 135 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1131 : "Sending batch request [%u-%u)\n",
1132 : rpos,
1133 : rend);
1134 135 : if (GNUNET_OK !=
1135 135 : TALER_crypto_helper_send_all (dh->sock,
1136 : obuf,
1137 135 : sizeof (obuf)))
1138 : {
1139 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1140 : "send");
1141 0 : do_disconnect (dh);
1142 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
1143 : }
1144 : } /* end of obuf scope */
1145 135 : rpos = rend;
1146 : {
1147 : char buf[UINT16_MAX];
1148 135 : size_t off = 0;
1149 135 : const struct GNUNET_MessageHeader *hdr
1150 : = (const struct GNUNET_MessageHeader *) buf;
1151 135 : bool finished = false;
1152 :
1153 : while (1)
1154 584 : {
1155 : uint16_t msize;
1156 : ssize_t ret;
1157 :
1158 719 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1159 : "Awaiting reply at %u (up to %u)\n",
1160 : wpos,
1161 : rend);
1162 854 : ret = recv (dh->sock,
1163 719 : &buf[off],
1164 : sizeof (buf) - off,
1165 135 : (finished && (0 == off))
1166 : ? MSG_DONTWAIT
1167 : : 0);
1168 719 : if (ret < 0)
1169 : {
1170 135 : if (EINTR == errno)
1171 0 : continue;
1172 135 : if (EAGAIN == errno)
1173 : {
1174 135 : GNUNET_assert (finished);
1175 135 : GNUNET_assert (0 == off);
1176 135 : break;
1177 : }
1178 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1179 : "recv");
1180 0 : do_disconnect (dh);
1181 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
1182 : }
1183 584 : if (0 == ret)
1184 : {
1185 0 : GNUNET_break (0 == off);
1186 0 : if (! finished)
1187 0 : return TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG;
1188 0 : if (TALER_EC_NONE == ec)
1189 0 : break;
1190 0 : return ec;
1191 : }
1192 584 : off += ret;
1193 1685 : more:
1194 1685 : if (off < sizeof (struct GNUNET_MessageHeader))
1195 584 : continue;
1196 1101 : msize = ntohs (hdr->size);
1197 1101 : if (off < msize)
1198 0 : continue;
1199 1101 : switch (ntohs (hdr->type))
1200 : {
1201 346 : case TALER_HELPER_CS_MT_RES_RDERIVE:
1202 346 : if (msize != sizeof (struct TALER_CRYPTO_RDeriveResponse))
1203 : {
1204 0 : GNUNET_break_op (0);
1205 0 : do_disconnect (dh);
1206 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
1207 : }
1208 346 : if (finished)
1209 : {
1210 0 : GNUNET_break_op (0);
1211 0 : do_disconnect (dh);
1212 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
1213 : }
1214 : {
1215 346 : const struct TALER_CRYPTO_RDeriveResponse *rdr =
1216 : (const struct TALER_CRYPTO_RDeriveResponse *) buf;
1217 :
1218 346 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1219 : "Received %u R pair\n",
1220 : wpos);
1221 346 : crps[wpos] = rdr->r_pub;
1222 346 : wpos++;
1223 346 : if (wpos == rend)
1224 : {
1225 105 : if (TALER_EC_INVALID == ec)
1226 105 : ec = TALER_EC_NONE;
1227 105 : finished = true;
1228 : }
1229 346 : break;
1230 : }
1231 755 : case TALER_HELPER_CS_MT_RES_RDERIVE_FAILURE:
1232 755 : if (msize != sizeof (struct TALER_CRYPTO_RDeriveFailure))
1233 : {
1234 0 : GNUNET_break_op (0);
1235 0 : do_disconnect (dh);
1236 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
1237 : }
1238 : {
1239 755 : const struct TALER_CRYPTO_RDeriveFailure *rdf =
1240 : (const struct TALER_CRYPTO_RDeriveFailure *) buf;
1241 :
1242 755 : ec = (enum TALER_ErrorCode) (int) ntohl (rdf->ec);
1243 755 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1244 : "R derivation %u failed with status %d!\n",
1245 : wpos,
1246 : ec);
1247 755 : wpos++;
1248 755 : if (wpos == rend)
1249 : {
1250 30 : finished = true;
1251 : }
1252 755 : break;
1253 : }
1254 0 : case TALER_HELPER_CS_MT_AVAIL:
1255 0 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1256 : "Received new key!\n");
1257 0 : if (GNUNET_OK !=
1258 0 : handle_mt_avail (dh,
1259 : hdr))
1260 : {
1261 0 : GNUNET_break_op (0);
1262 0 : do_disconnect (dh);
1263 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
1264 : }
1265 0 : break; /* while(1) loop ensures we recvfrom() again */
1266 0 : case TALER_HELPER_CS_MT_PURGE:
1267 0 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1268 : "Received revocation!\n");
1269 0 : if (GNUNET_OK !=
1270 0 : handle_mt_purge (dh,
1271 : hdr))
1272 : {
1273 0 : GNUNET_break_op (0);
1274 0 : do_disconnect (dh);
1275 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
1276 : }
1277 0 : break; /* while(1) loop ensures we recvfrom() again */
1278 0 : case TALER_HELPER_CS_SYNCED:
1279 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1280 : "Synchronized add odd time with CS helper!\n");
1281 0 : dh->synced = true;
1282 0 : break;
1283 0 : default:
1284 0 : GNUNET_break_op (0);
1285 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1286 : "Received unexpected message of type %u\n",
1287 : ntohs (hdr->type));
1288 0 : do_disconnect (dh);
1289 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
1290 : }
1291 1101 : memmove (buf,
1292 1101 : &buf[msize],
1293 : off - msize);
1294 1101 : off -= msize;
1295 1101 : goto more;
1296 : } /* while(1) */
1297 : } /* scope */
1298 : } /* while (rpos < cdrs_length) */
1299 135 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1300 : "Existing with %u signatures and status %d\n",
1301 : wpos,
1302 : ec);
1303 135 : return ec;
1304 : }
1305 :
1306 :
1307 : void
1308 27 : TALER_CRYPTO_helper_cs_disconnect (
1309 : struct TALER_CRYPTO_CsDenominationHelper *dh)
1310 : {
1311 27 : if (-1 != dh->sock)
1312 26 : do_disconnect (dh);
1313 27 : GNUNET_free (dh);
1314 27 : }
1315 :
1316 :
1317 : /* end of crypto_helper_cs.c */
|