LCOV - code coverage report
Current view: top level - exchange - taler-exchange-httpd_csr.c (source / functions) Hit Total Coverage
Test: GNU Taler exchange coverage report Lines: 0 88 0.0 %
Date: 2022-08-25 06:15:09 Functions: 0 2 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014-2022 Taler Systems SA
       4             : 
       5             :   TALER is free software; you can redistribute it and/or modify
       6             :   it under the terms of the GNU Affero General Public License as
       7             :   published by the Free Software Foundation; either version 3,
       8             :   or (at your option) any later version.
       9             : 
      10             :   TALER is distributed in the hope that it will be useful,
      11             :   but WITHOUT ANY WARRANTY; without even the implied warranty
      12             :   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      13             :   See the GNU Affero General Public License for more details.
      14             : 
      15             :   You should have received a copy of the GNU Affero General
      16             :   Public License along with TALER; see the file COPYING.  If not,
      17             :   see <http://www.gnu.org/licenses/>
      18             : */
      19             : /**
      20             :  * @file taler-exchange-httpd_csr.c
      21             :  * @brief Handle /csr requests
      22             :  * @author Lucien Heuzeveldt
      23             :  * @author Gian Demarmles
      24             :  */
      25             : #include "platform.h"
      26             : #include <gnunet/gnunet_util_lib.h>
      27             : #include <jansson.h>
      28             : #include "taler_json_lib.h"
      29             : #include "taler_mhd_lib.h"
      30             : #include "taler-exchange-httpd_csr.h"
      31             : #include "taler-exchange-httpd_responses.h"
      32             : #include "taler-exchange-httpd_keys.h"
      33             : 
      34             : 
      35             : MHD_RESULT
      36           0 : TEH_handler_csr_melt (struct TEH_RequestContext *rc,
      37             :                       const json_t *root,
      38             :                       const char *const args[])
      39             : {
      40             :   struct TALER_RefreshMasterSecretP rms;
      41             :   unsigned int csr_requests_num;
      42             :   json_t *csr_requests;
      43             :   struct GNUNET_JSON_Specification spec[] = {
      44           0 :     GNUNET_JSON_spec_fixed_auto ("rms",
      45             :                                  &rms),
      46           0 :     GNUNET_JSON_spec_json ("nks",
      47             :                            &csr_requests),
      48           0 :     GNUNET_JSON_spec_end ()
      49             :   };
      50             :   enum TALER_ErrorCode ec;
      51             :   struct TEH_DenominationKey *dk;
      52             : 
      53             :   (void) args;
      54             :   /* parse input */
      55             :   {
      56             :     enum GNUNET_GenericReturnValue res;
      57             : 
      58           0 :     res = TALER_MHD_parse_json_data (rc->connection,
      59             :                                      root,
      60             :                                      spec);
      61           0 :     if (GNUNET_OK != res)
      62           0 :       return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
      63             :   }
      64           0 :   csr_requests_num = json_array_size (csr_requests);
      65           0 :   if ( (TALER_MAX_FRESH_COINS <= csr_requests_num) ||
      66             :        (0 == csr_requests_num) )
      67             :   {
      68           0 :     GNUNET_JSON_parse_free (spec);
      69           0 :     return TALER_MHD_reply_with_error (
      70             :       rc->connection,
      71             :       MHD_HTTP_BAD_REQUEST,
      72             :       TALER_EC_EXCHANGE_GENERIC_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE,
      73             :       NULL);
      74             :   }
      75             : 
      76           0 :   {
      77           0 :     struct TALER_ExchangeWithdrawValues ewvs[csr_requests_num];
      78             : 
      79           0 :     {
      80           0 :       struct TALER_CsNonce nonces[csr_requests_num];
      81           0 :       struct TALER_DenominationHashP denom_pub_hashes[csr_requests_num];
      82             : 
      83           0 :       for (unsigned int i = 0; i < csr_requests_num; i++)
      84             :       {
      85             :         uint32_t coin_off;
      86           0 :         struct TALER_DenominationHashP *denom_pub_hash = &denom_pub_hashes[i];
      87             :         struct GNUNET_JSON_Specification csr_spec[] = {
      88           0 :           GNUNET_JSON_spec_uint32 ("coin_offset",
      89             :                                    &coin_off),
      90           0 :           GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
      91             :                                        denom_pub_hash),
      92           0 :           GNUNET_JSON_spec_end ()
      93             :         };
      94             :         enum GNUNET_GenericReturnValue res;
      95             : 
      96           0 :         res = TALER_MHD_parse_json_array (rc->connection,
      97             :                                           csr_requests,
      98             :                                           csr_spec,
      99             :                                           i,
     100             :                                           -1);
     101           0 :         if (GNUNET_OK != res)
     102             :         {
     103           0 :           GNUNET_JSON_parse_free (spec);
     104           0 :           return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
     105             :         }
     106           0 :         TALER_cs_refresh_nonce_derive (&rms,
     107             :                                        coin_off,
     108             :                                        &nonces[i]);
     109             :       }
     110           0 :       GNUNET_JSON_parse_free (spec);
     111             : 
     112           0 :       for (unsigned int i = 0; i < csr_requests_num; i++)
     113             :       {
     114           0 :         const struct TALER_CsNonce *nonce = &nonces[i];
     115           0 :         const struct TALER_DenominationHashP *denom_pub_hash =
     116             :           &denom_pub_hashes[i];
     117           0 :         struct TALER_DenominationCSPublicRPairP *r_pub
     118             :           = &ewvs[i].details.cs_values;
     119             : 
     120           0 :         ewvs[i].cipher = TALER_DENOMINATION_CS;
     121             :         /* check denomination referenced by denom_pub_hash */
     122             :         {
     123             :           struct TEH_KeyStateHandle *ksh;
     124             : 
     125           0 :           ksh = TEH_keys_get_state ();
     126           0 :           if (NULL == ksh)
     127             :           {
     128           0 :             return TALER_MHD_reply_with_error (rc->connection,
     129             :                                                MHD_HTTP_INTERNAL_SERVER_ERROR,
     130             :                                                TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
     131             :                                                NULL);
     132             :           }
     133           0 :           dk = TEH_keys_denomination_by_hash2 (ksh,
     134             :                                                denom_pub_hash,
     135             :                                                NULL,
     136             :                                                NULL);
     137           0 :           if (NULL == dk)
     138             :           {
     139           0 :             return TEH_RESPONSE_reply_unknown_denom_pub_hash (
     140             :               rc->connection,
     141           0 :               &denom_pub_hash[i]);
     142             :           }
     143           0 :           if (GNUNET_TIME_absolute_is_past (dk->meta.expire_withdraw.abs_time))
     144             :           {
     145             :             /* This denomination is past the expiration time for withdraws/refreshes*/
     146           0 :             return TEH_RESPONSE_reply_expired_denom_pub_hash (
     147             :               rc->connection,
     148             :               denom_pub_hash,
     149             :               TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED,
     150             :               "csr-melt");
     151             :           }
     152           0 :           if (GNUNET_TIME_absolute_is_future (dk->meta.start.abs_time))
     153             :           {
     154             :             /* This denomination is not yet valid, no need to check
     155             :                for idempotency! */
     156           0 :             return TEH_RESPONSE_reply_expired_denom_pub_hash (
     157             :               rc->connection,
     158             :               denom_pub_hash,
     159             :               TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE,
     160             :               "csr-melt");
     161             :           }
     162           0 :           if (dk->recoup_possible)
     163             :           {
     164             :             /* This denomination has been revoked */
     165           0 :             return TEH_RESPONSE_reply_expired_denom_pub_hash (
     166             :               rc->connection,
     167             :               denom_pub_hash,
     168             :               TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED,
     169             :               "csr-melt");
     170             :           }
     171           0 :           if (TALER_DENOMINATION_CS != dk->denom_pub.cipher)
     172             :           {
     173             :             /* denomination is valid but not for CS */
     174           0 :             return TEH_RESPONSE_reply_invalid_denom_cipher_for_operation (
     175             :               rc->connection,
     176             :               denom_pub_hash);
     177             :           }
     178             :         }
     179             : 
     180             :         /* derive r_pub */
     181             :         // FIXME-#7272: bundle all requests into one derivation request (TEH_keys_..., crypto helper, security module)
     182           0 :         ec = TEH_keys_denomination_cs_r_pub_melt (denom_pub_hash,
     183             :                                                   nonce,
     184             :                                                   r_pub);
     185           0 :         if (TALER_EC_NONE != ec)
     186             :         {
     187           0 :           GNUNET_break (0);
     188           0 :           return TALER_MHD_reply_with_ec (rc->connection,
     189             :                                           ec,
     190             :                                           NULL);
     191             :         }
     192             :       }
     193             :     }
     194             : 
     195             :     /* send response */
     196             :     {
     197             :       json_t *csr_response_ewvs;
     198             :       json_t *csr_response;
     199             : 
     200           0 :       csr_response_ewvs = json_array ();
     201           0 :       for (unsigned int i = 0; i < csr_requests_num; i++)
     202             :       {
     203             :         json_t *csr_obj;
     204             : 
     205           0 :         csr_obj = GNUNET_JSON_PACK (
     206             :           TALER_JSON_pack_exchange_withdraw_values ("ewv",
     207             :                                                     &ewvs[i]));
     208           0 :         GNUNET_assert (NULL != csr_obj);
     209           0 :         GNUNET_assert (0 ==
     210             :                        json_array_append_new (csr_response_ewvs,
     211             :                                               csr_obj));
     212             :       }
     213           0 :       csr_response = GNUNET_JSON_PACK (
     214             :         GNUNET_JSON_pack_array_steal ("ewvs",
     215             :                                       csr_response_ewvs));
     216           0 :       GNUNET_assert (NULL != csr_response);
     217           0 :       return TALER_MHD_reply_json_steal (rc->connection,
     218             :                                          csr_response,
     219             :                                          MHD_HTTP_OK);
     220             :     }
     221             :   }
     222             : }
     223             : 
     224             : 
     225             : MHD_RESULT
     226           0 : TEH_handler_csr_withdraw (struct TEH_RequestContext *rc,
     227             :                           const json_t *root,
     228             :                           const char *const args[])
     229             : {
     230             :   struct TALER_CsNonce nonce;
     231             :   struct TALER_DenominationHashP denom_pub_hash;
     232           0 :   struct TALER_ExchangeWithdrawValues ewv = {
     233             :     .cipher = TALER_DENOMINATION_CS
     234             :   };
     235             :   struct GNUNET_JSON_Specification spec[] = {
     236           0 :     GNUNET_JSON_spec_fixed ("nonce",
     237             :                             &nonce,
     238             :                             sizeof (struct TALER_CsNonce)),
     239           0 :     GNUNET_JSON_spec_fixed ("denom_pub_hash",
     240             :                             &denom_pub_hash,
     241             :                             sizeof (struct TALER_DenominationHashP)),
     242           0 :     GNUNET_JSON_spec_end ()
     243             :   };
     244             :   struct TEH_DenominationKey *dk;
     245             : 
     246             :   (void) args;
     247             :   {
     248             :     enum GNUNET_GenericReturnValue res;
     249             : 
     250           0 :     res = TALER_MHD_parse_json_data (rc->connection,
     251             :                                      root,
     252             :                                      spec);
     253           0 :     if (GNUNET_OK != res)
     254           0 :       return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
     255             :   }
     256             : 
     257             :   {
     258             :     struct TEH_KeyStateHandle *ksh;
     259             : 
     260           0 :     ksh = TEH_keys_get_state ();
     261           0 :     if (NULL == ksh)
     262             :     {
     263           0 :       return TALER_MHD_reply_with_error (rc->connection,
     264             :                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
     265             :                                          TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
     266             :                                          NULL);
     267             :     }
     268           0 :     dk = TEH_keys_denomination_by_hash2 (ksh,
     269             :                                          &denom_pub_hash,
     270             :                                          NULL,
     271             :                                          NULL);
     272           0 :     if (NULL == dk)
     273             :     {
     274           0 :       return TEH_RESPONSE_reply_unknown_denom_pub_hash (
     275             :         rc->connection,
     276             :         &denom_pub_hash);
     277             :     }
     278           0 :     if (GNUNET_TIME_absolute_is_past (dk->meta.expire_withdraw.abs_time))
     279             :     {
     280             :       /* This denomination is past the expiration time for withdraws/refreshes*/
     281           0 :       return TEH_RESPONSE_reply_expired_denom_pub_hash (
     282             :         rc->connection,
     283             :         &denom_pub_hash,
     284             :         TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED,
     285             :         "csr-withdraw");
     286             :     }
     287           0 :     if (GNUNET_TIME_absolute_is_future (dk->meta.start.abs_time))
     288             :     {
     289             :       /* This denomination is not yet valid, no need to check
     290             :          for idempotency! */
     291           0 :       return TEH_RESPONSE_reply_expired_denom_pub_hash (
     292             :         rc->connection,
     293             :         &denom_pub_hash,
     294             :         TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE,
     295             :         "csr-withdraw");
     296             :     }
     297           0 :     if (dk->recoup_possible)
     298             :     {
     299             :       /* This denomination has been revoked */
     300           0 :       return TEH_RESPONSE_reply_expired_denom_pub_hash (
     301             :         rc->connection,
     302             :         &denom_pub_hash,
     303             :         TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED,
     304             :         "csr-withdraw");
     305             :     }
     306           0 :     if (TALER_DENOMINATION_CS != dk->denom_pub.cipher)
     307             :     {
     308             :       /* denomination is valid but not for CS */
     309           0 :       return TEH_RESPONSE_reply_invalid_denom_cipher_for_operation (
     310             :         rc->connection,
     311             :         &denom_pub_hash);
     312             :     }
     313             :   }
     314             : 
     315             :   /* derive r_pub */
     316             :   {
     317             :     enum TALER_ErrorCode ec;
     318             : 
     319           0 :     ec = TEH_keys_denomination_cs_r_pub_withdraw (&denom_pub_hash,
     320             :                                                   &nonce,
     321             :                                                   &ewv.details.cs_values);
     322           0 :     if (TALER_EC_NONE != ec)
     323             :     {
     324           0 :       GNUNET_break (0);
     325           0 :       return TALER_MHD_reply_with_ec (rc->connection,
     326             :                                       ec,
     327             :                                       NULL);
     328             :     }
     329             :   }
     330             : 
     331             :   {
     332             :     json_t *csr_obj;
     333             : 
     334           0 :     csr_obj = GNUNET_JSON_PACK (
     335             :       TALER_JSON_pack_exchange_withdraw_values ("ewv",
     336             :                                                 &ewv));
     337           0 :     GNUNET_assert (NULL != csr_obj);
     338           0 :     return TALER_MHD_reply_json_steal (rc->connection,
     339             :                                        csr_obj,
     340             :                                        MHD_HTTP_OK);
     341             :   }
     342             : }
     343             : 
     344             : 
     345             : /* end of taler-exchange-httpd_csr.c */

Generated by: LCOV version 1.14