Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2014-2022 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify
6 : it under the terms of the GNU General Public License as
7 : published by the Free Software Foundation; either version 3, or
8 : (at your option) any later version.
9 :
10 : TALER is distributed in the hope that it will be useful, but
11 : WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : GNU General Public License for more details.
14 :
15 : You should have received a copy of the GNU General Public
16 : License along with TALER; see the file COPYING. If not, see
17 : <http://www.gnu.org/licenses/>
18 : */
19 : /**
20 : * @file testing/testing_api_cmd_reserve_attest.c
21 : * @brief Implement the /reserve/$RID/attest test command.
22 : * @author Christian Grothoff
23 : */
24 : #include "platform.h"
25 : #include "taler_json_lib.h"
26 : #include <gnunet/gnunet_curl_lib.h>
27 : #include "taler_testing_lib.h"
28 :
29 : /**
30 : * State for a "attest" CMD.
31 : */
32 : struct AttestState
33 : {
34 : /**
35 : * Label to the command which created the reserve to check,
36 : * needed to resort the reserve key.
37 : */
38 : const char *reserve_reference;
39 :
40 : /**
41 : * Handle to the "reserve attest" operation.
42 : */
43 : struct TALER_EXCHANGE_ReservesAttestHandle *rsh;
44 :
45 : /**
46 : * Private key of the reserve being analyzed.
47 : */
48 : const struct TALER_ReservePrivateKeyP *reserve_priv;
49 :
50 : /**
51 : * Public key of the reserve being analyzed.
52 : */
53 : struct TALER_ReservePublicKeyP reserve_pub;
54 :
55 : /**
56 : * Array of attributes to request, of length @e attrs_len.
57 : */
58 : const char **attrs;
59 :
60 : /**
61 : * Length of the @e attrs array.
62 : */
63 : unsigned int attrs_len;
64 :
65 : /**
66 : * Expected HTTP response code.
67 : */
68 : unsigned int expected_response_code;
69 :
70 : /**
71 : * Interpreter state.
72 : */
73 : struct TALER_TESTING_Interpreter *is;
74 :
75 : /* FIXME: expose fields below as traits... */
76 :
77 : /**
78 : * Attested attributes returned by the exchange.
79 : */
80 : json_t *attributes;
81 :
82 : /**
83 : * Expiration time of the attested attributes.
84 : */
85 : struct GNUNET_TIME_Timestamp expiration_time;
86 :
87 : /**
88 : * Signature by the exchange affirming the attributes.
89 : */
90 : struct TALER_ExchangeSignatureP exchange_sig;
91 :
92 : /**
93 : * Online signing key used by the exchange.
94 : */
95 : struct TALER_ExchangePublicKeyP exchange_pub;
96 : };
97 :
98 :
99 : /**
100 : * Check that the reserve balance and HTTP response code are
101 : * both acceptable.
102 : *
103 : * @param cls closure.
104 : * @param rs HTTP response details
105 : */
106 : static void
107 1 : reserve_attest_cb (
108 : void *cls,
109 : const struct TALER_EXCHANGE_ReservePostAttestResult *rs)
110 : {
111 1 : struct AttestState *ss = cls;
112 1 : struct TALER_TESTING_Interpreter *is = ss->is;
113 :
114 1 : ss->rsh = NULL;
115 1 : if (ss->expected_response_code != rs->hr.http_status)
116 : {
117 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
118 : "Unexpected HTTP response code: %d in %s:%u\n",
119 : rs->hr.http_status,
120 : __FILE__,
121 : __LINE__);
122 0 : json_dumpf (rs->hr.reply,
123 : stderr,
124 : JSON_INDENT (2));
125 0 : TALER_TESTING_interpreter_fail (ss->is);
126 0 : return;
127 : }
128 1 : if (MHD_HTTP_OK != rs->hr.http_status)
129 : {
130 0 : TALER_TESTING_interpreter_next (is);
131 0 : return;
132 : }
133 1 : ss->attributes = json_incref ((json_t*) rs->details.ok.attributes);
134 1 : ss->expiration_time = rs->details.ok.expiration_time;
135 1 : ss->exchange_pub = rs->details.ok.exchange_pub;
136 1 : ss->exchange_sig = rs->details.ok.exchange_sig;
137 1 : TALER_TESTING_interpreter_next (is);
138 : }
139 :
140 :
141 : /**
142 : * Run the command.
143 : *
144 : * @param cls closure.
145 : * @param cmd the command being executed.
146 : * @param is the interpreter state.
147 : */
148 : static void
149 1 : attest_run (void *cls,
150 : const struct TALER_TESTING_Command *cmd,
151 : struct TALER_TESTING_Interpreter *is)
152 : {
153 1 : struct AttestState *ss = cls;
154 : const struct TALER_TESTING_Command *create_reserve;
155 : const char *exchange_url;
156 :
157 1 : ss->is = is;
158 1 : exchange_url = TALER_TESTING_get_exchange_url (is);
159 1 : if (NULL == exchange_url)
160 : {
161 0 : GNUNET_break (0);
162 0 : return;
163 : }
164 : create_reserve
165 1 : = TALER_TESTING_interpreter_lookup_command (is,
166 : ss->reserve_reference);
167 :
168 1 : if (NULL == create_reserve)
169 : {
170 0 : GNUNET_break (0);
171 0 : TALER_TESTING_interpreter_fail (is);
172 0 : return;
173 : }
174 1 : if (GNUNET_OK !=
175 1 : TALER_TESTING_get_trait_reserve_priv (create_reserve,
176 : &ss->reserve_priv))
177 : {
178 0 : GNUNET_break (0);
179 0 : TALER_LOG_ERROR ("Failed to find reserve_priv for attest query\n");
180 0 : TALER_TESTING_interpreter_fail (is);
181 0 : return;
182 : }
183 1 : GNUNET_CRYPTO_eddsa_key_get_public (&ss->reserve_priv->eddsa_priv,
184 : &ss->reserve_pub.eddsa_pub);
185 1 : ss->rsh = TALER_EXCHANGE_reserves_attest (
186 : TALER_TESTING_interpreter_get_context (is),
187 : exchange_url,
188 : TALER_TESTING_get_keys (is),
189 : ss->reserve_priv,
190 : ss->attrs_len,
191 : ss->attrs,
192 : &reserve_attest_cb,
193 : ss);
194 : }
195 :
196 :
197 : /**
198 : * Cleanup the state from a "reserve attest" CMD, and possibly
199 : * cancel a pending operation thereof.
200 : *
201 : * @param cls closure.
202 : * @param cmd the command which is being cleaned up.
203 : */
204 : static void
205 1 : attest_cleanup (void *cls,
206 : const struct TALER_TESTING_Command *cmd)
207 : {
208 1 : struct AttestState *ss = cls;
209 :
210 1 : if (NULL != ss->rsh)
211 : {
212 0 : TALER_TESTING_command_incomplete (ss->is,
213 : cmd->label);
214 0 : TALER_EXCHANGE_reserves_attest_cancel (ss->rsh);
215 0 : ss->rsh = NULL;
216 : }
217 1 : json_decref (ss->attributes);
218 1 : GNUNET_free (ss->attrs);
219 1 : GNUNET_free (ss);
220 1 : }
221 :
222 :
223 : struct TALER_TESTING_Command
224 1 : TALER_TESTING_cmd_reserve_attest (const char *label,
225 : const char *reserve_reference,
226 : unsigned int expected_response_code,
227 : ...)
228 : {
229 : struct AttestState *ss;
230 : unsigned int num_args;
231 : const char *ea;
232 : va_list ap;
233 :
234 1 : num_args = 0;
235 1 : va_start (ap, expected_response_code);
236 2 : while (NULL != va_arg (ap, const char *))
237 1 : num_args++;
238 1 : va_end (ap);
239 :
240 1 : GNUNET_assert (NULL != reserve_reference);
241 1 : ss = GNUNET_new (struct AttestState);
242 1 : ss->reserve_reference = reserve_reference;
243 1 : ss->expected_response_code = expected_response_code;
244 1 : ss->attrs_len = num_args;
245 1 : ss->attrs = GNUNET_new_array (num_args,
246 : const char *);
247 1 : num_args = 0;
248 1 : va_start (ap, expected_response_code);
249 2 : while (NULL != (ea = va_arg (ap, const char *)))
250 1 : ss->attrs[num_args++] = ea;
251 1 : va_end (ap);
252 :
253 : {
254 1 : struct TALER_TESTING_Command cmd = {
255 : .cls = ss,
256 : .label = label,
257 : .run = &attest_run,
258 : .cleanup = &attest_cleanup
259 : };
260 :
261 1 : return cmd;
262 : }
263 : }
|