Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2020, 2021 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_rsa.c
18 : * @brief utility functions for running out-of-process private key operations
19 : * @author Christian Grothoff
20 : */
21 : #include "platform.h"
22 : #include "taler/taler_util.h"
23 : #include "taler/taler_signatures.h"
24 : #include "crypto_helper_common.h"
25 : #include "secmod_rsa.h"
26 : #include <poll.h>
27 :
28 :
29 : struct TALER_CRYPTO_RsaDenominationHelper
30 : {
31 : /**
32 : * Function to call with updates to available key material.
33 : */
34 : TALER_CRYPTO_RsaDenominationKeyStatusCallback 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_RsaDenominationHelper *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 1742 : try_connect (struct TALER_CRYPTO_RsaDenominationHelper *dh)
83 : {
84 1742 : if (-1 != dh->sock)
85 1715 : 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_rsa_poll (dh);
109 26 : return GNUNET_OK;
110 : }
111 :
112 :
113 : struct TALER_CRYPTO_RsaDenominationHelper *
114 27 : TALER_CRYPTO_helper_rsa_connect (
115 : const struct GNUNET_CONFIGURATION_Handle *cfg,
116 : const char *section,
117 : TALER_CRYPTO_RsaDenominationKeyStatusCallback dkc,
118 : void *dkc_cls)
119 : {
120 : struct TALER_CRYPTO_RsaDenominationHelper *dh;
121 : char *unixpath;
122 : char *secname;
123 :
124 27 : GNUNET_asprintf (&secname,
125 : "%s-secmod-rsa",
126 : section);
127 :
128 27 : if (GNUNET_OK !=
129 27 : GNUNET_CONFIGURATION_get_value_filename (cfg,
130 : secname,
131 : "UNIXPATH",
132 : &unixpath))
133 : {
134 0 : GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
135 : secname,
136 : "UNIXPATH");
137 0 : GNUNET_free (secname);
138 0 : return NULL;
139 : }
140 : /* we use >= here because we want the sun_path to always
141 : be 0-terminated */
142 27 : if (strlen (unixpath) >= sizeof (dh->sa.sun_path))
143 : {
144 0 : GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
145 : secname,
146 : "UNIXPATH",
147 : "path too long");
148 0 : GNUNET_free (unixpath);
149 0 : GNUNET_free (secname);
150 0 : return NULL;
151 : }
152 27 : GNUNET_free (secname);
153 27 : dh = GNUNET_new (struct TALER_CRYPTO_RsaDenominationHelper);
154 27 : dh->dkc = dkc;
155 27 : dh->dkc_cls = dkc_cls;
156 27 : dh->sa.sun_family = AF_UNIX;
157 27 : strncpy (dh->sa.sun_path,
158 : unixpath,
159 : sizeof (dh->sa.sun_path) - 1);
160 27 : GNUNET_free (unixpath);
161 27 : dh->sock = -1;
162 27 : if (GNUNET_OK !=
163 27 : try_connect (dh))
164 : {
165 1 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
166 : "Could not connect to %s. Will keep trying\n",
167 : "taler-exchange-helper-secmod-rsa");
168 : }
169 27 : return dh;
170 : }
171 :
172 :
173 : /**
174 : * Handle a #TALER_HELPER_RSA_MT_AVAIL message from the helper.
175 : *
176 : * @param dh helper context
177 : * @param hdr message that we received
178 : * @return #GNUNET_OK on success
179 : */
180 : static enum GNUNET_GenericReturnValue
181 268 : handle_mt_avail (struct TALER_CRYPTO_RsaDenominationHelper *dh,
182 : const struct GNUNET_MessageHeader *hdr)
183 : {
184 268 : const struct TALER_CRYPTO_RsaKeyAvailableNotification *kan
185 : = (const struct TALER_CRYPTO_RsaKeyAvailableNotification *) hdr;
186 268 : const char *buf = (const char *) &kan[1];
187 : const char *section_name;
188 : uint16_t ps;
189 : uint16_t snl;
190 :
191 268 : if (sizeof (*kan) > ntohs (hdr->size))
192 : {
193 0 : GNUNET_break_op (0);
194 0 : return GNUNET_SYSERR;
195 : }
196 268 : ps = ntohs (kan->pub_size);
197 268 : snl = ntohs (kan->section_name_len);
198 268 : if (ntohs (hdr->size) != sizeof (*kan) + ps + snl)
199 : {
200 0 : GNUNET_break_op (0);
201 0 : return GNUNET_SYSERR;
202 : }
203 268 : if (0 == snl)
204 : {
205 0 : GNUNET_break_op (0);
206 0 : return GNUNET_SYSERR;
207 : }
208 268 : section_name = &buf[ps];
209 268 : if ('\0' != section_name[snl - 1])
210 : {
211 0 : GNUNET_break_op (0);
212 0 : return GNUNET_SYSERR;
213 : }
214 :
215 : {
216 : struct GNUNET_CRYPTO_BlindSignPublicKey *bs_pub;
217 : struct TALER_RsaPubHashP h_rsa;
218 :
219 268 : bs_pub = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey);
220 268 : bs_pub->cipher = GNUNET_CRYPTO_BSA_RSA;
221 : bs_pub->details.rsa_public_key
222 536 : = GNUNET_CRYPTO_rsa_public_key_decode (buf,
223 268 : ntohs (kan->pub_size));
224 268 : if (NULL == bs_pub->details.rsa_public_key)
225 : {
226 0 : GNUNET_break_op (0);
227 0 : GNUNET_free (bs_pub);
228 0 : return GNUNET_SYSERR;
229 : }
230 268 : bs_pub->rc = 1;
231 268 : GNUNET_CRYPTO_rsa_public_key_hash (bs_pub->details.rsa_public_key,
232 : &bs_pub->pub_key_hash);
233 268 : h_rsa.hash = bs_pub->pub_key_hash;
234 268 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
235 : "Received RSA key %s (%s)\n",
236 : GNUNET_h2s (&bs_pub->pub_key_hash),
237 : section_name);
238 268 : if (GNUNET_OK !=
239 268 : TALER_exchange_secmod_rsa_verify (
240 : &h_rsa,
241 : section_name,
242 : GNUNET_TIME_timestamp_ntoh (kan->anchor_time),
243 : GNUNET_TIME_relative_ntoh (kan->duration_withdraw),
244 : &kan->secm_pub,
245 : &kan->secm_sig))
246 : {
247 0 : GNUNET_break_op (0);
248 0 : GNUNET_CRYPTO_blind_sign_pub_decref (bs_pub);
249 0 : return GNUNET_SYSERR;
250 : }
251 268 : dh->dkc (dh->dkc_cls,
252 : section_name,
253 : GNUNET_TIME_timestamp_ntoh (kan->anchor_time),
254 : GNUNET_TIME_relative_ntoh (kan->duration_withdraw),
255 : &h_rsa,
256 : bs_pub,
257 : &kan->secm_pub,
258 : &kan->secm_sig);
259 268 : GNUNET_CRYPTO_blind_sign_pub_decref (bs_pub);
260 : }
261 268 : return GNUNET_OK;
262 : }
263 :
264 :
265 : /**
266 : * Handle a #TALER_HELPER_RSA_MT_PURGE message from the helper.
267 : *
268 : * @param dh helper context
269 : * @param hdr message that we received
270 : * @return #GNUNET_OK on success
271 : */
272 : static enum GNUNET_GenericReturnValue
273 3 : handle_mt_purge (struct TALER_CRYPTO_RsaDenominationHelper *dh,
274 : const struct GNUNET_MessageHeader *hdr)
275 : {
276 3 : const struct TALER_CRYPTO_RsaKeyPurgeNotification *pn
277 : = (const struct TALER_CRYPTO_RsaKeyPurgeNotification *) hdr;
278 :
279 3 : if (sizeof (*pn) != ntohs (hdr->size))
280 : {
281 0 : GNUNET_break_op (0);
282 0 : return GNUNET_SYSERR;
283 : }
284 3 : GNUNET_log (GNUNET_ERROR_TYPE_INFO,
285 : "Received revocation of denomination key %s\n",
286 : GNUNET_h2s (&pn->h_rsa.hash));
287 3 : dh->dkc (dh->dkc_cls,
288 : NULL,
289 3 : GNUNET_TIME_UNIT_ZERO_TS,
290 3 : GNUNET_TIME_UNIT_ZERO,
291 : &pn->h_rsa,
292 : NULL,
293 : NULL,
294 : NULL);
295 3 : return GNUNET_OK;
296 : }
297 :
298 :
299 : void
300 738 : TALER_CRYPTO_helper_rsa_poll (struct TALER_CRYPTO_RsaDenominationHelper *dh)
301 : {
302 : char buf[UINT16_MAX];
303 738 : size_t off = 0;
304 738 : unsigned int retry_limit = 3;
305 738 : const struct GNUNET_MessageHeader *hdr
306 : = (const struct GNUNET_MessageHeader *) buf;
307 :
308 738 : if (GNUNET_OK !=
309 738 : try_connect (dh))
310 0 : return; /* give up */
311 : while (1)
312 32 : {
313 : uint16_t msize;
314 : ssize_t ret;
315 :
316 770 : ret = recv (dh->sock,
317 : buf + off,
318 : sizeof (buf) - off,
319 770 : (dh->synced && (0 == off))
320 : ? MSG_DONTWAIT
321 : : 0);
322 770 : if (ret < 0)
323 : {
324 738 : if (EINTR == errno)
325 0 : continue;
326 738 : if (EAGAIN == errno)
327 : {
328 738 : GNUNET_assert (dh->synced);
329 738 : GNUNET_assert (0 == off);
330 738 : break;
331 : }
332 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
333 : "recv");
334 0 : do_disconnect (dh);
335 0 : if (0 == retry_limit)
336 0 : return; /* give up */
337 0 : if (GNUNET_OK !=
338 0 : try_connect (dh))
339 0 : return; /* give up */
340 0 : retry_limit--;
341 0 : continue;
342 : }
343 32 : if (0 == ret)
344 : {
345 0 : GNUNET_break (0 == off);
346 0 : return;
347 : }
348 32 : off += ret;
349 329 : more:
350 329 : if (off < sizeof (struct GNUNET_MessageHeader))
351 32 : continue;
352 297 : msize = ntohs (hdr->size);
353 297 : if (msize < sizeof (struct GNUNET_MessageHeader))
354 : {
355 0 : GNUNET_break_op (0);
356 0 : do_disconnect (dh);
357 0 : return;
358 : }
359 297 : if (off < msize)
360 0 : continue;
361 297 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
362 : "Received message of type %u and length %u\n",
363 : (unsigned int) ntohs (hdr->type),
364 : (unsigned int) msize);
365 297 : switch (ntohs (hdr->type))
366 : {
367 268 : case TALER_HELPER_RSA_MT_AVAIL:
368 268 : if (GNUNET_OK !=
369 268 : handle_mt_avail (dh,
370 : hdr))
371 : {
372 0 : GNUNET_break_op (0);
373 0 : do_disconnect (dh);
374 0 : return;
375 : }
376 268 : break;
377 3 : case TALER_HELPER_RSA_MT_PURGE:
378 3 : if (GNUNET_OK !=
379 3 : handle_mt_purge (dh,
380 : hdr))
381 : {
382 0 : GNUNET_break_op (0);
383 0 : do_disconnect (dh);
384 0 : return;
385 : }
386 3 : break;
387 26 : case TALER_HELPER_RSA_SYNCED:
388 26 : GNUNET_log (GNUNET_ERROR_TYPE_INFO,
389 : "Now synchronized with RSA helper\n");
390 26 : dh->synced = true;
391 26 : break;
392 0 : default:
393 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
394 : "Received unexpected message of type %d (len: %u)\n",
395 : (unsigned int) ntohs (hdr->type),
396 : (unsigned int) msize);
397 0 : GNUNET_break_op (0);
398 0 : do_disconnect (dh);
399 0 : return;
400 : }
401 297 : memmove (buf,
402 297 : &buf[msize],
403 : off - msize);
404 297 : off -= msize;
405 297 : goto more;
406 : }
407 : }
408 :
409 :
410 : enum TALER_ErrorCode
411 974 : TALER_CRYPTO_helper_rsa_batch_sign (
412 : struct TALER_CRYPTO_RsaDenominationHelper *dh,
413 : unsigned int rsrs_length,
414 : const struct TALER_CRYPTO_RsaSignRequest rsrs[static rsrs_length],
415 : struct TALER_BlindedDenominationSignature bss[static rsrs_length])
416 974 : {
417 974 : enum TALER_ErrorCode ec = TALER_EC_INVALID;
418 : unsigned int rpos;
419 : unsigned int rend;
420 : unsigned int wpos;
421 :
422 974 : memset (bss,
423 : 0,
424 : sizeof (*bss) * rsrs_length);
425 : /* Every request must fit into an IPC message of its own, together
426 : with the batch header; otherwise it could never be transmitted. */
427 2397 : for (unsigned int i = 0; i<rsrs_length; i++)
428 : {
429 1423 : if (rsrs[i].msg_size >=
430 : UINT16_MAX
431 : - sizeof (struct TALER_CRYPTO_BatchSignRequest)
432 : - sizeof (struct TALER_CRYPTO_SignRequest))
433 : {
434 0 : GNUNET_break_op (0);
435 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
436 : "Message to sign is too large (%llu bytes)\n",
437 : (unsigned long long) rsrs[i].msg_size);
438 0 : return TALER_EC_GENERIC_PARAMETER_MALFORMED;
439 : }
440 : }
441 974 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
442 : "Starting signature process\n");
443 974 : if (GNUNET_OK !=
444 974 : try_connect (dh))
445 : {
446 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
447 : "Failed to connect to helper\n");
448 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
449 : }
450 974 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
451 : "Requesting %u signatures\n",
452 : rsrs_length);
453 974 : rpos = 0;
454 974 : rend = 0;
455 974 : wpos = 0;
456 1948 : while (rpos < rsrs_length)
457 : {
458 974 : unsigned int mlen = sizeof (struct TALER_CRYPTO_BatchSignRequest);
459 :
460 : /* as each individual request fits, this loop always advances rend
461 : at least once, and thus the outer loop makes progress */
462 2397 : while ( (rend < rsrs_length) &&
463 : (mlen
464 : + sizeof (struct TALER_CRYPTO_SignRequest)
465 1423 : + rsrs[rend].msg_size < UINT16_MAX) )
466 : {
467 1423 : mlen += sizeof (struct TALER_CRYPTO_SignRequest) + rsrs[rend].msg_size;
468 1423 : rend++;
469 : }
470 974 : {
471 974 : char obuf[mlen] GNUNET_ALIGN;
472 974 : struct TALER_CRYPTO_BatchSignRequest *bsr
473 : = (struct TALER_CRYPTO_BatchSignRequest *) obuf;
474 : void *wbuf;
475 :
476 974 : bsr->header.type = htons (TALER_HELPER_RSA_MT_REQ_BATCH_SIGN);
477 974 : bsr->header.size = htons (mlen);
478 974 : bsr->batch_size = htonl (rend - rpos);
479 974 : wbuf = &bsr[1];
480 2397 : for (unsigned int i = rpos; i<rend; i++)
481 : {
482 1423 : struct TALER_CRYPTO_SignRequest *sr = wbuf;
483 1423 : const struct TALER_CRYPTO_RsaSignRequest *rsr = &rsrs[i];
484 :
485 1423 : sr->header.type = htons (TALER_HELPER_RSA_MT_REQ_SIGN);
486 1423 : sr->header.size = htons (sizeof (*sr) + rsr->msg_size);
487 1423 : sr->reserved = htonl (0);
488 1423 : sr->h_rsa = *rsr->h_rsa;
489 1423 : GNUNET_memcpy (&sr[1],
490 : rsr->msg,
491 : rsr->msg_size);
492 1423 : wbuf += sizeof (*sr) + rsr->msg_size;
493 : }
494 974 : GNUNET_assert (wbuf == &obuf[mlen]);
495 974 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
496 : "Sending batch request [%u-%u)\n",
497 : rpos,
498 : rend);
499 974 : if (GNUNET_OK !=
500 974 : TALER_crypto_helper_send_all (dh->sock,
501 : obuf,
502 974 : sizeof (obuf)))
503 : {
504 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
505 : "send");
506 0 : do_disconnect (dh);
507 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
508 : }
509 : }
510 974 : rpos = rend;
511 : {
512 : char buf[UINT16_MAX];
513 974 : size_t off = 0;
514 974 : const struct GNUNET_MessageHeader *hdr
515 : = (const struct GNUNET_MessageHeader *) buf;
516 974 : bool finished = false;
517 :
518 : while (1)
519 1181 : {
520 : uint16_t msize;
521 : ssize_t ret;
522 :
523 2155 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
524 : "Awaiting reply at %u (up to %u)\n",
525 : wpos,
526 : rend);
527 3129 : ret = recv (dh->sock,
528 2155 : &buf[off],
529 : sizeof (buf) - off,
530 974 : (finished && (0 == off))
531 : ? MSG_DONTWAIT
532 : : 0);
533 2155 : if (ret < 0)
534 : {
535 974 : if (EINTR == errno)
536 0 : continue;
537 974 : if (EAGAIN == errno)
538 : {
539 974 : GNUNET_assert (finished);
540 974 : GNUNET_assert (0 == off);
541 974 : break;
542 : }
543 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
544 : "recv");
545 0 : do_disconnect (dh);
546 0 : ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
547 0 : break;
548 : }
549 1181 : if (0 == ret)
550 : {
551 0 : GNUNET_break (0 == off);
552 0 : if (! finished)
553 0 : ec = TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG;
554 0 : if (TALER_EC_NONE == ec)
555 0 : break;
556 0 : return ec;
557 : }
558 1181 : off += ret;
559 2604 : more:
560 2604 : if (off < sizeof (struct GNUNET_MessageHeader))
561 1181 : continue;
562 1423 : msize = ntohs (hdr->size);
563 1423 : if (msize < sizeof (struct GNUNET_MessageHeader))
564 : {
565 0 : GNUNET_break_op (0);
566 0 : do_disconnect (dh);
567 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
568 : }
569 1423 : if (off < msize)
570 0 : continue;
571 1423 : switch (ntohs (hdr->type))
572 : {
573 1152 : case TALER_HELPER_RSA_MT_RES_SIGNATURE:
574 1152 : if (msize < sizeof (struct TALER_CRYPTO_SignResponse))
575 : {
576 0 : GNUNET_break_op (0);
577 0 : do_disconnect (dh);
578 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
579 : }
580 1152 : if (finished)
581 : {
582 0 : GNUNET_break_op (0);
583 0 : do_disconnect (dh);
584 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
585 : }
586 : {
587 1152 : const struct TALER_CRYPTO_SignResponse *sr =
588 : (const struct TALER_CRYPTO_SignResponse *) buf;
589 : struct GNUNET_CRYPTO_RsaSignature *rsa_signature;
590 : struct GNUNET_CRYPTO_BlindedSignature *blind_sig;
591 :
592 1152 : rsa_signature = GNUNET_CRYPTO_rsa_signature_decode (
593 1152 : &sr[1],
594 : msize - sizeof (*sr));
595 1152 : if (NULL == rsa_signature)
596 : {
597 0 : GNUNET_break_op (0);
598 0 : do_disconnect (dh);
599 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
600 : }
601 1152 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
602 : "Received %u signature\n",
603 : wpos);
604 1152 : blind_sig = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature);
605 1152 : blind_sig->cipher = GNUNET_CRYPTO_BSA_RSA;
606 1152 : blind_sig->rc = 1;
607 1152 : blind_sig->details.blinded_rsa_signature = rsa_signature;
608 1152 : bss[wpos].blinded_sig = blind_sig;
609 1152 : wpos++;
610 1152 : if (wpos == rend)
611 : {
612 959 : if (TALER_EC_INVALID == ec)
613 959 : ec = TALER_EC_NONE;
614 959 : finished = true;
615 : }
616 1152 : break;
617 : }
618 271 : case TALER_HELPER_RSA_MT_RES_SIGN_FAILURE:
619 271 : if (msize != sizeof (struct TALER_CRYPTO_SignFailure))
620 : {
621 0 : GNUNET_break_op (0);
622 0 : do_disconnect (dh);
623 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
624 : }
625 : {
626 271 : const struct TALER_CRYPTO_SignFailure *sf =
627 : (const struct TALER_CRYPTO_SignFailure *) buf;
628 :
629 271 : ec = (enum TALER_ErrorCode) (int) ntohl (sf->ec);
630 271 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
631 : "Signing %u failed with status %d!\n",
632 : wpos,
633 : ec);
634 271 : wpos++;
635 271 : if (wpos == rend)
636 : {
637 15 : finished = true;
638 : }
639 271 : break;
640 : }
641 0 : case TALER_HELPER_RSA_MT_AVAIL:
642 0 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
643 : "Received new key!\n");
644 0 : if (GNUNET_OK !=
645 0 : handle_mt_avail (dh,
646 : hdr))
647 : {
648 0 : GNUNET_break_op (0);
649 0 : do_disconnect (dh);
650 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
651 : }
652 0 : break; /* while(1) loop ensures we recvfrom() again */
653 0 : case TALER_HELPER_RSA_MT_PURGE:
654 0 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
655 : "Received revocation!\n");
656 0 : if (GNUNET_OK !=
657 0 : handle_mt_purge (dh,
658 : hdr))
659 : {
660 0 : GNUNET_break_op (0);
661 0 : do_disconnect (dh);
662 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
663 : }
664 0 : break; /* while(1) loop ensures we recvfrom() again */
665 0 : case TALER_HELPER_RSA_SYNCED:
666 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
667 : "Synchronized add odd time with RSA helper!\n");
668 0 : dh->synced = true;
669 0 : break;
670 0 : default:
671 0 : GNUNET_break_op (0);
672 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
673 : "Received unexpected message of type %u\n",
674 : ntohs (hdr->type));
675 0 : do_disconnect (dh);
676 0 : return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG;
677 : }
678 1423 : memmove (buf,
679 1423 : &buf[msize],
680 : off - msize);
681 1423 : off -= msize;
682 1423 : goto more;
683 : } /* while(1) */
684 : } /* scope */
685 : } /* while (rpos < rsrs_length) */
686 974 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
687 : "Existing with %u signatures and status %d\n",
688 : wpos,
689 : ec);
690 974 : return ec;
691 : }
692 :
693 :
694 : void
695 3 : TALER_CRYPTO_helper_rsa_revoke (
696 : struct TALER_CRYPTO_RsaDenominationHelper *dh,
697 : const struct TALER_RsaPubHashP *h_rsa)
698 : {
699 3 : struct TALER_CRYPTO_RevokeRequest rr = {
700 3 : .header.size = htons (sizeof (rr)),
701 3 : .header.type = htons (TALER_HELPER_RSA_MT_REQ_REVOKE),
702 : .h_rsa = *h_rsa
703 : };
704 :
705 3 : if (GNUNET_OK !=
706 3 : try_connect (dh))
707 0 : return; /* give up */
708 3 : if (GNUNET_OK !=
709 3 : TALER_crypto_helper_send_all (dh->sock,
710 : &rr,
711 : sizeof (rr)))
712 : {
713 0 : GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
714 : "send");
715 0 : do_disconnect (dh);
716 0 : return;
717 : }
718 3 : GNUNET_log (GNUNET_ERROR_TYPE_INFO,
719 : "Requested revocation of denomination key %s\n",
720 : GNUNET_h2s (&h_rsa->hash));
721 : }
722 :
723 :
724 : void
725 27 : TALER_CRYPTO_helper_rsa_disconnect (
726 : struct TALER_CRYPTO_RsaDenominationHelper *dh)
727 : {
728 27 : if (-1 != dh->sock)
729 26 : do_disconnect (dh);
730 27 : GNUNET_free (dh);
731 27 : }
732 :
733 :
734 : /* end of crypto_helper_denom.c */
|