LCOV - code coverage report
Current view: top level - util - crypto_helper_rsa.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 65.4 % 338 221
Test Date: 2026-09-11 18:55:36 Functions: 100.0 % 9 9

            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 */
        

Generated by: LCOV version 2.0-1