merchant

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

mfa.c (4938B)


      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 "taler/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/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] =
     91       "account creation",
     92     [TALER_MERCHANT_MFA_CO_ACCOUNT_CONFIGURATION] =
     93       "account configuration",
     94     [TALER_MERCHANT_MFA_CO_AUTH_CONFIGURATION] =
     95       "authentication change",
     96     [TALER_MERCHANT_MFA_CO_INSTANCE_DELETION] =
     97       "account deletion",
     98     [TALER_MERCHANT_MFA_CO_AUTH_TOKEN_CREATION] =
     99       "access token creation"
    100   };
    101 
    102   if ( (co < 0) ||
    103        (co >= sizeof (co_s) / sizeof (co_s[0])) )
    104   {
    105     GNUNET_break (0);
    106     return NULL;
    107   }
    108   return co_s[co];
    109 }
    110 
    111 
    112 const char *
    113 TALER_MERCHANT_MFA_channel_to_string (
    114   enum TALER_MERCHANT_MFA_Channel ch)
    115 {
    116   if ( (ch < 0) ||
    117        (ch >= sizeof (channel_strings) / sizeof (channel_strings[0])) )
    118   {
    119     GNUNET_break (0);
    120     return NULL;
    121   }
    122   return channel_strings[ch];
    123 }
    124 
    125 
    126 enum TALER_MERCHANT_MFA_Channel
    127 TALER_MERCHANT_MFA_channel_from_string (const char *str)
    128 {
    129   if (NULL == str)
    130     return TALER_MERCHANT_MFA_CHANNEL_NONE;
    131   for (unsigned int i = 1;
    132        i < sizeof (channel_strings) / sizeof (channel_strings[0]);
    133        i++)
    134   {
    135     if (0 == strcmp (str,
    136                      channel_strings[i]))
    137       return (enum TALER_MERCHANT_MFA_Channel) i;
    138   }
    139   GNUNET_break (0);
    140   return TALER_MERCHANT_MFA_CHANNEL_NONE;
    141 }
    142 
    143 
    144 void
    145 TALER_MERCHANT_mfa_body_hash (
    146   const json_t *body,
    147   const struct TALER_MERCHANT_MFA_BodySalt *salt,
    148   struct TALER_MERCHANT_MFA_BodyHash *h_body)
    149 {
    150   char *json_str;
    151   struct GNUNET_HashCode hash;
    152   struct GNUNET_HashContext *hc;
    153 
    154   if (NULL == body)
    155   {
    156     json_str = NULL;
    157   }
    158   else
    159   {
    160     json_str = json_dumps (body,
    161                            JSON_COMPACT | JSON_SORT_KEYS);
    162     GNUNET_assert (NULL != json_str);
    163   }
    164   hc = GNUNET_CRYPTO_hash_context_start ();
    165   GNUNET_CRYPTO_hash_context_read (hc,
    166                                    salt,
    167                                    sizeof (*salt));
    168   if (NULL != json_str)
    169   {
    170     GNUNET_CRYPTO_hash_context_read (hc,
    171                                      json_str,
    172                                      strlen (json_str));
    173     free (json_str);
    174   }
    175   GNUNET_CRYPTO_hash_context_finish (hc,
    176                                      &hash);
    177 
    178   GNUNET_static_assert (sizeof (*h_body) <= sizeof (hash));
    179   /* Truncate to short hash */
    180   memcpy (&h_body->hash,
    181           &hash,
    182           sizeof (*h_body));
    183 }