testing_api_cmd_reserve_attest.c (7089B)
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 "taler/platform.h" 25 #include "taler/taler_json_lib.h" 26 #include <gnunet/gnunet_curl_lib.h> 27 #include "taler/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_PostReservesAttestHandle *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 reserve_attest_cb ( 108 void *cls, 109 const struct TALER_EXCHANGE_PostReservesAttestResponse *rs) 110 { 111 struct AttestState *ss = cls; 112 struct TALER_TESTING_Interpreter *is = ss->is; 113 114 ss->rsh = NULL; 115 if (ss->expected_response_code != rs->hr.http_status) 116 { 117 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 json_dumpf (rs->hr.reply, 123 stderr, 124 JSON_INDENT (2)); 125 TALER_TESTING_interpreter_fail (ss->is); 126 return; 127 } 128 if (MHD_HTTP_OK != rs->hr.http_status) 129 { 130 TALER_TESTING_interpreter_next (is); 131 return; 132 } 133 ss->attributes = json_incref ((json_t*) rs->details.ok.attributes); 134 ss->expiration_time = rs->details.ok.expiration_time; 135 ss->exchange_pub = rs->details.ok.exchange_pub; 136 ss->exchange_sig = rs->details.ok.exchange_sig; 137 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 attest_run (void *cls, 150 const struct TALER_TESTING_Command *cmd, 151 struct TALER_TESTING_Interpreter *is) 152 { 153 struct AttestState *ss = cls; 154 const struct TALER_TESTING_Command *create_reserve; 155 const char *exchange_url; 156 157 ss->is = is; 158 exchange_url = TALER_TESTING_get_exchange_url (is); 159 if (NULL == exchange_url) 160 { 161 GNUNET_break (0); 162 return; 163 } 164 create_reserve 165 = TALER_TESTING_interpreter_lookup_command (is, 166 ss->reserve_reference); 167 168 if (NULL == create_reserve) 169 { 170 GNUNET_break (0); 171 TALER_TESTING_interpreter_fail (is); 172 return; 173 } 174 if (GNUNET_OK != 175 TALER_TESTING_get_trait_reserve_priv (create_reserve, 176 &ss->reserve_priv)) 177 { 178 GNUNET_break (0); 179 TALER_LOG_ERROR ("Failed to find reserve_priv for attest query\n"); 180 TALER_TESTING_interpreter_fail (is); 181 return; 182 } 183 GNUNET_CRYPTO_eddsa_key_get_public (&ss->reserve_priv->eddsa_priv, 184 &ss->reserve_pub.eddsa_pub); 185 ss->rsh = TALER_EXCHANGE_post_reserves_attest_create ( 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 if (NULL == ss->rsh) 193 { 194 GNUNET_break (0); 195 TALER_TESTING_interpreter_fail (is); 196 return; 197 } 198 { 199 enum TALER_ErrorCode ec; 200 201 ec = TALER_EXCHANGE_post_reserves_attest_start (ss->rsh, 202 &reserve_attest_cb, 203 ss); 204 if (TALER_EC_NONE != ec) 205 { 206 GNUNET_break (0); 207 ss->rsh = NULL; 208 TALER_TESTING_interpreter_fail (is); 209 return; 210 } 211 } 212 } 213 214 215 /** 216 * Cleanup the state from a "reserve attest" CMD, and possibly 217 * cancel a pending operation thereof. 218 * 219 * @param cls closure. 220 * @param cmd the command which is being cleaned up. 221 */ 222 static void 223 attest_cleanup (void *cls, 224 const struct TALER_TESTING_Command *cmd) 225 { 226 struct AttestState *ss = cls; 227 228 if (NULL != ss->rsh) 229 { 230 TALER_TESTING_command_incomplete (ss->is, 231 cmd->label); 232 TALER_EXCHANGE_post_reserves_attest_cancel (ss->rsh); 233 ss->rsh = NULL; 234 } 235 json_decref (ss->attributes); 236 GNUNET_free (ss->attrs); 237 GNUNET_free (ss); 238 } 239 240 241 struct TALER_TESTING_Command 242 TALER_TESTING_cmd_reserve_attest (const char *label, 243 const char *reserve_reference, 244 unsigned int expected_response_code, 245 ...) 246 { 247 struct AttestState *ss; 248 unsigned int num_args; 249 const char *ea; 250 va_list ap; 251 252 num_args = 0; 253 va_start (ap, expected_response_code); 254 while (NULL != va_arg (ap, const char *)) 255 num_args++; 256 va_end (ap); 257 258 GNUNET_assert (NULL != reserve_reference); 259 ss = GNUNET_new (struct AttestState); 260 ss->reserve_reference = reserve_reference; 261 ss->expected_response_code = expected_response_code; 262 ss->attrs_len = num_args; 263 ss->attrs = GNUNET_new_array (num_args, 264 const char *); 265 num_args = 0; 266 va_start (ap, expected_response_code); 267 while (NULL != (ea = va_arg (ap, const char *))) 268 ss->attrs[num_args++] = ea; 269 va_end (ap); 270 271 { 272 struct TALER_TESTING_Command cmd = { 273 .cls = ss, 274 .label = label, 275 .run = &attest_run, 276 .cleanup = &attest_cleanup 277 }; 278 279 return cmd; 280 } 281 }