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 }