LCOV - code coverage report
Current view: top level - exchangedb - test_signkey_revocations.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 46 46
Test Date: 2026-09-11 18:55:36 Functions: 100.0 % 6 6

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2026 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 exchangedb/test_signkey_revocations.c
      18              :  * @brief tests for the exchangedb functions whose primary table is
      19              :  *        `signkey_revocations`
      20              :  * @author Christian Grothoff
      21              :  *
      22              :  * Covers #TALER_EXCHANGEDB_insert_signkey_revocation() and
      23              :  * #TALER_EXCHANGEDB_get_signkey_revocation().
      24              :  *
      25              :  * `signkey_revocations` references `exchange_sign_keys`, and both functions
      26              :  * find the row through the signing key rather than through the revocation's
      27              :  * own primary key -- so an unknown signing key has to come back as "no
      28              :  * revocation" rather than as an error.  The fixture is inserted with
      29              :  * #TALER_EXCHANGEDB_insert_signkey(), whose own table is covered by
      30              :  * test_exchange_sign_keys.c.
      31              :  */
      32              : #include "test_common.h"
      33              : #include "exchange-database/insert_signkey.h"
      34              : #include "exchange-database/insert_signkey_revocation.h"
      35              : #include "exchange-database/get_signkey_revocation.h"
      36              : #include "exchange-database/iterate_active_signkeys.h"
      37              : 
      38              : 
      39              : /**
      40              :  * Insert a signing key that is valid for another hour.
      41              :  *
      42              :  * @param pg the database context
      43              :  * @param seed seed for the key and its master signature
      44              :  * @param[out] exchange_pub set to the public key
      45              :  */
      46              : static void
      47            2 : add_signkey (struct TALER_EXCHANGEDB_PostgresContext *pg,
      48              :              uint32_t seed,
      49              :              struct TALER_ExchangePublicKeyP *exchange_pub)
      50              : {
      51            2 :   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
      52              :   struct TALER_MasterSignatureP master_sig;
      53              :   struct TALER_EXCHANGEDB_SignkeyMetaData meta;
      54              : 
      55            2 :   TDB_fill (exchange_pub,
      56              :             sizeof (*exchange_pub),
      57              :             seed);
      58            2 :   TDB_FILL (master_sig,
      59              :             seed);
      60            2 :   meta.start = GNUNET_TIME_absolute_to_timestamp (now);
      61              :   meta.expire_sign
      62            2 :     = GNUNET_TIME_absolute_to_timestamp (
      63              :         GNUNET_TIME_absolute_add (now,
      64              :                                   GNUNET_TIME_UNIT_HOURS));
      65              :   meta.expire_legal
      66            2 :     = GNUNET_TIME_absolute_to_timestamp (
      67              :         GNUNET_TIME_absolute_add (now,
      68              :                                   GNUNET_TIME_relative_multiply (
      69              :                                     GNUNET_TIME_UNIT_HOURS,
      70              :                                     24)));
      71            2 :   GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
      72              :                  TALER_EXCHANGEDB_insert_signkey (pg,
      73              :                                                   exchange_pub,
      74              :                                                   &meta,
      75              :                                                   &master_sig));
      76            2 : }
      77              : 
      78              : 
      79              : /**
      80              :  * Counts the keys the active-signkey iterator reports.
      81              :  */
      82              : struct CountContext
      83              : {
      84              :   /**
      85              :    * Key we are looking for.
      86              :    */
      87              :   const struct TALER_ExchangePublicKeyP *exchange_pub;
      88              : 
      89              :   /**
      90              :    * How many times did we see @e exchange_pub?
      91              :    */
      92              :   unsigned int matched;
      93              : };
      94              : 
      95              : 
      96              : /**
      97              :  * Callback for #TALER_EXCHANGEDB_iterate_active_signkeys().
      98              :  *
      99              :  * @param cls a `struct CountContext *`
     100              :  * @param exchange_pub public key of the exchange
     101              :  * @param meta meta data of @a exchange_pub
     102              :  * @param master_sig master signature over @a exchange_pub
     103              :  */
     104              : static void
     105            3 : count_cb (void *cls,
     106              :           const struct TALER_ExchangePublicKeyP *exchange_pub,
     107              :           const struct TALER_EXCHANGEDB_SignkeyMetaData *meta,
     108              :           const struct TALER_MasterSignatureP *master_sig)
     109              : {
     110            3 :   struct CountContext *ctx = cls;
     111              : 
     112              :   (void) meta;
     113              :   (void) master_sig;
     114            3 :   if (0 == GNUNET_memcmp (exchange_pub,
     115              :                           ctx->exchange_pub))
     116            1 :     ctx->matched++;
     117            3 : }
     118              : 
     119              : 
     120              : /**
     121              :  * A signing key that does not exist has no revocation, and revoking it
     122              :  * does nothing.
     123              :  *
     124              :  * @param pg the database context
     125              :  * @return 0 on success
     126              :  */
     127              : static int
     128            1 : check_unknown_signkey (struct TALER_EXCHANGEDB_PostgresContext *pg)
     129              : {
     130              :   struct TALER_ExchangePublicKeyP exchange_pub;
     131              :   struct TALER_MasterSignatureP master_sig;
     132              :   struct TALER_MasterSignatureP got;
     133              : 
     134            1 :   TDB_FILL (exchange_pub,
     135              :             1);
     136            1 :   TDB_FILL (master_sig,
     137              :             1);
     138            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     139              :           TALER_EXCHANGEDB_get_signkey_revocation (pg,
     140              :                                                    &exchange_pub,
     141              :                                                    &got));
     142            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     143              :           TALER_EXCHANGEDB_insert_signkey_revocation (pg,
     144              :                                                       &exchange_pub,
     145              :                                                       &master_sig));
     146            1 :   FAILIF (0 != TDB_count (pg,
     147              :                           "FROM signkey_revocations"));
     148            1 :   return 0;
     149              : }
     150              : 
     151              : 
     152              : /**
     153              :  * A key that exists but was not revoked has no revocation either.
     154              :  *
     155              :  * @param pg the database context
     156              :  * @return 0 on success
     157              :  */
     158              : static int
     159            1 : check_not_revoked (struct TALER_EXCHANGEDB_PostgresContext *pg)
     160              : {
     161              :   struct TALER_ExchangePublicKeyP exchange_pub;
     162              :   struct TALER_MasterSignatureP got;
     163              : 
     164            1 :   add_signkey (pg,
     165              :                2,
     166              :                &exchange_pub);
     167            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     168              :           TALER_EXCHANGEDB_get_signkey_revocation (pg,
     169              :                                                    &exchange_pub,
     170              :                                                    &got));
     171            1 :   return 0;
     172              : }
     173              : 
     174              : 
     175              : /**
     176              :  * Revoking a key records the signature and takes the key out of the
     177              :  * active set.
     178              :  *
     179              :  * @param pg the database context
     180              :  * @return 0 on success
     181              :  */
     182              : static int
     183            1 : check_revoke (struct TALER_EXCHANGEDB_PostgresContext *pg)
     184              : {
     185              :   struct TALER_ExchangePublicKeyP exchange_pub;
     186              :   struct TALER_MasterSignatureP master_sig;
     187              :   struct TALER_MasterSignatureP got;
     188              :   struct CountContext ctx;
     189              : 
     190            1 :   add_signkey (pg,
     191              :                3,
     192              :                &exchange_pub);
     193            1 :   TDB_FILL (master_sig,
     194              :             33);
     195              : 
     196              :   /* while unrevoked, the key is active */
     197            1 :   memset (&ctx,
     198              :           0,
     199              :           sizeof (ctx));
     200            1 :   ctx.exchange_pub = &exchange_pub;
     201            1 :   FAILIF (0 >=
     202              :           TALER_EXCHANGEDB_iterate_active_signkeys (pg,
     203              :                                                     &count_cb,
     204              :                                                     &ctx));
     205            1 :   FAILIF (1 != ctx.matched);
     206              : 
     207            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     208              :           TALER_EXCHANGEDB_insert_signkey_revocation (pg,
     209              :                                                       &exchange_pub,
     210              :                                                       &master_sig));
     211            1 :   memset (&got,
     212              :           0,
     213              :           sizeof (got));
     214            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     215              :           TALER_EXCHANGEDB_get_signkey_revocation (pg,
     216              :                                                    &exchange_pub,
     217              :                                                    &got));
     218            1 :   FAILIF (0 != GNUNET_memcmp (&got,
     219              :                               &master_sig));
     220              : 
     221              :   /* ...and now it is gone from the active set */
     222            1 :   memset (&ctx,
     223              :           0,
     224              :           sizeof (ctx));
     225            1 :   ctx.exchange_pub = &exchange_pub;
     226            1 :   FAILIF (0 >
     227              :           TALER_EXCHANGEDB_iterate_active_signkeys (pg,
     228              :                                                     &count_cb,
     229              :                                                     &ctx));
     230            1 :   FAILIF (0 != ctx.matched);
     231              : 
     232              :   /* the untouched key from the previous check is still fine */
     233              :   {
     234              :     struct TALER_ExchangePublicKeyP other;
     235              : 
     236            1 :     TDB_FILL (other,
     237              :               2);
     238            1 :     FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     239              :             TALER_EXCHANGEDB_get_signkey_revocation (pg,
     240              :                                                      &other,
     241              :                                                      &got));
     242              :   }
     243            1 :   FAILIF (1 != TDB_count (pg,
     244              :                           "FROM signkey_revocations"));
     245            1 :   return 0;
     246              : }
     247              : 
     248              : 
     249              : /**
     250              :  * The checks to run, in order.
     251              :  */
     252              : static const struct TDB_Test tests[] = {
     253              :   { "signkey-revocations-unknown-signkey",
     254              :     &check_unknown_signkey },
     255              :   { "signkey-revocations-not-revoked",
     256              :     &check_not_revoked },
     257              :   { "signkey-revocations-revoke",
     258              :     &check_revoke },
     259              :   { NULL, NULL }
     260              : };
     261              : 
     262              : 
     263              : int
     264            1 : main (int argc,
     265              :       char *const *argv)
     266              : {
     267            1 :   return TDB_main (argc,
     268              :                    argv,
     269              :                    "test-signkey-revocations",
     270              :                    "Tests for the exchangedb `signkey_revocations' table",
     271              :                    tests);
     272              : }
     273              : 
     274              : 
     275              : /* end of test_signkey_revocations.c */
        

Generated by: LCOV version 2.0-1