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 "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 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] =
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 0 : if ( (co < 0) ||
103 : (co >= sizeof (co_s) / sizeof (co_s[0])) )
104 : {
105 0 : GNUNET_break (0);
106 0 : return NULL;
107 : }
108 0 : return co_s[co];
109 : }
110 :
111 :
112 : const char *
113 0 : TALER_MERCHANT_MFA_channel_to_string (
114 : enum TALER_MERCHANT_MFA_Channel ch)
115 : {
116 0 : if ( (ch < 0) ||
117 : (ch >= sizeof (channel_strings) / sizeof (channel_strings[0])) )
118 : {
119 0 : GNUNET_break (0);
120 0 : return NULL;
121 : }
122 0 : return channel_strings[ch];
123 : }
124 :
125 :
126 : enum TALER_MERCHANT_MFA_Channel
127 0 : TALER_MERCHANT_MFA_channel_from_string (const char *str)
128 : {
129 0 : if (NULL == str)
130 0 : return TALER_MERCHANT_MFA_CHANNEL_NONE;
131 0 : for (unsigned int i = 1;
132 0 : i < sizeof (channel_strings) / sizeof (channel_strings[0]);
133 0 : i++)
134 : {
135 0 : if (0 == strcmp (str,
136 : channel_strings[i]))
137 0 : return (enum TALER_MERCHANT_MFA_Channel) i;
138 : }
139 0 : GNUNET_break (0);
140 0 : return TALER_MERCHANT_MFA_CHANNEL_NONE;
141 : }
142 :
143 :
144 : void
145 0 : 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 0 : if (NULL == body)
155 : {
156 0 : json_str = NULL;
157 : }
158 : else
159 : {
160 0 : json_str = json_dumps (body,
161 : JSON_COMPACT | JSON_SORT_KEYS);
162 0 : GNUNET_assert (NULL != json_str);
163 : }
164 0 : hc = GNUNET_CRYPTO_hash_context_start ();
165 0 : GNUNET_CRYPTO_hash_context_read (hc,
166 : salt,
167 : sizeof (*salt));
168 0 : if (NULL != json_str)
169 : {
170 0 : GNUNET_CRYPTO_hash_context_read (hc,
171 : json_str,
172 : strlen (json_str));
173 0 : free (json_str);
174 : }
175 0 : GNUNET_CRYPTO_hash_context_finish (hc,
176 : &hash);
177 :
178 : GNUNET_static_assert (sizeof (*h_body) <= sizeof (hash));
179 : /* Truncate to short hash */
180 0 : memcpy (&h_body->hash,
181 : &hash,
182 : sizeof (*h_body));
183 0 : }
|