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 }