testing_api_cmd_reserve_attest.c (7061B)
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/taler_json_lib.h" 25 #include <gnunet/gnunet_curl_lib.h> 26 #include "taler/taler_testing_lib.h" 27 28 /** 29 * State for a "attest" CMD. 30 */ 31 struct AttestState 32 { 33 /** 34 * Label to the command which created the reserve to check, 35 * needed to resort the reserve key. 36 */ 37 const char *reserve_reference; 38 39 /** 40 * Handle to the "reserve attest" operation. 41 */ 42 struct TALER_EXCHANGE_PostReservesAttestHandle *rsh; 43 44 /** 45 * Private key of the reserve being analyzed. 46 */ 47 const struct TALER_ReservePrivateKeyP *reserve_priv; 48 49 /** 50 * Public key of the reserve being analyzed. 51 */ 52 struct TALER_ReservePublicKeyP reserve_pub; 53 54 /** 55 * Array of attributes to request, of length @e attrs_len. 56 */ 57 const char **attrs; 58 59 /** 60 * Length of the @e attrs array. 61 */ 62 unsigned int attrs_len; 63 64 /** 65 * Expected HTTP response code. 66 */ 67 unsigned int expected_response_code; 68 69 /** 70 * Interpreter state. 71 */ 72 struct TALER_TESTING_Interpreter *is; 73 74 /* FIXME: expose fields below as traits... */ 75 76 /** 77 * Attested attributes returned by the exchange. 78 */ 79 json_t *attributes; 80 81 /** 82 * Expiration time of the attested attributes. 83 */ 84 struct GNUNET_TIME_Timestamp expiration_time; 85 86 /** 87 * Signature by the exchange affirming the attributes. 88 */ 89 struct TALER_ExchangeSignatureP exchange_sig; 90 91 /** 92 * Online signing key used by the exchange. 93 */ 94 struct TALER_ExchangePublicKeyP exchange_pub; 95 }; 96 97 98 /** 99 * Check that the reserve balance and HTTP response code are 100 * both acceptable. 101 * 102 * @param cls closure. 103 * @param rs HTTP response details 104 */ 105 static void 106 reserve_attest_cb ( 107 void *cls, 108 const struct TALER_EXCHANGE_PostReservesAttestResponse *rs) 109 { 110 struct AttestState *ss = cls; 111 struct TALER_TESTING_Interpreter *is = ss->is; 112 113 ss->rsh = NULL; 114 if (ss->expected_response_code != rs->hr.http_status) 115 { 116 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 117 "Unexpected HTTP response code: %d in %s:%u\n", 118 rs->hr.http_status, 119 __FILE__, 120 __LINE__); 121 json_dumpf (rs->hr.reply, 122 stderr, 123 JSON_INDENT (2)); 124 TALER_TESTING_interpreter_fail (ss->is); 125 return; 126 } 127 if (MHD_HTTP_OK != rs->hr.http_status) 128 { 129 TALER_TESTING_interpreter_next (is); 130 return; 131 } 132 ss->attributes = json_incref ((json_t*) rs->details.ok.attributes); 133 ss->expiration_time = rs->details.ok.expiration_time; 134 ss->exchange_pub = rs->details.ok.exchange_pub; 135 ss->exchange_sig = rs->details.ok.exchange_sig; 136 TALER_TESTING_interpreter_next (is); 137 } 138 139 140 /** 141 * Run the command. 142 * 143 * @param cls closure. 144 * @param cmd the command being executed. 145 * @param is the interpreter state. 146 */ 147 static void 148 attest_run (void *cls, 149 const struct TALER_TESTING_Command *cmd, 150 struct TALER_TESTING_Interpreter *is) 151 { 152 struct AttestState *ss = cls; 153 const struct TALER_TESTING_Command *create_reserve; 154 const char *exchange_url; 155 156 ss->is = is; 157 exchange_url = TALER_TESTING_get_exchange_url (is); 158 if (NULL == exchange_url) 159 { 160 GNUNET_break (0); 161 return; 162 } 163 create_reserve 164 = TALER_TESTING_interpreter_lookup_command (is, 165 ss->reserve_reference); 166 167 if (NULL == create_reserve) 168 { 169 GNUNET_break (0); 170 TALER_TESTING_interpreter_fail (is); 171 return; 172 } 173 if (GNUNET_OK != 174 TALER_TESTING_get_trait_reserve_priv (create_reserve, 175 &ss->reserve_priv)) 176 { 177 GNUNET_break (0); 178 TALER_LOG_ERROR ("Failed to find reserve_priv for attest query\n"); 179 TALER_TESTING_interpreter_fail (is); 180 return; 181 } 182 GNUNET_CRYPTO_eddsa_key_get_public (&ss->reserve_priv->eddsa_priv, 183 &ss->reserve_pub.eddsa_pub); 184 ss->rsh = TALER_EXCHANGE_post_reserves_attest_create ( 185 TALER_TESTING_interpreter_get_context (is), 186 exchange_url, 187 TALER_TESTING_get_keys (is), 188 ss->reserve_priv, 189 ss->attrs_len, 190 ss->attrs); 191 if (NULL == ss->rsh) 192 { 193 GNUNET_break (0); 194 TALER_TESTING_interpreter_fail (is); 195 return; 196 } 197 { 198 enum TALER_ErrorCode ec; 199 200 ec = TALER_EXCHANGE_post_reserves_attest_start (ss->rsh, 201 &reserve_attest_cb, 202 ss); 203 if (TALER_EC_NONE != ec) 204 { 205 GNUNET_break (0); 206 ss->rsh = NULL; 207 TALER_TESTING_interpreter_fail (is); 208 return; 209 } 210 } 211 } 212 213 214 /** 215 * Cleanup the state from a "reserve attest" CMD, and possibly 216 * cancel a pending operation thereof. 217 * 218 * @param cls closure. 219 * @param cmd the command which is being cleaned up. 220 */ 221 static void 222 attest_cleanup (void *cls, 223 const struct TALER_TESTING_Command *cmd) 224 { 225 struct AttestState *ss = cls; 226 227 if (NULL != ss->rsh) 228 { 229 TALER_TESTING_command_incomplete (ss->is, 230 cmd->label); 231 TALER_EXCHANGE_post_reserves_attest_cancel (ss->rsh); 232 ss->rsh = NULL; 233 } 234 json_decref (ss->attributes); 235 GNUNET_free (ss->attrs); 236 GNUNET_free (ss); 237 } 238 239 240 struct TALER_TESTING_Command 241 TALER_TESTING_cmd_reserve_attest (const char *label, 242 const char *reserve_reference, 243 unsigned int expected_response_code, 244 ...) 245 { 246 struct AttestState *ss; 247 unsigned int num_args; 248 const char *ea; 249 va_list ap; 250 251 num_args = 0; 252 va_start (ap, expected_response_code); 253 while (NULL != va_arg (ap, const char *)) 254 num_args++; 255 va_end (ap); 256 257 GNUNET_assert (NULL != reserve_reference); 258 ss = GNUNET_new (struct AttestState); 259 ss->reserve_reference = reserve_reference; 260 ss->expected_response_code = expected_response_code; 261 ss->attrs_len = num_args; 262 ss->attrs = GNUNET_new_array (num_args, 263 const char *); 264 num_args = 0; 265 va_start (ap, expected_response_code); 266 while (NULL != (ea = va_arg (ap, const char *))) 267 ss->attrs[num_args++] = ea; 268 va_end (ap); 269 270 { 271 struct TALER_TESTING_Command cmd = { 272 .cls = ss, 273 .label = label, 274 .run = &attest_run, 275 .cleanup = &attest_cleanup 276 }; 277 278 return cmd; 279 } 280 }