LCOV - code coverage report
Current view: top level - testing - test_exchange_api_revocation.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 71 71
Test Date: 2026-10-17 15:46:49 Functions: 100.0 % 3 3

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2014--2023 Taler Systems SA
       4              : 
       5              :   TALER is free software; you can redistribute it and/or modify
       6              :   it under the terms of the GNU General Public License as
       7              :   published by the Free Software Foundation; either version 3, or
       8              :   (at your option) any later version.
       9              : 
      10              :   TALER is distributed in the hope that it will be useful, but
      11              :   WITHOUT ANY WARRANTY; without even the implied warranty of
      12              :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13              :   GNU General Public License for more details.
      14              : 
      15              :   You should have received a copy of the GNU General Public
      16              :   License along with TALER; see the file COPYING.  If not, see
      17              :   <http://www.gnu.org/licenses/>
      18              : */
      19              : /**
      20              :  * @file testing/test_exchange_api_revocation.c
      21              :  * @brief testcase to test key revocation handling via the exchange's HTTP API interface
      22              :  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
      23              :  * @author Christian Grothoff
      24              :  * @author Marcello Stanisci
      25              :  */
      26              : #include "taler/taler_util.h"
      27              : #include "taler/taler_json_lib.h"
      28              : #include <gnunet/gnunet_util_lib.h>
      29              : #include <gnunet/gnunet_testing_lib.h>
      30              : #include <microhttpd.h>
      31              : #include "taler/taler_bank_service.h"
      32              : #include "taler/taler_testing_lib.h"
      33              : 
      34              : /**
      35              :  * Configuration file we use.  One (big) configuration is used
      36              :  * for the various components for this test.
      37              :  */
      38              : static char *config_file;
      39              : 
      40              : /**
      41              :  * Our credentials.
      42              :  */
      43              : static struct TALER_TESTING_Credentials cred;
      44              : 
      45              : 
      46              : /**
      47              :  * Execute the taler-exchange-wirewatch command with
      48              :  * our configuration file.
      49              :  *
      50              :  * @param label label to use for the command.
      51              :  */
      52              : static struct TALER_TESTING_Command
      53            8 : CMD_EXEC_WIREWATCH (const char *label)
      54              : {
      55            8 :   return TALER_TESTING_cmd_exec_wirewatch2 (label,
      56              :                                             config_file,
      57              :                                             "exchange-account-2");
      58              : }
      59              : 
      60              : 
      61              : /**
      62              :  * Main function that will tell the interpreter what commands to
      63              :  * run.
      64              :  *
      65              :  * @param cls closure
      66              :  */
      67              : static void
      68            2 : run (void *cls,
      69              :      struct TALER_TESTING_Interpreter *is)
      70              : {
      71              :   struct TALER_TESTING_Command revocation[] = {
      72            2 :     TALER_TESTING_cmd_run_fakebank ("run-fakebank",
      73            2 :                                     cred.cfg,
      74              :                                     "exchange-account-2"),
      75            2 :     TALER_TESTING_cmd_system_start ("start-taler",
      76              :                                     config_file,
      77              :                                     "-e",
      78              :                                     NULL),
      79            2 :     TALER_TESTING_cmd_get_exchange ("get-exchange",
      80            2 :                                     cred.cfg,
      81              :                                     NULL,
      82              :                                     true,
      83              :                                     true),
      84              :     /**
      85              :      * Fill reserve with EUR:10.02, as withdraw fee is 1 ct per
      86              :      * config.
      87              :      */
      88            2 :     TALER_TESTING_cmd_admin_add_incoming ("create-reserve-1",
      89              :                                           "EUR:10.02",
      90              :                                           &cred.ba,
      91              :                                           cred.user42_payto),
      92            2 :     TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-1",
      93              :                                                  "EUR:10.02",
      94              :                                                  cred.user42_payto,
      95              :                                                  cred.exchange_payto,
      96              :                                                  "create-reserve-1"),
      97              :     /**
      98              :      * Run wire-watch to trigger the reserve creation.
      99              :      */
     100            2 :     CMD_EXEC_WIREWATCH ("wirewatch-4"),
     101              :     /* Withdraw a 5 EUR coin, at fee of 1 ct */
     102            2 :     TALER_TESTING_cmd_withdraw_amount ("withdraw-revocation-coin-1",
     103              :                                        "create-reserve-1",
     104              :                                        "EUR:5",
     105              :                                        0, /* age restriction off */
     106              :                                        MHD_HTTP_OK),
     107              :     /* Withdraw another 5 EUR coin, at fee of 1 ct */
     108            2 :     TALER_TESTING_cmd_withdraw_amount ("withdraw-revocation-coin-2",
     109              :                                        "create-reserve-1",
     110              :                                        "EUR:5",
     111              :                                        0, /* age restriction off */
     112              :                                        MHD_HTTP_OK),
     113              :     /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin (in full)
     114              :      * (merchant would receive EUR:0.99 due to 1 ct deposit fee) *///
     115            2 :     TALER_TESTING_cmd_set_var (
     116              :       "account-priv",
     117              :       TALER_TESTING_cmd_deposit (
     118              :         "deposit-partial-fail-kyc",
     119              :         "withdraw-revocation-coin-1",
     120              :         0,
     121              :         cred.user42_payto,
     122              :         "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}",
     123            2 :         GNUNET_TIME_UNIT_ZERO,
     124              :         "EUR:1",
     125              :         MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)),
     126            2 :     TALER_TESTING_cmd_admin_add_kycauth (
     127              :       "kyc-auth-transfer",
     128              :       "EUR:0.01",
     129              :       &cred.ba,
     130              :       cred.user42_payto,
     131              :       "deposit-partial-fail-kyc"),
     132            2 :     CMD_EXEC_WIREWATCH (
     133              :       "import-kyc-account-withdraw"),
     134            2 :     TALER_TESTING_cmd_deposit (
     135              :       "deposit-partial",
     136              :       "withdraw-revocation-coin-1",
     137              :       0,
     138              :       cred.user42_payto,
     139              :       "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:2\"}]}",
     140            2 :       GNUNET_TIME_UNIT_ZERO,
     141              :       "EUR:1",
     142              :       MHD_HTTP_OK),
     143              :     /* Deposit another coin in full */
     144            2 :     TALER_TESTING_cmd_deposit (
     145              :       "deposit-full",
     146              :       "withdraw-revocation-coin-2",
     147              :       0,
     148              :       cred.user42_payto,
     149              :       "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:5\"}]}",
     150            2 :       GNUNET_TIME_UNIT_ZERO,
     151              :       "EUR:5",
     152              :       MHD_HTTP_OK),
     153              :     /**
     154              :      * Melt SOME of the rest of the coin's value
     155              :      * (EUR:3.17 = 3x EUR:1.03 + 7x EUR:0.13)
     156              :      */
     157            2 :     TALER_TESTING_cmd_melt ("refresh-melt-1",
     158              :                             "withdraw-revocation-coin-1",
     159              :                             MHD_HTTP_OK,
     160              :                             NULL),
     161              :     /**
     162              :      * Complete (successful) melt operation, and withdraw the coins
     163              :      */
     164            2 :     TALER_TESTING_cmd_melt_reveal ("refresh-reveal-1",
     165              :                                    "refresh-melt-1",
     166              :                                    MHD_HTTP_OK),
     167              :     /* Try to recoup before it's allowed */
     168            2 :     TALER_TESTING_cmd_recoup_refresh ("recoup-not-allowed",
     169              :                                       MHD_HTTP_GONE,
     170              :                                       "refresh-reveal-1#0",
     171              :                                       "refresh-melt-1",
     172              :                                       "EUR:0.1"),
     173              :     /* Make refreshed coin invalid */
     174            2 :     TALER_TESTING_cmd_revoke ("revoke-2-EUR:5",
     175              :                               MHD_HTTP_OK,
     176              :                               "refresh-melt-1",
     177              :                               config_file),
     178              :     /* Also make fully spent coin invalid (should be same denom) */
     179            2 :     TALER_TESTING_cmd_revoke ("revoke-2-EUR:5",
     180              :                               MHD_HTTP_OK,
     181              :                               "withdraw-revocation-coin-2",
     182              :                               config_file),
     183              :     /* Refund fully spent coin (which should fail) */
     184            2 :     TALER_TESTING_cmd_recoup ("recoup-fully-spent",
     185              :                               MHD_HTTP_CONFLICT,
     186              :                               "withdraw-revocation-coin-2",
     187              :                               "EUR:0.1"),
     188              :     /* Refund coin to original coin */
     189            2 :     TALER_TESTING_cmd_recoup_refresh ("recoup-1a",
     190              :                                       MHD_HTTP_OK,
     191              :                                       "refresh-reveal-1#0",
     192              :                                       "refresh-melt-1",
     193              :                                       "EUR:1"),
     194            2 :     TALER_TESTING_cmd_recoup_refresh ("recoup-1b",
     195              :                                       MHD_HTTP_OK,
     196              :                                       "refresh-reveal-1#1",
     197              :                                       "refresh-melt-1",
     198              :                                       "EUR:1"),
     199            2 :     TALER_TESTING_cmd_recoup_refresh ("recoup-1c",
     200              :                                       MHD_HTTP_OK,
     201              :                                       "refresh-reveal-1#2",
     202              :                                       "refresh-melt-1",
     203              :                                       "EUR:1"),
     204              :     /* Repeat recoup to test idempotency */
     205            2 :     TALER_TESTING_cmd_recoup_refresh ("recoup-1c",
     206              :                                       MHD_HTTP_OK,
     207              :                                       "refresh-reveal-1#2",
     208              :                                       "refresh-melt-1",
     209              :                                       "EUR:1"),
     210            2 :     TALER_TESTING_cmd_recoup_refresh ("recoup-1c",
     211              :                                       MHD_HTTP_OK,
     212              :                                       "refresh-reveal-1#2",
     213              :                                       "refresh-melt-1",
     214              :                                       "EUR:1"),
     215            2 :     TALER_TESTING_cmd_recoup_refresh ("recoup-1c",
     216              :                                       MHD_HTTP_OK,
     217              :                                       "refresh-reveal-1#2",
     218              :                                       "refresh-melt-1",
     219              :                                       "EUR:1"),
     220            2 :     TALER_TESTING_cmd_recoup_refresh ("recoup-1c",
     221              :                                       MHD_HTTP_OK,
     222              :                                       "refresh-reveal-1#2",
     223              :                                       "refresh-melt-1",
     224              :                                       "EUR:1"),
     225              :     /* Now we have EUR:3.83 EUR back after 3x EUR:1 in recoups */
     226              :     /* Melt original coin AGAIN, but only create one 0.1 EUR coin;
     227              :        This costs EUR:0.03 in refresh and EUR:01 in withdraw fees,
     228              :        leaving EUR:3.69. */
     229            2 :     TALER_TESTING_cmd_melt ("refresh-melt-2",
     230              :                             "withdraw-revocation-coin-1",
     231              :                             MHD_HTTP_OK,
     232              :                             "EUR:0.1",
     233              :                             NULL),
     234              :     /**
     235              :      * Complete (successful) melt operation, and withdraw the coins
     236              :      */
     237            2 :     TALER_TESTING_cmd_melt_reveal ("refresh-reveal-2",
     238              :                                    "refresh-melt-2",
     239              :                                    MHD_HTTP_OK),
     240              :     /* Revokes refreshed EUR:0.1 coin  */
     241            2 :     TALER_TESTING_cmd_revoke ("revoke-3-EUR:0.1",
     242              :                               MHD_HTTP_OK,
     243              :                               "refresh-reveal-2",
     244              :                               config_file),
     245              :     /* Revoke also original coin denomination */
     246            2 :     TALER_TESTING_cmd_revoke ("revoke-4-EUR:5",
     247              :                               MHD_HTTP_OK,
     248              :                               "withdraw-revocation-coin-1",
     249              :                               config_file),
     250              :     /* Refund coin EUR:0.1 to original coin, creating zombie! */
     251            2 :     TALER_TESTING_cmd_recoup_refresh ("recoup-2",
     252              :                                       MHD_HTTP_OK,
     253              :                                       "refresh-reveal-2",
     254              :                                       "refresh-melt-2",
     255              :                                       "EUR:0.1"),
     256              :     /* Due to recoup, original coin is now at EUR:3.79 */
     257              :     /* Refund original (now zombie) coin to reserve */
     258            2 :     TALER_TESTING_cmd_recoup ("recoup-3",
     259              :                               MHD_HTTP_OK,
     260              :                               "withdraw-revocation-coin-1",
     261              :                               "EUR:3.79"),
     262              :     /* Check the money is back with the reserve */
     263            2 :     TALER_TESTING_cmd_status ("recoup-reserve-status-1",
     264              :                               "create-reserve-1",
     265              :                               "EUR:3.79",
     266              :                               MHD_HTTP_OK),
     267              :     /* Batch recoup: three coins from one withdraw operation, two of
     268              :        them recouped in one request; the histories must show it. */
     269            2 :     TALER_TESTING_cmd_admin_add_incoming ("create-reserve-2",
     270              :                                           "EUR:30.04",
     271              :                                           &cred.ba,
     272              :                                           cred.user42_payto),
     273            2 :     TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-2",
     274              :                                                  "EUR:30.04",
     275              :                                                  cred.user42_payto,
     276              :                                                  cred.exchange_payto,
     277              :                                                  "create-reserve-2"),
     278            2 :     CMD_EXEC_WIREWATCH ("wirewatch-5"),
     279            2 :     TALER_TESTING_cmd_batch_withdraw ("batch-withdraw-revocation",
     280              :                                       "create-reserve-2",
     281              :                                       MHD_HTTP_OK,
     282              :                                       "EUR:10",
     283              :                                       "EUR:10",
     284              :                                       "EUR:10",
     285              :                                       NULL),
     286            2 :     TALER_TESTING_cmd_revoke ("revoke-5-EUR:10",
     287              :                               MHD_HTTP_OK,
     288              :                               "batch-withdraw-revocation",
     289              :                               config_file),
     290            2 :     TALER_TESTING_cmd_recoup_batch ("recoup-batch",
     291              :                                     MHD_HTTP_OK,
     292              :                                     "batch-withdraw-revocation",
     293              :                                     "0,2",
     294              :                                     "EUR:10"),
     295            2 :     TALER_TESTING_cmd_coin_history ("coin-history-recouped",
     296              :                                     "batch-withdraw-revocation#0",
     297              :                                     "EUR:0",
     298              :                                     MHD_HTTP_OK),
     299              :     /* the coin that was not recouped is still unknown to the exchange */
     300            2 :     TALER_TESTING_cmd_coin_history ("coin-history-not-recouped",
     301              :                                     "batch-withdraw-revocation#1",
     302              :                                     "EUR:10",
     303              :                                     MHD_HTTP_NOT_FOUND),
     304            2 :     TALER_TESTING_cmd_reserve_history ("reserve-history-recoup",
     305              :                                        "create-reserve-2",
     306              :                                        "EUR:20.01",
     307              :                                        MHD_HTTP_OK),
     308              :     /* replaying the request is idempotent (last, as the history
     309              :        checks above would otherwise expect its entries twice) */
     310            2 :     TALER_TESTING_cmd_recoup_batch ("recoup-batch-again",
     311              :                                     MHD_HTTP_OK,
     312              :                                     "batch-withdraw-revocation",
     313              :                                     "0,2",
     314              :                                     "EUR:10"),
     315              :     /* Revocation of an online signing key: get a coin to spend after
     316              :        the revocation (age-restricted, as the plain denominations of
     317              :        all these values were revoked above) ... */
     318            2 :     TALER_TESTING_cmd_admin_add_incoming ("create-reserve-3",
     319              :                                           "EUR:1.01",
     320              :                                           &cred.ba,
     321              :                                           cred.user42_payto),
     322            2 :     CMD_EXEC_WIREWATCH ("wirewatch-6"),
     323            2 :     TALER_TESTING_cmd_withdraw_amount ("withdraw-signkey-revocation",
     324              :                                        "create-reserve-3",
     325              :                                        "EUR:1",
     326              :                                        13, /* age restriction */
     327              :                                        MHD_HTTP_OK),
     328              :     /* ... revoke the key that signed "deposit-full", which the exchange
     329              :        must refuse with a bad master signature ... */
     330            2 :     TALER_TESTING_cmd_revoke_sign_key ("revoke-signkey-bad-sig",
     331              :                                        MHD_HTTP_FORBIDDEN,
     332              :                                        true,
     333              :                                        "deposit-full"),
     334            2 :     TALER_TESTING_cmd_revoke_sign_key ("revoke-signkey",
     335              :                                        MHD_HTTP_NO_CONTENT,
     336              :                                        false,
     337              :                                        "deposit-full"),
     338              :     /* ... sign the replacement key the security module created ... */
     339            2 :     TALER_TESTING_cmd_exec_offline_sign_keys ("sign-replacement-signkey",
     340              :                                               config_file),
     341              :     /* ... then /keys must no longer offer the revoked key, so that
     342              :        clients reject replies signed with it ... */
     343            2 :     TALER_TESTING_cmd_get_exchange ("get-exchange-after-signkey-revocation",
     344            2 :                                     cred.cfg,
     345              :                                     NULL,
     346              :                                     true,
     347              :                                     true),
     348            2 :     TALER_TESTING_cmd_check_signkey_revoked (
     349              :       "check-signkey-revoked",
     350              :       "deposit-full",
     351              :       "get-exchange",
     352              :       "get-exchange-after-signkey-revocation"),
     353              :     /* ... and the exchange must sign with the replacement key, which
     354              :        the client accepts. */
     355            2 :     TALER_TESTING_cmd_deposit (
     356              :       "deposit-after-signkey-revocation",
     357              :       "withdraw-signkey-revocation",
     358              :       0,
     359              :       cred.user42_payto,
     360              :       "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}",
     361            2 :       GNUNET_TIME_UNIT_ZERO,
     362              :       "EUR:1",
     363              :       MHD_HTTP_OK),
     364            2 :     TALER_TESTING_cmd_end ()
     365              :   };
     366              : 
     367              :   (void) cls;
     368            2 :   TALER_TESTING_run (is,
     369              :                      revocation);
     370            2 : }
     371              : 
     372              : 
     373              : int
     374            2 : main (int argc,
     375              :       char *const *argv)
     376              : {
     377              :   (void) argc;
     378              :   {
     379              :     char *cipher;
     380              : 
     381            2 :     cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]);
     382            2 :     GNUNET_assert (NULL != cipher);
     383            2 :     GNUNET_asprintf (&config_file,
     384              :                      "test_exchange_api-%s.conf",
     385              :                      cipher);
     386            2 :     GNUNET_free (cipher);
     387              :   }
     388            2 :   return TALER_TESTING_main (argv,
     389              :                              "INFO",
     390              :                              config_file,
     391              :                              "exchange-account-2",
     392              :                              TALER_TESTING_BS_FAKEBANK,
     393              :                              &cred,
     394              :                              &run,
     395              :                              NULL);
     396              : }
     397              : 
     398              : 
     399              : /* end of test_exchange_api_revocation.c */
        

Generated by: LCOV version 2.0-1