LCOV - code coverage report
Current view: top level - util - crypto_helper_esign.c (source / functions) Hit Total Coverage
Test: GNU Taler exchange coverage report Lines: 155 265 58.5 %
Date: 2021-08-30 06:43:37 Functions: 10 10 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2020 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_esign.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_util.h"
      23             : #include "taler_signatures.h"
      24             : #include "taler-exchange-secmod-eddsa.h"
      25             : #include <poll.h>
      26             : 
      27             : 
      28             : struct TALER_CRYPTO_ExchangeSignHelper
      29             : {
      30             :   /**
      31             :    * Function to call with updates to available key material.
      32             :    */
      33             :   TALER_CRYPTO_ExchangeKeyStatusCallback ekc;
      34             : 
      35             :   /**
      36             :    * Closure for @e ekc
      37             :    */
      38             :   void *ekc_cls;
      39             : 
      40             :   /**
      41             :    * Socket address of the denomination helper process.
      42             :    * Used to reconnect if the connection breaks.
      43             :    */
      44             :   struct sockaddr_un sa;
      45             : 
      46             :   /**
      47             :    * Socket address of this process.
      48             :    */
      49             :   struct sockaddr_un my_sa;
      50             : 
      51             :   /**
      52             :    * Template for @e my_sa.
      53             :    */
      54             :   char *template;
      55             : 
      56             :   /**
      57             :    * The UNIX domain socket, -1 if we are currently not connected.
      58             :    */
      59             :   int sock;
      60             : 
      61             :   /**
      62             :    * Have we reached the sync'ed state?
      63             :    */
      64             :   bool synced;
      65             : 
      66             : };
      67             : 
      68             : 
      69             : /**
      70             :  * Disconnect from the helper process.  Updates
      71             :  * @e sock field in @a esh.
      72             :  *
      73             :  * @param[in,out] esh handle to tear down connection of
      74             :  */
      75             : static void
      76          39 : do_disconnect (struct TALER_CRYPTO_ExchangeSignHelper *esh)
      77             : {
      78          39 :   GNUNET_break (0 == close (esh->sock));
      79          39 :   if (0 != unlink (esh->my_sa.sun_path))
      80           0 :     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
      81             :                               "unlink",
      82             :                               esh->my_sa.sun_path);
      83          39 :   esh->sock = -1;
      84          39 : }
      85             : 
      86             : 
      87             : /**
      88             :  * Try to connect to the helper process.  Updates
      89             :  * @e sock field in @a esh.
      90             :  *
      91             :  * @param[in,out] esh handle to establish connection for
      92             :  */
      93             : static void
      94         834 : try_connect (struct TALER_CRYPTO_ExchangeSignHelper *esh)
      95             : {
      96             :   char *tmpdir;
      97             : 
      98         834 :   if (-1 != esh->sock)
      99         795 :     return;
     100          39 :   esh->sock = socket (AF_UNIX,
     101             :                       SOCK_DGRAM,
     102             :                       0);
     103          39 :   if (-1 == esh->sock)
     104             :   {
     105           0 :     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
     106             :                          "socket");
     107           0 :     return;
     108             :   }
     109          39 :   tmpdir = GNUNET_DISK_mktemp (esh->template);
     110          39 :   if (NULL == tmpdir)
     111             :   {
     112           0 :     do_disconnect (esh);
     113           0 :     return;
     114             :   }
     115             :   /* we use >= here because we want the sun_path to always
     116             :      be 0-terminated */
     117          39 :   if (strlen (tmpdir) >= sizeof (esh->sa.sun_path))
     118             :   {
     119           0 :     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
     120             :                                "PATHS",
     121             :                                "TALER_RUNTIME_DIR",
     122             :                                "path too long");
     123           0 :     GNUNET_free (tmpdir);
     124           0 :     do_disconnect (esh);
     125           0 :     return;
     126             :   }
     127          39 :   esh->my_sa.sun_family = AF_UNIX;
     128          39 :   strncpy (esh->my_sa.sun_path,
     129             :            tmpdir,
     130             :            sizeof (esh->sa.sun_path) - 1);
     131          39 :   if (0 != unlink (tmpdir))
     132           0 :     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
     133             :                               "unlink",
     134             :                               tmpdir);
     135          39 :   if (0 != bind (esh->sock,
     136          39 :                  (const struct sockaddr *) &esh->my_sa,
     137             :                  sizeof (esh->my_sa)))
     138             :   {
     139           0 :     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
     140             :                               "bind",
     141             :                               tmpdir);
     142           0 :     do_disconnect (esh);
     143           0 :     GNUNET_free (tmpdir);
     144           0 :     return;
     145             :   }
     146             :   /* Fix permissions on client UNIX domain socket,
     147             :      just in case umask() is not set to enable group write */
     148             :   {
     149             :     char path[sizeof (esh->my_sa.sun_path) + 1];
     150             : 
     151          39 :     strncpy (path,
     152          39 :              esh->my_sa.sun_path,
     153             :              sizeof (path) - 1);
     154          39 :     path[sizeof (esh->my_sa.sun_path)] = '\0';
     155             : 
     156          39 :     if (0 != chmod (path,
     157             :                     S_IRUSR | S_IWUSR | S_IWGRP))
     158             :     {
     159           0 :       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
     160             :                                 "chmod",
     161             :                                 path);
     162             :     }
     163             :   }
     164             : 
     165          39 :   GNUNET_free (tmpdir);
     166             :   {
     167          39 :     struct GNUNET_MessageHeader hdr = {
     168          39 :       .size = htons (sizeof (hdr)),
     169          39 :       .type = htons (TALER_HELPER_EDDSA_MT_REQ_INIT)
     170             :     };
     171             :     ssize_t ret;
     172             : 
     173          39 :     ret = sendto (esh->sock,
     174             :                   &hdr,
     175             :                   sizeof (hdr),
     176             :                   0,
     177          39 :                   (const struct sockaddr *) &esh->sa,
     178             :                   sizeof (esh->sa));
     179          39 :     if (ret < 0)
     180             :     {
     181           2 :       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
     182             :                                 "sendto",
     183             :                                 esh->sa.sun_path);
     184           2 :       do_disconnect (esh);
     185           2 :       return;
     186             :     }
     187             :     /* We are using SOCK_DGRAM, partial writes should not be possible */
     188          37 :     GNUNET_break (((size_t) ret) == sizeof (hdr));
     189          37 :     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
     190             :                 "Successfully sent REQ_INIT\n");
     191             :   }
     192             : 
     193             : }
     194             : 
     195             : 
     196             : struct TALER_CRYPTO_ExchangeSignHelper *
     197          37 : TALER_CRYPTO_helper_esign_connect (
     198             :   const struct GNUNET_CONFIGURATION_Handle *cfg,
     199             :   TALER_CRYPTO_ExchangeKeyStatusCallback ekc,
     200             :   void *ekc_cls)
     201             : {
     202             :   struct TALER_CRYPTO_ExchangeSignHelper *esh;
     203             :   char *unixpath;
     204             : 
     205          37 :   if (GNUNET_OK !=
     206          37 :       GNUNET_CONFIGURATION_get_value_filename (cfg,
     207             :                                                "taler-exchange-secmod-eddsa",
     208             :                                                "UNIXPATH",
     209             :                                                &unixpath))
     210             :   {
     211           0 :     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
     212             :                                "taler-exchange-secmod-eddsa",
     213             :                                "UNIXPATH");
     214           0 :     return NULL;
     215             :   }
     216             :   /* we use >= here because we want the sun_path to always
     217             :      be 0-terminated */
     218          37 :   if (strlen (unixpath) >= sizeof (esh->sa.sun_path))
     219             :   {
     220           0 :     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
     221             :                                "taler-exchange-secmod-eddsa",
     222             :                                "UNIXPATH",
     223             :                                "path too long");
     224           0 :     GNUNET_free (unixpath);
     225           0 :     return NULL;
     226             :   }
     227          37 :   esh = GNUNET_new (struct TALER_CRYPTO_ExchangeSignHelper);
     228          37 :   esh->ekc = ekc;
     229          37 :   esh->ekc_cls = ekc_cls;
     230          37 :   esh->sa.sun_family = AF_UNIX;
     231          37 :   strncpy (esh->sa.sun_path,
     232             :            unixpath,
     233             :            sizeof (esh->sa.sun_path) - 1);
     234          37 :   GNUNET_free (unixpath);
     235          37 :   esh->sock = -1;
     236             :   {
     237             :     char *tmpdir;
     238             :     char *template;
     239             : 
     240          37 :     if (GNUNET_OK !=
     241          37 :         GNUNET_CONFIGURATION_get_value_filename (cfg,
     242             :                                                  "taler-exchange-secmod-eddsa",
     243             :                                                  "CLIENT_DIR",
     244             :                                                  &tmpdir))
     245             :     {
     246           0 :       GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
     247             :                                  "taler-exchange-secmod-eddsa",
     248             :                                  "CLIENT_DIR");
     249           0 :       GNUNET_free (esh);
     250           0 :       return NULL;
     251             :     }
     252          37 :     GNUNET_asprintf (&template,
     253             :                      "%s/cli",
     254             :                      tmpdir);
     255             :     /* We expect the service to create the client directory */
     256          37 :     if (GNUNET_OK !=
     257          37 :         GNUNET_DISK_directory_test (tmpdir,
     258             :                                     GNUNET_YES))
     259             :     {
     260           0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     261             :                   "Unable to read secmod client directory (%s)\n",
     262             :                   tmpdir);
     263           0 :       GNUNET_free (esh);
     264           0 :       GNUNET_free (template);
     265           0 :       GNUNET_free (tmpdir);
     266           0 :       return NULL;
     267             :     }
     268          37 :     GNUNET_free (tmpdir);
     269          37 :     esh->template = template;
     270          37 :     if (strlen (template) >= sizeof (esh->sa.sun_path))
     271             :     {
     272           0 :       GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
     273             :                                  "PATHS",
     274             :                                  "TALER_RUNTIME_DIR",
     275             :                                  "path too long");
     276           0 :       TALER_CRYPTO_helper_esign_disconnect (esh);
     277           0 :       return NULL;
     278             :     }
     279             :   }
     280          37 :   TALER_CRYPTO_helper_esign_poll (esh);
     281          37 :   return esh;
     282             : }
     283             : 
     284             : 
     285             : /**
     286             :  * Handle a #TALER_HELPER_EDDSA_MT_AVAIL message from the helper.
     287             :  *
     288             :  * @param esh helper context
     289             :  * @param hdr message that we received
     290             :  * @return #GNUNET_OK on success
     291             :  */
     292             : static int
     293          73 : handle_mt_avail (struct TALER_CRYPTO_ExchangeSignHelper *esh,
     294             :                  const struct GNUNET_MessageHeader *hdr)
     295             : {
     296          73 :   const struct TALER_CRYPTO_EddsaKeyAvailableNotification *kan
     297             :     = (const struct TALER_CRYPTO_EddsaKeyAvailableNotification *) hdr;
     298             : 
     299          73 :   if (sizeof (*kan) != ntohs (hdr->size))
     300             :   {
     301           0 :     GNUNET_break_op (0);
     302           0 :     return GNUNET_SYSERR;
     303             :   }
     304          73 :   if (GNUNET_OK !=
     305          73 :       TALER_exchange_secmod_eddsa_verify (
     306             :         &kan->exchange_pub,
     307             :         GNUNET_TIME_absolute_ntoh (kan->anchor_time),
     308             :         GNUNET_TIME_relative_ntoh (kan->duration),
     309             :         &kan->secm_pub,
     310             :         &kan->secm_sig))
     311             :   {
     312           0 :     GNUNET_break_op (0);
     313           0 :     return GNUNET_SYSERR;
     314             :   }
     315          73 :   esh->ekc (esh->ekc_cls,
     316             :             GNUNET_TIME_absolute_ntoh (kan->anchor_time),
     317             :             GNUNET_TIME_relative_ntoh (kan->duration),
     318             :             &kan->exchange_pub,
     319             :             &kan->secm_pub,
     320             :             &kan->secm_sig);
     321          73 :   return GNUNET_OK;
     322             : }
     323             : 
     324             : 
     325             : /**
     326             :  * Handle a #TALER_HELPER_EDDSA_MT_PURGE message from the helper.
     327             :  *
     328             :  * @param esh helper context
     329             :  * @param hdr message that we received
     330             :  * @return #GNUNET_OK on success
     331             :  */
     332             : static int
     333           3 : handle_mt_purge (struct TALER_CRYPTO_ExchangeSignHelper *esh,
     334             :                  const struct GNUNET_MessageHeader *hdr)
     335             : {
     336           3 :   const struct TALER_CRYPTO_EddsaKeyPurgeNotification *pn
     337             :     = (const struct TALER_CRYPTO_EddsaKeyPurgeNotification *) hdr;
     338             : 
     339           3 :   if (sizeof (*pn) != ntohs (hdr->size))
     340             :   {
     341           0 :     GNUNET_break_op (0);
     342           0 :     return GNUNET_SYSERR;
     343             :   }
     344           3 :   esh->ekc (esh->ekc_cls,
     345             :             GNUNET_TIME_UNIT_ZERO_ABS,
     346             :             GNUNET_TIME_UNIT_ZERO,
     347             :             &pn->exchange_pub,
     348             :             NULL,
     349             :             NULL);
     350           3 :   return GNUNET_OK;
     351             : }
     352             : 
     353             : 
     354             : /**
     355             :  * Wait until the socket is ready to read.
     356             :  *
     357             :  * @param esh helper to wait for
     358             :  * @return false on timeout (after 1s)
     359             :  */
     360             : static bool
     361         309 : await_read_ready (struct TALER_CRYPTO_ExchangeSignHelper *esh)
     362             : {
     363             :   /* wait for reply with 1s timeout */
     364         309 :   struct pollfd pfd = {
     365         309 :     .fd = esh->sock,
     366             :     .events = POLLIN
     367             :   };
     368             :   sigset_t sigmask;
     369         309 :   struct timespec ts = {
     370             :     .tv_sec = 1
     371             :   };
     372             :   int ret;
     373             : 
     374         309 :   GNUNET_assert (0 == sigemptyset (&sigmask));
     375         309 :   GNUNET_assert (0 == sigaddset (&sigmask, SIGTERM));
     376         309 :   GNUNET_assert (0 == sigaddset (&sigmask, SIGHUP));
     377         309 :   ret = ppoll (&pfd,
     378             :                1,
     379             :                &ts,
     380             :                &sigmask);
     381         309 :   if ( (-1 == ret) &&
     382           0 :        (EINTR != errno) )
     383           0 :     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
     384             :                          "ppoll");
     385         309 :   return (0 < ret);
     386             : }
     387             : 
     388             : 
     389             : void
     390         560 : TALER_CRYPTO_helper_esign_poll (struct TALER_CRYPTO_ExchangeSignHelper *esh)
     391             : {
     392             :   char buf[UINT16_MAX];
     393             :   ssize_t ret;
     394         560 :   unsigned int retry_limit = 3;
     395         560 :   const struct GNUNET_MessageHeader *hdr
     396             :     = (const struct GNUNET_MessageHeader *) buf;
     397         560 :   int flag = MSG_DONTWAIT;
     398             : 
     399         560 :   try_connect (esh);
     400         560 :   if (-1 == esh->sock)
     401           2 :     return; /* give up */
     402             :   while (1)
     403             :   {
     404         709 :     ret = recv (esh->sock,
     405             :                 buf,
     406             :                 sizeof (buf),
     407             :                 flag);
     408         709 :     if (ret < 0)
     409             :     {
     410         596 :       if (EAGAIN == errno)
     411             :       {
     412         596 :         GNUNET_assert (0 != flag);
     413         596 :         if (esh->synced)
     414         558 :           break;
     415          38 :         if (! await_read_ready (esh))
     416             :         {
     417             :           /* timeout AND not synced => full reconnect */
     418           0 :           GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     419             :                       "Restarting connection to EdDSA helper, did not come up properly\n");
     420           0 :           do_disconnect (esh);
     421           0 :           if (0 == retry_limit)
     422           0 :             return; /* give up */
     423           0 :           try_connect (esh);
     424           0 :           if (-1 == esh->sock)
     425           0 :             return; /* give up */
     426           0 :           retry_limit--;
     427           0 :           flag = MSG_DONTWAIT;
     428             :         }
     429             :         else
     430             :         {
     431          38 :           flag = 0; /* syscall must be non-blocking this time */
     432             :         }
     433          38 :         continue; /* try again */
     434             :       }
     435           0 :       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
     436             :                            "recv");
     437           0 :       do_disconnect (esh);
     438           0 :       return;
     439             :     }
     440             : 
     441         113 :     flag = MSG_DONTWAIT;
     442         113 :     if ( (ret < sizeof (struct GNUNET_MessageHeader)) ||
     443         113 :          (ret != ntohs (hdr->size)) )
     444             :     {
     445           0 :       GNUNET_break_op (0);
     446           0 :       do_disconnect (esh);
     447           0 :       return;
     448             :     }
     449         113 :     switch (ntohs (hdr->type))
     450             :     {
     451          73 :     case TALER_HELPER_EDDSA_MT_AVAIL:
     452          73 :       if (GNUNET_OK !=
     453          73 :           handle_mt_avail (esh,
     454             :                            hdr))
     455             :       {
     456           0 :         GNUNET_break_op (0);
     457           0 :         do_disconnect (esh);
     458           0 :         return;
     459             :       }
     460          73 :       break;
     461           3 :     case TALER_HELPER_EDDSA_MT_PURGE:
     462           3 :       if (GNUNET_OK !=
     463           3 :           handle_mt_purge (esh,
     464             :                            hdr))
     465             :       {
     466           0 :         GNUNET_break_op (0);
     467           0 :         do_disconnect (esh);
     468           0 :         return;
     469             :       }
     470           3 :       break;
     471          37 :     case TALER_HELPER_EDDSA_SYNCED:
     472          37 :       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     473             :                   "Now synchronized with EdDSA helper\n");
     474          37 :       esh->synced = true;
     475          37 :       break;
     476           0 :     default:
     477           0 :       GNUNET_break_op (0);
     478           0 :       do_disconnect (esh);
     479           0 :       return;
     480             :     }
     481             :   }
     482             : }
     483             : 
     484             : 
     485             : enum TALER_ErrorCode
     486         271 : TALER_CRYPTO_helper_esign_sign_ (
     487             :   struct TALER_CRYPTO_ExchangeSignHelper *esh,
     488             :   const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
     489             :   struct TALER_ExchangePublicKeyP *exchange_pub,
     490             :   struct TALER_ExchangeSignatureP *exchange_sig)
     491             : {
     492         271 :   {
     493         271 :     uint32_t purpose_size = ntohl (purpose->size);
     494         271 :     char buf[sizeof (struct TALER_CRYPTO_EddsaSignRequest) + purpose_size
     495         271 :              - sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose)];
     496         271 :     struct TALER_CRYPTO_EddsaSignRequest *sr
     497             :       = (struct TALER_CRYPTO_EddsaSignRequest *) buf;
     498             :     ssize_t ret;
     499             : 
     500         271 :     try_connect (esh);
     501         271 :     if (-1 == esh->sock)
     502             :     {
     503           0 :       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     504             :                   "Failed to connect to helper\n");
     505           0 :       return TALER_EC_EXCHANGE_SIGNKEY_HELPER_UNAVAILABLE;
     506             :     }
     507         271 :     sr->header.size = htons (sizeof (buf));
     508         271 :     sr->header.type = htons (TALER_HELPER_EDDSA_MT_REQ_SIGN);
     509         271 :     sr->reserved = htonl (0);
     510         271 :     memcpy (&sr->purpose,
     511             :             purpose,
     512             :             purpose_size);
     513         271 :     ret = sendto (esh->sock,
     514             :                   buf,
     515             :                   sizeof (buf),
     516             :                   0,
     517         271 :                   (const struct sockaddr *) &esh->sa,
     518             :                   sizeof (esh->sa));
     519         271 :     if (ret < 0)
     520             :     {
     521           0 :       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
     522             :                                 "sendto",
     523             :                                 esh->sa.sun_path);
     524           0 :       do_disconnect (esh);
     525           0 :       return TALER_EC_EXCHANGE_SIGNKEY_HELPER_UNAVAILABLE;
     526             :     }
     527             :     /* We are using SOCK_DGRAM, partial writes should not be possible */
     528         271 :     GNUNET_break (((size_t) ret) == sizeof (buf));
     529             :   }
     530             : 
     531             :   while (1)
     532           0 :   {
     533             :     char buf[UINT16_MAX];
     534             :     ssize_t ret;
     535         271 :     const struct GNUNET_MessageHeader *hdr
     536             :       = (const struct GNUNET_MessageHeader *) buf;
     537             : 
     538         271 :     if (! await_read_ready (esh))
     539             :     {
     540           0 :       do_disconnect (esh);
     541           0 :       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     542             :                   "Timeout waiting for helper\n");
     543         271 :       return TALER_EC_GENERIC_TIMEOUT;
     544             :     }
     545         271 :     ret = recv (esh->sock,
     546             :                 buf,
     547             :                 sizeof (buf),
     548             :                 0);
     549         271 :     if (ret < 0)
     550             :     {
     551           0 :       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
     552             :                            "recv");
     553           0 :       do_disconnect (esh);
     554           0 :       return TALER_EC_EXCHANGE_SIGNKEY_HELPER_UNAVAILABLE;
     555             :     }
     556         271 :     if ( (ret < sizeof (struct GNUNET_MessageHeader)) ||
     557         271 :          (ret != ntohs (hdr->size)) )
     558             :     {
     559           0 :       GNUNET_break_op (0);
     560           0 :       do_disconnect (esh);
     561           0 :       return TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG;
     562             :     }
     563         271 :     switch (ntohs (hdr->type))
     564             :     {
     565         271 :     case TALER_HELPER_EDDSA_MT_RES_SIGNATURE:
     566         271 :       if (ret != sizeof (struct TALER_CRYPTO_EddsaSignResponse))
     567             :       {
     568           0 :         GNUNET_break_op (0);
     569           0 :         do_disconnect (esh);
     570           0 :         return TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG;
     571             :       }
     572             :       {
     573         271 :         const struct TALER_CRYPTO_EddsaSignResponse *sr =
     574             :           (const struct TALER_CRYPTO_EddsaSignResponse *) buf;
     575         271 :         *exchange_sig = sr->exchange_sig;
     576         271 :         *exchange_pub = sr->exchange_pub;
     577         271 :         return TALER_EC_NONE;
     578             :       }
     579           0 :     case TALER_HELPER_EDDSA_MT_RES_SIGN_FAILURE:
     580           0 :       if (ret != sizeof (struct TALER_CRYPTO_EddsaSignFailure))
     581             :       {
     582           0 :         GNUNET_break_op (0);
     583           0 :         do_disconnect (esh);
     584           0 :         return TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG;
     585             :       }
     586             :       {
     587           0 :         const struct TALER_CRYPTO_EddsaSignFailure *sf =
     588             :           (const struct TALER_CRYPTO_EddsaSignFailure *) buf;
     589             : 
     590           0 :         return (enum TALER_ErrorCode) ntohl (sf->ec);
     591             :       }
     592           0 :     case TALER_HELPER_EDDSA_MT_AVAIL:
     593           0 :       if (GNUNET_OK !=
     594           0 :           handle_mt_avail (esh,
     595             :                            hdr))
     596             :       {
     597           0 :         GNUNET_break_op (0);
     598           0 :         do_disconnect (esh);
     599           0 :         return TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG;
     600             :       }
     601           0 :       break; /* while(1) loop ensures we recvfrom() again */
     602           0 :     case TALER_HELPER_EDDSA_MT_PURGE:
     603           0 :       if (GNUNET_OK !=
     604           0 :           handle_mt_purge (esh,
     605             :                            hdr))
     606             :       {
     607           0 :         GNUNET_break_op (0);
     608           0 :         do_disconnect (esh);
     609           0 :         return TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG;
     610             :       }
     611           0 :       break; /* while(1) loop ensures we recvfrom() again */
     612           0 :     default:
     613           0 :       GNUNET_break_op (0);
     614           0 :       do_disconnect (esh);
     615           0 :       return TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG;
     616             :     }
     617             :   }
     618             : }
     619             : 
     620             : 
     621             : void
     622           3 : TALER_CRYPTO_helper_esign_revoke (
     623             :   struct TALER_CRYPTO_ExchangeSignHelper *esh,
     624             :   const struct TALER_ExchangePublicKeyP *exchange_pub)
     625             : {
     626           3 :   struct TALER_CRYPTO_EddsaRevokeRequest rr = {
     627           3 :     .header.size = htons (sizeof (rr)),
     628           3 :     .header.type = htons (TALER_HELPER_EDDSA_MT_REQ_REVOKE),
     629             :     .exchange_pub = *exchange_pub
     630             :   };
     631             :   ssize_t ret;
     632             : 
     633           3 :   try_connect (esh);
     634           3 :   if (-1 == esh->sock)
     635           0 :     return; /* give up */
     636           3 :   ret = sendto (esh->sock,
     637             :                 &rr,
     638             :                 sizeof (rr),
     639             :                 0,
     640           3 :                 (const struct sockaddr *) &esh->sa,
     641             :                 sizeof (esh->sa));
     642           3 :   if (ret < 0)
     643             :   {
     644           0 :     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
     645             :                          "sendto");
     646           0 :     do_disconnect (esh);
     647           0 :     return;
     648             :   }
     649             :   /* We are using SOCK_DGRAM, partial writes should not be possible */
     650           3 :   GNUNET_break (((size_t) ret) == sizeof (rr));
     651             : }
     652             : 
     653             : 
     654             : void
     655          37 : TALER_CRYPTO_helper_esign_disconnect (
     656             :   struct TALER_CRYPTO_ExchangeSignHelper *esh)
     657             : {
     658          37 :   if (-1 != esh->sock)
     659          37 :     do_disconnect (esh);
     660          37 :   GNUNET_free (esh->template);
     661          37 :   GNUNET_free (esh);
     662          37 : }
     663             : 
     664             : 
     665             : /* end of crypto_helper_esign.c */

Generated by: LCOV version 1.14