Line data Source code
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 0 : TALER_MERCHANT_MFA_co_to_string (
54 : enum TALER_MERCHANT_MFA_CriticalOperation co)
55 : {
56 0 : if ( (co < 0) ||
57 : (co >= sizeof (co_strings) / sizeof (co_strings[0])) )
58 : {
59 0 : GNUNET_break (0);
60 0 : return NULL;
61 : }
62 0 : return co_strings[co];
63 : }
64 :
65 :
66 : enum TALER_MERCHANT_MFA_CriticalOperation
67 0 : TALER_MERCHANT_MFA_co_from_string (const char *str)
68 : {
69 0 : if (NULL == str)
70 0 : return TALER_MERCHANT_MFA_CO_NONE;
71 0 : for (unsigned int i = 1;
72 0 : i < sizeof (co_strings) / sizeof (co_strings[0]);
73 0 : i++)
74 : {
75 0 : if (0 == strcmp (str,
76 : co_strings[i]))
77 0 : return (enum TALER_MERCHANT_MFA_CriticalOperation) i;
78 : }
79 0 : GNUNET_break (0);
80 0 : return TALER_MERCHANT_MFA_CO_NONE;
81 : }
82 :
83 :
84 : const char *
85 0 : 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 0 : if ( (co < 0) ||
99 : (co >= sizeof (co_s) / sizeof (co_s[0])) )
100 : {
101 0 : GNUNET_break (0);
102 0 : return NULL;
103 : }
104 0 : return co_s[co];
105 : }
106 :
107 :
108 : const char *
109 0 : TALER_MERCHANT_MFA_channel_to_string (
110 : enum TALER_MERCHANT_MFA_Channel ch)
111 : {
112 0 : if ( (ch < 0) ||
113 : (ch >= sizeof (channel_strings) / sizeof (channel_strings[0])) )
114 : {
115 0 : GNUNET_break (0);
116 0 : return NULL;
117 : }
118 0 : return channel_strings[ch];
119 : }
120 :
121 :
122 : enum TALER_MERCHANT_MFA_Channel
123 0 : TALER_MERCHANT_MFA_channel_from_string (const char *str)
124 : {
125 0 : if (NULL == str)
126 0 : return TALER_MERCHANT_MFA_CHANNEL_NONE;
127 0 : for (unsigned int i = 1;
128 0 : i < sizeof (channel_strings) / sizeof (channel_strings[0]);
129 0 : i++)
130 : {
131 0 : if (0 == strcmp (str,
132 : channel_strings[i]))
133 0 : return (enum TALER_MERCHANT_MFA_Channel) i;
134 : }
135 0 : GNUNET_break (0);
136 0 : return TALER_MERCHANT_MFA_CHANNEL_NONE;
137 : }
138 :
139 :
140 : void
141 0 : 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 0 : if (NULL == body)
151 : {
152 0 : json_str = NULL;
153 : }
154 : else
155 : {
156 0 : json_str = json_dumps (body,
157 : JSON_COMPACT | JSON_SORT_KEYS);
158 0 : GNUNET_assert (NULL != json_str);
159 : }
160 0 : hc = GNUNET_CRYPTO_hash_context_start ();
161 0 : GNUNET_CRYPTO_hash_context_read (hc,
162 : salt,
163 : sizeof (*salt));
164 0 : if (NULL != json_str)
165 : {
166 0 : GNUNET_CRYPTO_hash_context_read (hc,
167 : json_str,
168 : strlen (json_str));
169 0 : free (json_str);
170 : }
171 0 : GNUNET_CRYPTO_hash_context_finish (hc,
172 : &hash);
173 :
174 : GNUNET_static_assert (sizeof (*h_body) <= sizeof (hash));
175 : /* Truncate to short hash */
176 0 : memcpy (&h_body->hash,
177 : &hash,
178 : sizeof (*h_body));
179 0 : }
|