crypto_helper_rsa.c (21246B)
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 do_disconnect (struct TALER_CRYPTO_RsaDenominationHelper *dh) 67 { 68 GNUNET_break (0 == close (dh->sock)); 69 dh->sock = -1; 70 dh->synced = false; 71 } 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 try_connect (struct TALER_CRYPTO_RsaDenominationHelper *dh) 83 { 84 if (-1 != dh->sock) 85 return GNUNET_OK; 86 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 87 "Establishing connection!\n"); 88 dh->sock = socket (AF_UNIX, 89 SOCK_STREAM, 90 0); 91 if (-1 == dh->sock) 92 { 93 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, 94 "socket"); 95 return GNUNET_SYSERR; 96 } 97 if (0 != 98 connect (dh->sock, 99 (const struct sockaddr *) &dh->sa, 100 sizeof (dh->sa))) 101 { 102 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, 103 "connect", 104 dh->sa.sun_path); 105 do_disconnect (dh); 106 return GNUNET_SYSERR; 107 } 108 TALER_CRYPTO_helper_rsa_poll (dh); 109 return GNUNET_OK; 110 } 111 112 113 struct TALER_CRYPTO_RsaDenominationHelper * 114 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 GNUNET_asprintf (&secname, 125 "%s-secmod-rsa", 126 section); 127 128 if (GNUNET_OK != 129 GNUNET_CONFIGURATION_get_value_filename (cfg, 130 secname, 131 "UNIXPATH", 132 &unixpath)) 133 { 134 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 135 secname, 136 "UNIXPATH"); 137 GNUNET_free (secname); 138 return NULL; 139 } 140 /* we use >= here because we want the sun_path to always 141 be 0-terminated */ 142 if (strlen (unixpath) >= sizeof (dh->sa.sun_path)) 143 { 144 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, 145 secname, 146 "UNIXPATH", 147 "path too long"); 148 GNUNET_free (unixpath); 149 GNUNET_free (secname); 150 return NULL; 151 } 152 GNUNET_free (secname); 153 dh = GNUNET_new (struct TALER_CRYPTO_RsaDenominationHelper); 154 dh->dkc = dkc; 155 dh->dkc_cls = dkc_cls; 156 dh->sa.sun_family = AF_UNIX; 157 strncpy (dh->sa.sun_path, 158 unixpath, 159 sizeof (dh->sa.sun_path) - 1); 160 GNUNET_free (unixpath); 161 dh->sock = -1; 162 if (GNUNET_OK != 163 try_connect (dh)) 164 { 165 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 166 "Could not connect to %s. Will keep trying\n", 167 "taler-exchange-helper-secmod-rsa"); 168 } 169 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 handle_mt_avail (struct TALER_CRYPTO_RsaDenominationHelper *dh, 182 const struct GNUNET_MessageHeader *hdr) 183 { 184 const struct TALER_CRYPTO_RsaKeyAvailableNotification *kan 185 = (const struct TALER_CRYPTO_RsaKeyAvailableNotification *) hdr; 186 const char *buf = (const char *) &kan[1]; 187 const char *section_name; 188 uint16_t ps; 189 uint16_t snl; 190 191 if (sizeof (*kan) > ntohs (hdr->size)) 192 { 193 GNUNET_break_op (0); 194 return GNUNET_SYSERR; 195 } 196 ps = ntohs (kan->pub_size); 197 snl = ntohs (kan->section_name_len); 198 if (ntohs (hdr->size) != sizeof (*kan) + ps + snl) 199 { 200 GNUNET_break_op (0); 201 return GNUNET_SYSERR; 202 } 203 if (0 == snl) 204 { 205 GNUNET_break_op (0); 206 return GNUNET_SYSERR; 207 } 208 section_name = &buf[ps]; 209 if ('\0' != section_name[snl - 1]) 210 { 211 GNUNET_break_op (0); 212 return GNUNET_SYSERR; 213 } 214 215 { 216 struct GNUNET_CRYPTO_BlindSignPublicKey *bs_pub; 217 struct TALER_RsaPubHashP h_rsa; 218 219 bs_pub = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey); 220 bs_pub->cipher = GNUNET_CRYPTO_BSA_RSA; 221 bs_pub->details.rsa_public_key 222 = GNUNET_CRYPTO_rsa_public_key_decode (buf, 223 ntohs (kan->pub_size)); 224 if (NULL == bs_pub->details.rsa_public_key) 225 { 226 GNUNET_break_op (0); 227 GNUNET_free (bs_pub); 228 return GNUNET_SYSERR; 229 } 230 bs_pub->rc = 1; 231 GNUNET_CRYPTO_rsa_public_key_hash (bs_pub->details.rsa_public_key, 232 &bs_pub->pub_key_hash); 233 h_rsa.hash = bs_pub->pub_key_hash; 234 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 if (GNUNET_OK != 239 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 GNUNET_break_op (0); 248 GNUNET_CRYPTO_blind_sign_pub_decref (bs_pub); 249 return GNUNET_SYSERR; 250 } 251 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 GNUNET_CRYPTO_blind_sign_pub_decref (bs_pub); 260 } 261 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 handle_mt_purge (struct TALER_CRYPTO_RsaDenominationHelper *dh, 274 const struct GNUNET_MessageHeader *hdr) 275 { 276 const struct TALER_CRYPTO_RsaKeyPurgeNotification *pn 277 = (const struct TALER_CRYPTO_RsaKeyPurgeNotification *) hdr; 278 279 if (sizeof (*pn) != ntohs (hdr->size)) 280 { 281 GNUNET_break_op (0); 282 return GNUNET_SYSERR; 283 } 284 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 285 "Received revocation of denomination key %s\n", 286 GNUNET_h2s (&pn->h_rsa.hash)); 287 dh->dkc (dh->dkc_cls, 288 NULL, 289 GNUNET_TIME_UNIT_ZERO_TS, 290 GNUNET_TIME_UNIT_ZERO, 291 &pn->h_rsa, 292 NULL, 293 NULL, 294 NULL); 295 return GNUNET_OK; 296 } 297 298 299 void 300 TALER_CRYPTO_helper_rsa_poll (struct TALER_CRYPTO_RsaDenominationHelper *dh) 301 { 302 char buf[UINT16_MAX]; 303 size_t off = 0; 304 unsigned int retry_limit = 3; 305 const struct GNUNET_MessageHeader *hdr 306 = (const struct GNUNET_MessageHeader *) buf; 307 308 if (GNUNET_OK != 309 try_connect (dh)) 310 return; /* give up */ 311 while (1) 312 { 313 uint16_t msize; 314 ssize_t ret; 315 316 ret = recv (dh->sock, 317 buf + off, 318 sizeof (buf) - off, 319 (dh->synced && (0 == off)) 320 ? MSG_DONTWAIT 321 : 0); 322 if (ret < 0) 323 { 324 if (EINTR == errno) 325 continue; 326 if (EAGAIN == errno) 327 { 328 GNUNET_assert (dh->synced); 329 GNUNET_assert (0 == off); 330 break; 331 } 332 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, 333 "recv"); 334 do_disconnect (dh); 335 if (0 == retry_limit) 336 return; /* give up */ 337 if (GNUNET_OK != 338 try_connect (dh)) 339 return; /* give up */ 340 retry_limit--; 341 continue; 342 } 343 if (0 == ret) 344 { 345 GNUNET_break (0 == off); 346 return; 347 } 348 off += ret; 349 more: 350 if (off < sizeof (struct GNUNET_MessageHeader)) 351 continue; 352 msize = ntohs (hdr->size); 353 if (msize < sizeof (struct GNUNET_MessageHeader)) 354 { 355 GNUNET_break_op (0); 356 do_disconnect (dh); 357 return; 358 } 359 if (off < msize) 360 continue; 361 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 switch (ntohs (hdr->type)) 366 { 367 case TALER_HELPER_RSA_MT_AVAIL: 368 if (GNUNET_OK != 369 handle_mt_avail (dh, 370 hdr)) 371 { 372 GNUNET_break_op (0); 373 do_disconnect (dh); 374 return; 375 } 376 break; 377 case TALER_HELPER_RSA_MT_PURGE: 378 if (GNUNET_OK != 379 handle_mt_purge (dh, 380 hdr)) 381 { 382 GNUNET_break_op (0); 383 do_disconnect (dh); 384 return; 385 } 386 break; 387 case TALER_HELPER_RSA_SYNCED: 388 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 389 "Now synchronized with RSA helper\n"); 390 dh->synced = true; 391 break; 392 default: 393 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 GNUNET_break_op (0); 398 do_disconnect (dh); 399 return; 400 } 401 memmove (buf, 402 &buf[msize], 403 off - msize); 404 off -= msize; 405 goto more; 406 } 407 } 408 409 410 enum TALER_ErrorCode 411 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 { 417 enum TALER_ErrorCode ec = TALER_EC_INVALID; 418 unsigned int rpos; 419 unsigned int rend; 420 unsigned int wpos; 421 422 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 for (unsigned int i = 0; i<rsrs_length; i++) 428 { 429 if (rsrs[i].msg_size >= 430 UINT16_MAX 431 - sizeof (struct TALER_CRYPTO_BatchSignRequest) 432 - sizeof (struct TALER_CRYPTO_SignRequest)) 433 { 434 GNUNET_break_op (0); 435 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 return TALER_EC_GENERIC_PARAMETER_MALFORMED; 439 } 440 } 441 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 442 "Starting signature process\n"); 443 if (GNUNET_OK != 444 try_connect (dh)) 445 { 446 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 447 "Failed to connect to helper\n"); 448 return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE; 449 } 450 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 451 "Requesting %u signatures\n", 452 rsrs_length); 453 rpos = 0; 454 rend = 0; 455 wpos = 0; 456 while (rpos < rsrs_length) 457 { 458 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 while ( (rend < rsrs_length) && 463 (mlen 464 + sizeof (struct TALER_CRYPTO_SignRequest) 465 + rsrs[rend].msg_size < UINT16_MAX) ) 466 { 467 mlen += sizeof (struct TALER_CRYPTO_SignRequest) + rsrs[rend].msg_size; 468 rend++; 469 } 470 { 471 char obuf[mlen] GNUNET_ALIGN; 472 struct TALER_CRYPTO_BatchSignRequest *bsr 473 = (struct TALER_CRYPTO_BatchSignRequest *) obuf; 474 void *wbuf; 475 476 bsr->header.type = htons (TALER_HELPER_RSA_MT_REQ_BATCH_SIGN); 477 bsr->header.size = htons (mlen); 478 bsr->batch_size = htonl (rend - rpos); 479 wbuf = &bsr[1]; 480 for (unsigned int i = rpos; i<rend; i++) 481 { 482 struct TALER_CRYPTO_SignRequest *sr = wbuf; 483 const struct TALER_CRYPTO_RsaSignRequest *rsr = &rsrs[i]; 484 485 sr->header.type = htons (TALER_HELPER_RSA_MT_REQ_SIGN); 486 sr->header.size = htons (sizeof (*sr) + rsr->msg_size); 487 sr->reserved = htonl (0); 488 sr->h_rsa = *rsr->h_rsa; 489 GNUNET_memcpy (&sr[1], 490 rsr->msg, 491 rsr->msg_size); 492 wbuf += sizeof (*sr) + rsr->msg_size; 493 } 494 GNUNET_assert (wbuf == &obuf[mlen]); 495 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 496 "Sending batch request [%u-%u)\n", 497 rpos, 498 rend); 499 if (GNUNET_OK != 500 TALER_crypto_helper_send_all (dh->sock, 501 obuf, 502 sizeof (obuf))) 503 { 504 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, 505 "send"); 506 do_disconnect (dh); 507 return TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE; 508 } 509 } 510 rpos = rend; 511 { 512 char buf[UINT16_MAX]; 513 size_t off = 0; 514 const struct GNUNET_MessageHeader *hdr 515 = (const struct GNUNET_MessageHeader *) buf; 516 bool finished = false; 517 518 while (1) 519 { 520 uint16_t msize; 521 ssize_t ret; 522 523 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 524 "Awaiting reply at %u (up to %u)\n", 525 wpos, 526 rend); 527 ret = recv (dh->sock, 528 &buf[off], 529 sizeof (buf) - off, 530 (finished && (0 == off)) 531 ? MSG_DONTWAIT 532 : 0); 533 if (ret < 0) 534 { 535 if (EINTR == errno) 536 continue; 537 if (EAGAIN == errno) 538 { 539 GNUNET_assert (finished); 540 GNUNET_assert (0 == off); 541 break; 542 } 543 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, 544 "recv"); 545 do_disconnect (dh); 546 ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE; 547 break; 548 } 549 if (0 == ret) 550 { 551 GNUNET_break (0 == off); 552 if (! finished) 553 ec = TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG; 554 if (TALER_EC_NONE == ec) 555 break; 556 return ec; 557 } 558 off += ret; 559 more: 560 if (off < sizeof (struct GNUNET_MessageHeader)) 561 continue; 562 msize = ntohs (hdr->size); 563 if (msize < sizeof (struct GNUNET_MessageHeader)) 564 { 565 GNUNET_break_op (0); 566 do_disconnect (dh); 567 return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG; 568 } 569 if (off < msize) 570 continue; 571 switch (ntohs (hdr->type)) 572 { 573 case TALER_HELPER_RSA_MT_RES_SIGNATURE: 574 if (msize < sizeof (struct TALER_CRYPTO_SignResponse)) 575 { 576 GNUNET_break_op (0); 577 do_disconnect (dh); 578 return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG; 579 } 580 if (finished) 581 { 582 GNUNET_break_op (0); 583 do_disconnect (dh); 584 return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG; 585 } 586 { 587 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 rsa_signature = GNUNET_CRYPTO_rsa_signature_decode ( 593 &sr[1], 594 msize - sizeof (*sr)); 595 if (NULL == rsa_signature) 596 { 597 GNUNET_break_op (0); 598 do_disconnect (dh); 599 return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG; 600 } 601 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 602 "Received %u signature\n", 603 wpos); 604 blind_sig = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature); 605 blind_sig->cipher = GNUNET_CRYPTO_BSA_RSA; 606 blind_sig->rc = 1; 607 blind_sig->details.blinded_rsa_signature = rsa_signature; 608 bss[wpos].blinded_sig = blind_sig; 609 wpos++; 610 if (wpos == rend) 611 { 612 if (TALER_EC_INVALID == ec) 613 ec = TALER_EC_NONE; 614 finished = true; 615 } 616 break; 617 } 618 case TALER_HELPER_RSA_MT_RES_SIGN_FAILURE: 619 if (msize != sizeof (struct TALER_CRYPTO_SignFailure)) 620 { 621 GNUNET_break_op (0); 622 do_disconnect (dh); 623 return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG; 624 } 625 { 626 const struct TALER_CRYPTO_SignFailure *sf = 627 (const struct TALER_CRYPTO_SignFailure *) buf; 628 629 ec = (enum TALER_ErrorCode) (int) ntohl (sf->ec); 630 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 631 "Signing %u failed with status %d!\n", 632 wpos, 633 ec); 634 wpos++; 635 if (wpos == rend) 636 { 637 finished = true; 638 } 639 break; 640 } 641 case TALER_HELPER_RSA_MT_AVAIL: 642 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 643 "Received new key!\n"); 644 if (GNUNET_OK != 645 handle_mt_avail (dh, 646 hdr)) 647 { 648 GNUNET_break_op (0); 649 do_disconnect (dh); 650 return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG; 651 } 652 break; /* while(1) loop ensures we recvfrom() again */ 653 case TALER_HELPER_RSA_MT_PURGE: 654 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 655 "Received revocation!\n"); 656 if (GNUNET_OK != 657 handle_mt_purge (dh, 658 hdr)) 659 { 660 GNUNET_break_op (0); 661 do_disconnect (dh); 662 return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG; 663 } 664 break; /* while(1) loop ensures we recvfrom() again */ 665 case TALER_HELPER_RSA_SYNCED: 666 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 667 "Synchronized add odd time with RSA helper!\n"); 668 dh->synced = true; 669 break; 670 default: 671 GNUNET_break_op (0); 672 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 673 "Received unexpected message of type %u\n", 674 ntohs (hdr->type)); 675 do_disconnect (dh); 676 return TALER_EC_EXCHANGE_DENOMINATION_HELPER_BUG; 677 } 678 memmove (buf, 679 &buf[msize], 680 off - msize); 681 off -= msize; 682 goto more; 683 } /* while(1) */ 684 } /* scope */ 685 } /* while (rpos < rsrs_length) */ 686 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 687 "Existing with %u signatures and status %d\n", 688 wpos, 689 ec); 690 return ec; 691 } 692 693 694 void 695 TALER_CRYPTO_helper_rsa_revoke ( 696 struct TALER_CRYPTO_RsaDenominationHelper *dh, 697 const struct TALER_RsaPubHashP *h_rsa) 698 { 699 struct TALER_CRYPTO_RevokeRequest rr = { 700 .header.size = htons (sizeof (rr)), 701 .header.type = htons (TALER_HELPER_RSA_MT_REQ_REVOKE), 702 .h_rsa = *h_rsa 703 }; 704 705 if (GNUNET_OK != 706 try_connect (dh)) 707 return; /* give up */ 708 if (GNUNET_OK != 709 TALER_crypto_helper_send_all (dh->sock, 710 &rr, 711 sizeof (rr))) 712 { 713 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, 714 "send"); 715 do_disconnect (dh); 716 return; 717 } 718 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 TALER_CRYPTO_helper_rsa_disconnect ( 726 struct TALER_CRYPTO_RsaDenominationHelper *dh) 727 { 728 if (-1 != dh->sock) 729 do_disconnect (dh); 730 GNUNET_free (dh); 731 } 732 733 734 /* end of crypto_helper_denom.c */