LCOV - code coverage report
Current view: top level - exchangedb - exchangedb_signkeys.c (source / functions) Hit Total Coverage
Test: rcoverage.info Lines: 24 30 80.0 %
Date: 2017-09-17 17:24:28 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014, 2015, 2016 Inria & 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 exchangedb/exchangedb_signkeys.c
      18             :  * @brief I/O operations for the Exchange's private online signing keys
      19             :  * @author Florian Dold
      20             :  * @author Benedikt Mueller
      21             :  * @author Sree Harsha Totakura
      22             :  * @author Christian Grothoff
      23             :  */
      24             : #include "platform.h"
      25             : #include "taler_exchangedb_lib.h"
      26             : 
      27             : 
      28             : /**
      29             :  * Closure for the #signkeys_iterate_dir_iter().
      30             :  */
      31             : struct SignkeysIterateContext
      32             : {
      33             : 
      34             :   /**
      35             :    * Function to call on each signing key.
      36             :    */
      37             :   TALER_EXCHANGEDB_SigningKeyIterator it;
      38             : 
      39             :   /**
      40             :    * Closure for @e it.
      41             :    */
      42             :   void *it_cls;
      43             : };
      44             : 
      45             : 
      46             : /**
      47             :  * Function called on each file in the directory with our signing
      48             :  * keys. Parses the file and calls the iterator from @a cls.
      49             :  *
      50             :  * @param cls the `struct SignkeysIterateContext *`
      51             :  * @param filename name of the file to parse
      52             :  * @return #GNUNET_OK to continue,
      53             :  *         #GNUNET_NO to stop iteration without error,
      54             :  *         #GNUNET_SYSERR to stop iteration with error
      55             :  */
      56             : static int
      57           7 : signkeys_iterate_dir_iter (void *cls,
      58             :                            const char *filename)
      59             : {
      60           7 :   struct SignkeysIterateContext *skc = cls;
      61             :   ssize_t nread;
      62             :   struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP issue;
      63             : 
      64           7 :   nread = GNUNET_DISK_fn_read (filename,
      65             :                                &issue,
      66             :                                sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP));
      67           7 :   if (nread != sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP))
      68             :   {
      69           0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
      70             :                 "Invalid signkey file `%s': wrong size (%d, expected %u)\n",
      71             :                 filename,
      72             :                 (int) nread,
      73             :                 (unsigned int) sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP));
      74           0 :     return GNUNET_OK;
      75             :   }
      76           7 :   return skc->it (skc->it_cls,
      77             :                   filename,
      78             :                   &issue);
      79             : }
      80             : 
      81             : 
      82             : /**
      83             :  * Call @a it for each signing key found in the @a exchange_base_dir.
      84             :  *
      85             :  * @param exchange_base_dir base directory for the exchange,
      86             :  *                      the signing keys must be in the #TALER_EXCHANGEDB_DIR_SIGNING_KEYS
      87             :  *                      subdirectory
      88             :  * @param it function to call on each signing key
      89             :  * @param it_cls closure for @a it
      90             :  * @return number of files found (may not match
      91             :  *         number of keys given to @a it as malformed
      92             :  *         files are simply skipped), -1 on error
      93             :  */
      94             : int
      95           7 : TALER_EXCHANGEDB_signing_keys_iterate (const char *exchange_base_dir,
      96             :                                        TALER_EXCHANGEDB_SigningKeyIterator it,
      97             :                                        void *it_cls)
      98             : {
      99             :   char *signkey_dir;
     100             :   struct SignkeysIterateContext skc;
     101             :   int ret;
     102             : 
     103           7 :   GNUNET_asprintf (&signkey_dir,
     104             :                    "%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_SIGNING_KEYS,
     105             :                    exchange_base_dir);
     106           7 :   skc.it = it;
     107           7 :   skc.it_cls = it_cls;
     108           7 :   ret = GNUNET_DISK_directory_scan (signkey_dir,
     109             :                                     &signkeys_iterate_dir_iter,
     110             :                                     &skc);
     111           7 :   GNUNET_free (signkey_dir);
     112           7 :   return ret;
     113             : }
     114             : 
     115             : 
     116             : /**
     117             :  * Obtain the name of the directory we use to store signing
     118             :  * keys created at time @a start.
     119             :  *
     120             :  * @param exchange_directory base director where we store key material
     121             :  * @param start time at which we create the signing key
     122             :  * @return name of the directory we should use, basically "$EXCHANGEDIR/$TIME/";
     123             :  *         (valid until next call to this function)
     124             :  */
     125             : static char *
     126          12 : get_signkey_file (const char *exchange_directory,
     127             :                   struct GNUNET_TIME_Absolute start)
     128             : {
     129             :   char *fn;
     130             : 
     131          12 :   GNUNET_asprintf (&fn,
     132             :                    "%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_SIGNING_KEYS DIR_SEPARATOR_STR "%llu",
     133             :                    exchange_directory,
     134          12 :                    (unsigned long long) start.abs_value_us);
     135          12 :   return fn;
     136             : }
     137             : 
     138             : 
     139             : /**
     140             :  * Exports a signing key to the given file.
     141             :  *
     142             :  * @param exchange_base_dir base directory for the keys
     143             :  * @param start start time of the validity for the key
     144             :  * @param ski the signing key
     145             :  * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
     146             :  */
     147             : int
     148          12 : TALER_EXCHANGEDB_signing_key_write (const char *exchange_base_dir,
     149             :                                     struct GNUNET_TIME_Absolute start,
     150             :                                     const struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP *ski)
     151             : {
     152             :   char *skf;
     153             :   ssize_t nwrite;
     154             : 
     155          12 :   skf = get_signkey_file (exchange_base_dir,
     156             :                           start);
     157          12 :   if (GNUNET_OK !=
     158          12 :       GNUNET_DISK_directory_create_for_file (skf))
     159           0 :     return GNUNET_SYSERR;
     160          12 :   nwrite = GNUNET_DISK_fn_write (skf,
     161             :                                  ski,
     162             :                                  sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP),
     163             :                                  GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_USER_READ);
     164          12 :   if (sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP) != nwrite)
     165             :   {
     166           0 :     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
     167             :                               "write",
     168             :                               skf);
     169           0 :     GNUNET_free (skf);
     170           0 :     return GNUNET_SYSERR;
     171             :   }
     172          12 :   GNUNET_free (skf);
     173          12 :   return GNUNET_OK;
     174             : }
     175             : 
     176             : /* end of exchangedb_signkeys.c */

Generated by: LCOV version 1.13