merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

mfa.c (4926B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2025 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 util/mfa.c
     18  * @brief helper functions for MFA processing
     19  * @author Christian Grothoff
     20  */
     21 #include "platform.h"
     22 #include <gnunet/gnunet_util_lib.h>
     23 #include <gnunet/gnunet_json_lib.h>
     24 #include <taler/taler_util.h>
     25 #include <taler/taler_json_lib.h>
     26 #include <taler_merchant_util.h>
     27 #include <jansson.h>
     28 
     29 /**
     30  * Mapping from critical operation enum to string.
     31  */
     32 static const char *co_strings[] = {
     33   [TALER_MERCHANT_MFA_CO_NONE] = NULL,
     34   [TALER_MERCHANT_MFA_CO_INSTANCE_PROVISION] = "instance_provision",
     35   [TALER_MERCHANT_MFA_CO_ACCOUNT_CONFIGURATION] = "account_config",
     36   [TALER_MERCHANT_MFA_CO_AUTH_CONFIGURATION] = "auth_config",
     37   [TALER_MERCHANT_MFA_CO_INSTANCE_DELETION] = "instance_deletion",
     38   [TALER_MERCHANT_MFA_CO_AUTH_TOKEN_CREATION] = "auth_token_creation"
     39 };
     40 
     41 /**
     42  * Mapping from MFA channel enum to string.
     43  */
     44 static const char *channel_strings[] = {
     45   [TALER_MERCHANT_MFA_CHANNEL_NONE] = NULL,
     46   [TALER_MERCHANT_MFA_CHANNEL_SMS] = "sms",
     47   [TALER_MERCHANT_MFA_CHANNEL_EMAIL] = "email",
     48   [TALER_MERCHANT_MFA_CHANNEL_TOTP] = "totp"
     49 };
     50 
     51 
     52 const char *
     53 TALER_MERCHANT_MFA_co_to_string (
     54   enum TALER_MERCHANT_MFA_CriticalOperation co)
     55 {
     56   if ( (co < 0) ||
     57        (co >= sizeof (co_strings) / sizeof (co_strings[0])) )
     58   {
     59     GNUNET_break (0);
     60     return NULL;
     61   }
     62   return co_strings[co];
     63 }
     64 
     65 
     66 enum TALER_MERCHANT_MFA_CriticalOperation
     67 TALER_MERCHANT_MFA_co_from_string (const char *str)
     68 {
     69   if (NULL == str)
     70     return TALER_MERCHANT_MFA_CO_NONE;
     71   for (unsigned int i = 1;
     72        i < sizeof (co_strings) / sizeof (co_strings[0]);
     73        i++)
     74   {
     75     if (0 == strcmp (str,
     76                      co_strings[i]))
     77       return (enum TALER_MERCHANT_MFA_CriticalOperation) i;
     78   }
     79   GNUNET_break (0);
     80   return TALER_MERCHANT_MFA_CO_NONE;
     81 }
     82 
     83 
     84 const char *
     85 TALER_MERCHANT_MFA_co2s (
     86   enum TALER_MERCHANT_MFA_CriticalOperation co)
     87 {
     88   static const char *co_s[] = {
     89     [TALER_MERCHANT_MFA_CO_NONE] = NULL,
     90     [TALER_MERCHANT_MFA_CO_INSTANCE_PROVISION] = "create new instance",
     91     [TALER_MERCHANT_MFA_CO_ACCOUNT_CONFIGURATION] = "configure bank accounts",
     92     [TALER_MERCHANT_MFA_CO_AUTH_CONFIGURATION] =
     93       "change authentication configuration",
     94     [TALER_MERCHANT_MFA_CO_INSTANCE_DELETION] = "delete instance",
     95     [TALER_MERCHANT_MFA_CO_AUTH_TOKEN_CREATION] = "create authentication token"
     96   };
     97 
     98   if ( (co < 0) ||
     99        (co >= sizeof (co_s) / sizeof (co_s[0])) )
    100   {
    101     GNUNET_break (0);
    102     return NULL;
    103   }
    104   return co_s[co];
    105 }
    106 
    107 
    108 const char *
    109 TALER_MERCHANT_MFA_channel_to_string (
    110   enum TALER_MERCHANT_MFA_Channel ch)
    111 {
    112   if ( (ch < 0) ||
    113        (ch >= sizeof (channel_strings) / sizeof (channel_strings[0])) )
    114   {
    115     GNUNET_break (0);
    116     return NULL;
    117   }
    118   return channel_strings[ch];
    119 }
    120 
    121 
    122 enum TALER_MERCHANT_MFA_Channel
    123 TALER_MERCHANT_MFA_channel_from_string (const char *str)
    124 {
    125   if (NULL == str)
    126     return TALER_MERCHANT_MFA_CHANNEL_NONE;
    127   for (unsigned int i = 1;
    128        i < sizeof (channel_strings) / sizeof (channel_strings[0]);
    129        i++)
    130   {
    131     if (0 == strcmp (str,
    132                      channel_strings[i]))
    133       return (enum TALER_MERCHANT_MFA_Channel) i;
    134   }
    135   GNUNET_break (0);
    136   return TALER_MERCHANT_MFA_CHANNEL_NONE;
    137 }
    138 
    139 
    140 void
    141 TALER_MERCHANT_mfa_body_hash (
    142   const json_t *body,
    143   const struct TALER_MERCHANT_MFA_BodySalt *salt,
    144   struct TALER_MERCHANT_MFA_BodyHash *h_body)
    145 {
    146   char *json_str;
    147   struct GNUNET_HashCode hash;
    148   struct GNUNET_HashContext *hc;
    149 
    150   if (NULL == body)
    151   {
    152     json_str = NULL;
    153   }
    154   else
    155   {
    156     json_str = json_dumps (body,
    157                            JSON_COMPACT | JSON_SORT_KEYS);
    158     GNUNET_assert (NULL != json_str);
    159   }
    160   hc = GNUNET_CRYPTO_hash_context_start ();
    161   GNUNET_CRYPTO_hash_context_read (hc,
    162                                    salt,
    163                                    sizeof (*salt));
    164   if (NULL != json_str)
    165   {
    166     GNUNET_CRYPTO_hash_context_read (hc,
    167                                      json_str,
    168                                      strlen (json_str));
    169     free (json_str);
    170   }
    171   GNUNET_CRYPTO_hash_context_finish (hc,
    172                                      &hash);
    173 
    174   GNUNET_static_assert (sizeof (*h_body) <= sizeof (hash));
    175   /* Truncate to short hash */
    176   memcpy (&h_body->hash,
    177           &hash,
    178           sizeof (*h_body));
    179 }