LCOV - code coverage report
Current view: top level - auditor - taler-auditor-sign.c (source / functions) Hit Total Coverage
Test: rcoverage.info Lines: 69 162 42.6 %
Date: 2017-11-25 11:31:41 Functions: 1 2 50.0 %

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014, 2015 GNUnet e.V.
       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 taler-auditor-sign.c
      18             :  * @brief Tool used by the auditor to sign the exchange's master key and the
      19             :  *        denomination key(s).
      20             :  * @author Christian Grothoff
      21             :  */
      22             : #include <platform.h>
      23             : #include "taler_exchangedb_lib.h"
      24             : #include "taler_auditordb_lib.h"
      25             : 
      26             : 
      27             : /**
      28             :  * Are we running in verbose mode?
      29             :  */
      30             : static unsigned int verbose;
      31             : 
      32             : /**
      33             :  * Filename of the auditor's private key.
      34             :  */
      35             : static char *auditor_key_file;
      36             : 
      37             : /**
      38             :  * File with the Exchange's denomination keys to sign, itself
      39             :  * signed by the Exchange's public key.
      40             :  */
      41             : static char *exchange_request_file;
      42             : 
      43             : /**
      44             :  * Where should we write the auditor's signature?
      45             :  */
      46             : static char *output_file;
      47             : 
      48             : /**
      49             :  * URL of the auditor (informative for the user).
      50             :  */
      51             : static char *auditor_url;
      52             : 
      53             : /**
      54             :  * Master public key of the exchange.
      55             :  */
      56             : static struct TALER_MasterPublicKeyP master_public_key;
      57             : 
      58             : /**
      59             :  * Our configuration.
      60             :  */
      61             : static struct GNUNET_CONFIGURATION_Handle *cfg;
      62             : 
      63             : /**
      64             :  * Handle to access the auditor's database.
      65             :  */
      66             : static struct TALER_AUDITORDB_Plugin *adb;
      67             : 
      68             : 
      69             : /**
      70             :  * Print denomination key details for diagnostics.
      71             :  *
      72             :  * @param dk denomination key to print
      73             :  */
      74             : static void
      75           0 : print_dk (const struct TALER_DenominationKeyValidityPS *dk)
      76             : {
      77             :   struct TALER_Amount a;
      78             :   char *s;
      79             : 
      80           0 :   fprintf (stdout,
      81             :            "Denomination key hash: %s\n",
      82             :            GNUNET_h2s_full (&dk->denom_hash));
      83           0 :   TALER_amount_ntoh (&a,
      84             :                      &dk->value);
      85           0 :   fprintf (stdout,
      86             :            "Value: %s\n",
      87             :            s = TALER_amount_to_string (&a));
      88           0 :   GNUNET_free (s);
      89           0 :     TALER_amount_ntoh (&a,
      90             :                        &dk->fee_withdraw);
      91           0 :   fprintf (stdout,
      92             :            "Withdraw fee: %s\n",
      93             :            s = TALER_amount_to_string (&a));
      94           0 :   GNUNET_free (s);
      95           0 :     TALER_amount_ntoh (&a,
      96             :                        &dk->fee_deposit);
      97           0 :   fprintf (stdout,
      98             :            "Deposit fee: %s\n",
      99             :            s = TALER_amount_to_string (&a));
     100           0 :   GNUNET_free (s);
     101           0 :   TALER_amount_ntoh (&a,
     102             :                      &dk->fee_refresh);
     103           0 :   fprintf (stdout,
     104             :            "Refresh fee: %s\n",
     105             :            s = TALER_amount_to_string (&a));
     106           0 :   GNUNET_free (s);
     107           0 :   TALER_amount_ntoh (&a,
     108             :                      &dk->fee_refund);
     109           0 :   fprintf (stdout,
     110             :            "Refund fee: %s\n",
     111             :            s = TALER_amount_to_string (&a));
     112           0 :   GNUNET_free (s);
     113             : 
     114           0 :   fprintf (stdout,
     115             :            "Validity start time: %s\n",
     116             :            GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->start)));
     117           0 :   fprintf (stdout,
     118             :            "Withdraw end time: %s\n",
     119             :            GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->expire_withdraw)));
     120           0 :   fprintf (stdout,
     121             :            "Deposit end time: %s\n",
     122             :            GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->expire_deposit)));
     123           0 :   fprintf (stdout,
     124             :            "Legal dispute end time: %s\n",
     125             :            GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->expire_legal)));
     126             : 
     127           0 :   fprintf (stdout,
     128             :            "\n");
     129           0 : }
     130             : 
     131             : 
     132             : /**
     133             :  * The main function of the taler-auditor-sign tool.  This tool is used
     134             :  * to sign a exchange's master and denomination keys, affirming that the
     135             :  * auditor is aware of them and will validate the exchange's database with
     136             :  * respect to these keys.
     137             :  *
     138             :  * @param argc number of arguments from the command line
     139             :  * @param argv command line arguments
     140             :  * @return 0 ok, 1 on error
     141             :  */
     142             : int
     143           3 : main (int argc,
     144             :       char *const *argv)
     145             : {
     146           3 :   char *cfgfile = NULL;
     147           9 :   const struct GNUNET_GETOPT_CommandLineOption options[] = {
     148             :     GNUNET_GETOPT_option_filename ('a',
     149             :                                    "auditor-key",
     150             :                                    "FILENAME",
     151             :                                    "file containing the private key of the auditor",
     152             :                                    &auditor_key_file),
     153             :     GNUNET_GETOPT_option_cfgfile (&cfgfile),
     154             :     GNUNET_GETOPT_option_help ("Private key of the auditor to use for signing"),
     155           3 :     GNUNET_GETOPT_option_mandatory
     156             :     (GNUNET_GETOPT_option_base32_auto ('m',
     157             :                                            "exchange-key",
     158             :                                            "KEY",
     159             :                                            "public key of the exchange (Crockford base32 encoded)",
     160             :                                            &master_public_key)),
     161             :     GNUNET_GETOPT_option_string ('u',
     162             :                                  "auditor-url",
     163             :                                  "URL",
     164             :                                  "URL of the auditor (informative link for the user)",
     165             :                                  &auditor_url),
     166           3 :     GNUNET_GETOPT_option_mandatory
     167             :     (GNUNET_GETOPT_option_filename ('r',
     168             :                                     "exchange-request",
     169             :                                     "FILENAME",
     170             :                                     "set of keys the exchange requested the auditor to sign",
     171             :                                     &exchange_request_file)),
     172             :     GNUNET_GETOPT_option_filename ('o',
     173             :                                    "output",
     174             :                                    "FILENAME",
     175             :                                    "where to write our signature",
     176             :                                    &output_file),
     177             :     GNUNET_GETOPT_option_version (VERSION "-" VCS_VERSION),
     178             :     GNUNET_GETOPT_option_verbose (&verbose),
     179             :     GNUNET_GETOPT_OPTION_END
     180             :   };
     181             :   struct GNUNET_CRYPTO_EddsaPrivateKey *eddsa_priv;
     182             :   struct TALER_AuditorSignatureP *sigs;
     183             :   struct TALER_AuditorPublicKeyP apub;
     184             :   struct GNUNET_DISK_FileHandle *fh;
     185             :   struct TALER_DenominationKeyValidityPS *dks;
     186             :   unsigned int dks_len;
     187             :   struct TALER_ExchangeKeyValidityPS kv;
     188             :   off_t in_size;
     189             : 
     190           3 :   GNUNET_assert (GNUNET_OK ==
     191             :                  GNUNET_log_setup ("taler-auditor-sign",
     192             :                                    "WARNING",
     193             :                                    NULL));
     194           3 :   if (GNUNET_GETOPT_run ("taler-auditor-sign",
     195             :                          options,
     196             :                          argc, argv) < 0)
     197           0 :     return 1;
     198           3 :   cfg = GNUNET_CONFIGURATION_create ();
     199           3 :   if (GNUNET_SYSERR ==
     200           3 :       GNUNET_CONFIGURATION_load (cfg,
     201             :                                  cfgfile))
     202             :   {
     203           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     204             :                 _("Malformed configuration file `%s', exit ...\n"),
     205             :                 cfgfile);
     206           0 :     GNUNET_free_non_null (cfgfile);
     207           0 :     return 1;
     208             :   }
     209           3 :   GNUNET_free_non_null (cfgfile);
     210           6 :   if ( (NULL == auditor_key_file) &&
     211             :        (GNUNET_OK !=
     212           3 :         GNUNET_CONFIGURATION_get_value_filename (cfg,
     213             :                                                  "auditor",
     214             :                                                  "AUDITOR_PRIV_FILE",
     215             :                                                  &auditor_key_file)) )
     216             :   {
     217           0 :     fprintf (stderr,
     218             :              "Auditor key file not given in neither configuration nor command-line\n");
     219           0 :     return 1;
     220             :   }
     221           3 :   if ( (NULL == auditor_url) &&
     222             :        (GNUNET_OK !=
     223           0 :         GNUNET_CONFIGURATION_get_value_string (cfg,
     224             :                                                "auditor",
     225             :                                                "AUDITOR_URL",
     226             :                                                &auditor_url)) )
     227             :   {
     228           0 :     fprintf (stderr,
     229             :              "Auditor URL not given in neither configuration nor command-line\n");
     230           0 :     return 1;
     231             :   }
     232           3 :   if (GNUNET_YES !=
     233           3 :       GNUNET_DISK_file_test (auditor_key_file))
     234           1 :     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     235             :                 "Auditor private key `%s' does not exist yet, creating it!\n",
     236             :                 auditor_key_file);
     237           3 :   eddsa_priv = GNUNET_CRYPTO_eddsa_key_create_from_file (auditor_key_file);
     238           3 :   if (NULL == eddsa_priv)
     239             :   {
     240           0 :     fprintf (stderr,
     241             :              "Failed to initialize auditor key from file `%s'\n",
     242             :              auditor_key_file);
     243           0 :     return 1;
     244             :   }
     245           3 :   GNUNET_CRYPTO_eddsa_key_get_public (eddsa_priv,
     246             :                                       &apub.eddsa_pub);
     247           3 :   fh = GNUNET_DISK_file_open (exchange_request_file,
     248             :                               GNUNET_DISK_OPEN_READ,
     249             :                               GNUNET_DISK_PERM_NONE);
     250           3 :   if (NULL == fh)
     251             :   {
     252           0 :     fprintf (stderr,
     253             :              "Failed to open file `%s': %s\n",
     254             :              exchange_request_file,
     255           0 :              STRERROR (errno));
     256           0 :     GNUNET_free (eddsa_priv);
     257           0 :     return 1;
     258             :   }
     259           3 :   if (GNUNET_OK !=
     260           3 :       GNUNET_DISK_file_handle_size (fh,
     261             :                                     &in_size))
     262             :   {
     263           0 :     fprintf (stderr,
     264             :              "Failed to obtain input file size `%s': %s\n",
     265             :              exchange_request_file,
     266           0 :              STRERROR (errno));
     267           0 :     GNUNET_DISK_file_close (fh);
     268           0 :     GNUNET_free (eddsa_priv);
     269           0 :     return 1;
     270             :   }
     271           3 :   if (0 != (in_size % sizeof (struct TALER_DenominationKeyValidityPS)))
     272             :   {
     273           0 :     fprintf (stderr,
     274             :              "Input file size of file `%s' is invalid\n",
     275             :              exchange_request_file);
     276           0 :     GNUNET_DISK_file_close (fh);
     277           0 :     GNUNET_free (eddsa_priv);
     278           0 :     return 1;
     279             :   }
     280           3 :   dks_len = in_size / sizeof (struct TALER_DenominationKeyValidityPS);
     281           3 :   if (0 == dks_len)
     282             :   {
     283           0 :     fprintf (stderr,
     284             :              "Denomination list has length zero, signature not produced.\n");
     285           0 :     GNUNET_DISK_file_close (fh);
     286           0 :     GNUNET_free (eddsa_priv);
     287           0 :     return 2;
     288             :   }
     289           3 :   if (NULL ==
     290           3 :       (adb = TALER_AUDITORDB_plugin_load (cfg)))
     291             :   {
     292           0 :     fprintf (stderr,
     293             :              "Failed to initialize auditor database plugin.\n");
     294           0 :     GNUNET_DISK_file_close (fh);
     295           0 :     GNUNET_free (eddsa_priv);
     296           0 :     return 3;
     297             :   }
     298             : 
     299           3 :   kv.purpose.purpose = htonl (TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS);
     300           3 :   kv.purpose.size = htonl (sizeof (struct TALER_ExchangeKeyValidityPS));
     301           3 :   GNUNET_CRYPTO_hash (auditor_url,
     302           3 :                       strlen (auditor_url) + 1,
     303             :                       &kv.auditor_url_hash);
     304           3 :   kv.master = master_public_key;
     305           3 :   dks = GNUNET_new_array (dks_len,
     306             :                           struct TALER_DenominationKeyValidityPS);
     307           3 :   sigs = GNUNET_new_array (dks_len,
     308             :                            struct TALER_AuditorSignatureP);
     309           3 :   if (in_size !=
     310           3 :       GNUNET_DISK_file_read (fh,
     311             :                              dks,
     312             :                              in_size))
     313             :   {
     314           0 :     fprintf (stderr,
     315             :              "Failed to read input file `%s': %s\n",
     316             :              exchange_request_file,
     317           0 :              STRERROR (errno));
     318           0 :     TALER_AUDITORDB_plugin_unload (adb);
     319           0 :     GNUNET_DISK_file_close (fh);
     320           0 :     GNUNET_free (sigs);
     321           0 :     GNUNET_free (dks);
     322           0 :     GNUNET_free (eddsa_priv);
     323           0 :     return 1;
     324             :   }
     325           3 :   GNUNET_DISK_file_close (fh);
     326          16 :   for (unsigned int i=0;i<dks_len;i++)
     327             :   {
     328          13 :     struct TALER_DenominationKeyValidityPS *dk = &dks[i];
     329             : 
     330          13 :     if (verbose)
     331           0 :       print_dk (dk);
     332          13 :     kv.start = dk->start;
     333          13 :     kv.expire_withdraw = dk->expire_withdraw;
     334          13 :     kv.expire_deposit = dk->expire_deposit;
     335          13 :     kv.expire_legal = dk->expire_legal;
     336          13 :     kv.value = dk->value;
     337          13 :     kv.fee_withdraw = dk->fee_withdraw;
     338          13 :     kv.fee_deposit = dk->fee_deposit;
     339          13 :     kv.fee_refresh = dk->fee_refresh;
     340          13 :     kv.fee_refund = dk->fee_refund;
     341          13 :     kv.denom_hash = dk->denom_hash;
     342             : 
     343             :     /* Finally sign ... */
     344          13 :     GNUNET_assert (GNUNET_OK ==
     345             :                    GNUNET_CRYPTO_eddsa_sign (eddsa_priv,
     346             :                                              &kv.purpose,
     347             :                                              &sigs[i].eddsa_sig));
     348             :   }
     349             : 
     350           3 :   if (NULL == output_file)
     351             :   {
     352           0 :     fprintf (stderr,
     353             :              "Output file not given\n");
     354           0 :     TALER_AUDITORDB_plugin_unload (adb);
     355           0 :     GNUNET_free (dks);
     356           0 :     GNUNET_free (sigs);
     357           0 :     GNUNET_free (eddsa_priv);
     358           0 :     return 1;
     359             :   }
     360             : 
     361             :   /* Create required tables */
     362           3 :   if (GNUNET_OK !=
     363           3 :       adb->create_tables (adb->cls))
     364             :   {
     365           0 :     fprintf (stderr,
     366             :              "Failed to create tables in auditor's database\n");
     367           0 :     TALER_AUDITORDB_plugin_unload (adb);
     368           0 :     GNUNET_free (dks);
     369           0 :     GNUNET_free (sigs);
     370           0 :     GNUNET_free (eddsa_priv);
     371           0 :     return 3;
     372             :   }
     373             : 
     374             : 
     375             :   /* Update DB */
     376             :   {
     377             :     enum GNUNET_DB_QueryStatus qs;
     378             :     struct TALER_AUDITORDB_Session *session;
     379             : 
     380           3 :     session = adb->get_session (adb->cls);
     381           3 :     if (NULL == session)
     382             :     {
     383           0 :       fprintf (stderr,
     384             :                "Failed to initialize database session\n");
     385           0 :       TALER_AUDITORDB_plugin_unload (adb);
     386           0 :       GNUNET_free (dks);
     387           0 :       GNUNET_free (sigs);
     388           0 :       GNUNET_free (eddsa_priv);
     389           0 :       return 3;
     390             :     }
     391          16 :     for (unsigned int i=0;i<dks_len;i++)
     392             :     {
     393          13 :       const struct TALER_DenominationKeyValidityPS *dk = &dks[i];
     394             : 
     395          13 :       qs = adb->insert_denomination_info (adb->cls,
     396             :                                           session,
     397             :                                           dk);
     398          13 :       if (0 > qs)
     399             :       {
     400           0 :         fprintf (stderr,
     401             :                  "Failed to store key in auditor DB\n");
     402           0 :         TALER_AUDITORDB_plugin_unload (adb);
     403           0 :         GNUNET_free (dks);
     404           0 :         GNUNET_free (sigs);
     405           0 :         GNUNET_free (eddsa_priv);
     406           0 :         return 3;
     407             :       }
     408             :     }
     409             :   }
     410           3 :   TALER_AUDITORDB_plugin_unload (adb);
     411             : 
     412             :   /* write result to disk */
     413           3 :   if (GNUNET_OK !=
     414           3 :       TALER_EXCHANGEDB_auditor_write (output_file,
     415             :                                       &apub,
     416             :                                       auditor_url,
     417             :                                       sigs,
     418             :                                       &master_public_key,
     419             :                                       dks_len,
     420             :                                       dks))
     421             :   {
     422           0 :     fprintf (stderr,
     423             :              "Failed to write to file `%s': %s\n",
     424             :              output_file,
     425           0 :              STRERROR (errno));
     426           0 :     GNUNET_free (sigs);
     427           0 :     GNUNET_free (dks);
     428           0 :     return 1;
     429             :   }
     430           3 :   GNUNET_free (sigs);
     431           3 :   GNUNET_free (dks);
     432           3 :   GNUNET_free (eddsa_priv);
     433           3 :   return 0;
     434             : }
     435             : 
     436             : /* end of taler-auditor-sign.c */

Generated by: LCOV version 1.13