test_anastasis_db.c (12802B)
1 /* 2 This file is part of Anastasis 3 Copyright (C) 2020, 2021 Anastasis SARL 4 5 Anastasis is free software; you can redistribute it and/or modify it under the 6 terms of the GNU Affero General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 Anastasis 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 Affero General Public License for more details. 12 13 You should have received a copy of the GNU Affero General Public License along with 14 Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file anastasis/test_anastasis_db.c 18 * @brief testcase for anastasis postgres db plugin 19 * @author Marcello Stanisci 20 * @author Christian Grothoff 21 */ 22 #include "platform.h" 23 #include "anastasis_database_lib.h" 24 #include "anastasis_util_lib.h" 25 #include <gnunet/gnunet_signatures.h> 26 27 28 #define FAILIF(cond) \ 29 do { \ 30 if (! (cond)) { break;} \ 31 GNUNET_break (0); \ 32 goto drop; \ 33 } while (0) 34 35 #define RND_BLK(ptr) \ 36 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (* \ 37 ptr)) 38 39 /** 40 * Global return value for the test. Initially -1, set to 0 upon 41 * completion. Other values indicate some kind of error. 42 */ 43 static int result; 44 45 /** 46 * Handle to the plugin we are testing. 47 */ 48 static struct ANASTASIS_DatabasePlugin *plugin; 49 50 51 /** 52 * Main function that will be run by the scheduler. 53 * 54 * @param cls closure with config 55 */ 56 static void 57 run (void *cls) 58 { 59 struct GNUNET_CONFIGURATION_Handle *cfg = cls; 60 struct TALER_Amount amount; 61 struct ANASTASIS_PaymentSecretP paymentSecretP; 62 struct ANASTASIS_CRYPTO_AccountPublicKeyP accountPubP; 63 struct ANASTASIS_AccountSignatureP accountSig; 64 struct ANASTASIS_AccountSignatureP res_account_sig; 65 struct GNUNET_HashCode recoveryDataHash; 66 struct GNUNET_HashCode res_recovery_data_hash; 67 struct GNUNET_HashCode r; 68 struct GNUNET_TIME_Relative rel_time; 69 struct ANASTASIS_CRYPTO_TruthUUIDP truth_uuid; 70 struct ANASTASIS_CRYPTO_EncryptedKeyShareP key_share; 71 unsigned int post_counter; 72 const char *mime_type; 73 const char *method; 74 uint32_t docVersion; 75 uint32_t res_version; 76 size_t recoverydatasize; 77 void *res_recovery_data = NULL; 78 struct ANASTASIS_CRYPTO_EncryptedKeyShareP res_key_share; 79 bool paid; 80 bool valid_counter; 81 uint32_t recversion = 1; 82 unsigned char aes_gcm_tag[16]; 83 const char *recovery_data = "RECOVERY_DATA"; 84 uint64_t challenge_code = 1234; 85 struct GNUNET_HashCode c_hash; 86 struct ANASTASIS_UploadSignaturePS usp = { 87 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST), 88 .purpose.size = htonl (sizeof (usp)) 89 }; 90 91 if (NULL == (plugin = ANASTASIS_DB_plugin_load (cfg, 92 true))) 93 { 94 result = 77; 95 return; 96 } 97 (void) plugin->drop_tables (plugin->cls); 98 if (GNUNET_OK != 99 plugin->create_tables (plugin->cls)) 100 { 101 result = 77; 102 return; 103 } 104 if (GNUNET_OK != 105 plugin->connect (plugin->cls)) 106 { 107 result = 77; 108 return; 109 } 110 111 GNUNET_CRYPTO_hash (recovery_data, 112 strlen (recovery_data), 113 &recoveryDataHash); 114 RND_BLK (&paymentSecretP); 115 RND_BLK (&aes_gcm_tag); 116 post_counter = 2; 117 mime_type = "Picture"; 118 method = "Method"; 119 TALER_string_to_amount ("EUR:30",&amount); 120 121 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, 122 &truth_uuid, 123 sizeof (truth_uuid)); 124 rel_time = GNUNET_TIME_UNIT_MONTHS; 125 126 GNUNET_assert (GNUNET_OK == 127 TALER_string_to_amount ("EUR:1", 128 &amount)); 129 130 memset (&key_share, 1, sizeof (key_share)); 131 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 132 plugin->store_truth (plugin->cls, 133 &truth_uuid, 134 &key_share, 135 mime_type, 136 "encrypted_truth", 137 strlen ("encrypted_truth"), 138 method, 139 rel_time)); 140 141 FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != 142 plugin->check_payment_identifier (plugin->cls, 143 &paymentSecretP, 144 &paid, 145 &valid_counter)); 146 147 memset (&accountPubP, 2, sizeof (accountPubP)); 148 memset (&accountSig, 3, sizeof (accountSig)); 149 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 150 plugin->record_recdoc_payment (plugin->cls, 151 &accountPubP, 152 post_counter, 153 &paymentSecretP, 154 &amount)); 155 { 156 struct GNUNET_TIME_Timestamp res_time; 157 158 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 159 plugin->increment_lifetime (plugin->cls, 160 &accountPubP, 161 &paymentSecretP, 162 rel_time, 163 &res_time)); 164 } 165 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 166 plugin->check_payment_identifier (plugin->cls, 167 &paymentSecretP, 168 &paid, 169 &valid_counter)); 170 FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != 171 plugin->check_challenge_payment (plugin->cls, 172 &paymentSecretP, 173 &truth_uuid, 174 &paid)); 175 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 176 plugin->record_challenge_payment (plugin->cls, 177 &truth_uuid, 178 &paymentSecretP, 179 &amount)); 180 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 181 plugin->update_challenge_payment (plugin->cls, 182 &truth_uuid, 183 &paymentSecretP)); 184 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 185 plugin->check_challenge_payment (plugin->cls, 186 &paymentSecretP, 187 &truth_uuid, 188 &paid)); 189 FAILIF (! paid); 190 FAILIF (ANASTASIS_DB_STORE_STATUS_SUCCESS != 191 plugin->store_recovery_document (plugin->cls, 192 &accountPubP, 193 &accountSig, 194 &recoveryDataHash, 195 recovery_data, 196 strlen (recovery_data), 197 "meta-data", 198 strlen ("meta-data"), 199 &paymentSecretP, 200 &docVersion)); 201 { 202 uint32_t vrs; 203 struct GNUNET_TIME_Timestamp exp; 204 205 FAILIF (ANASTASIS_DB_ACCOUNT_STATUS_VALID_HASH_RETURNED != 206 plugin->lookup_account (plugin->cls, 207 &accountPubP, 208 &exp, 209 &r, 210 &vrs)); 211 } 212 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 213 plugin->get_key_share (plugin->cls, 214 &truth_uuid, 215 &res_key_share)); 216 FAILIF (0 != 217 GNUNET_memcmp (&res_key_share, 218 &key_share)); 219 220 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 221 plugin->get_recovery_document (plugin->cls, 222 &accountPubP, 223 recversion, 224 &res_account_sig, 225 &res_recovery_data_hash, 226 &recoverydatasize, 227 &res_recovery_data)); 228 FAILIF (0 != memcmp (res_recovery_data, 229 recovery_data, 230 strlen (recovery_data))); 231 GNUNET_free (res_recovery_data); 232 233 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 234 plugin->get_latest_recovery_document (plugin->cls, 235 &accountPubP, 236 &res_account_sig, 237 &res_recovery_data_hash, 238 &recoverydatasize, 239 &res_recovery_data, 240 &res_version)); 241 FAILIF (0 != memcmp (res_recovery_data, 242 recovery_data, 243 strlen (recovery_data))); 244 GNUNET_free (res_recovery_data); 245 246 { 247 struct GNUNET_TIME_Timestamp rt; 248 249 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 250 plugin->create_challenge_code (plugin->cls, 251 &truth_uuid, 252 GNUNET_TIME_UNIT_HOURS, 253 GNUNET_TIME_UNIT_DAYS, 254 3, /* retry counter */ 255 &rt, 256 &challenge_code)); 257 FAILIF (! GNUNET_TIME_absolute_is_zero (rt.abs_time)); 258 } 259 { 260 struct GNUNET_TIME_Timestamp rt; 261 uint64_t c2; 262 263 FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != 264 plugin->create_challenge_code (plugin->cls, 265 &truth_uuid, 266 GNUNET_TIME_UNIT_HOURS, 267 GNUNET_TIME_UNIT_DAYS, 268 3, /* retry counter */ 269 &rt, 270 &c2)); 271 FAILIF (c2 != challenge_code); 272 } 273 ANASTASIS_hash_answer (123, 274 &c_hash); 275 { 276 bool sat; 277 uint64_t r_code; 278 279 FAILIF (ANASTASIS_DB_CODE_STATUS_CHALLENGE_CODE_MISMATCH != 280 plugin->verify_challenge_code (plugin->cls, 281 &truth_uuid, 282 &c_hash, 283 &r_code, 284 &sat)); 285 286 ANASTASIS_hash_answer (challenge_code, 287 &c_hash); 288 FAILIF (ANASTASIS_DB_CODE_STATUS_VALID_CODE_STORED != 289 plugin->verify_challenge_code (plugin->cls, 290 &truth_uuid, 291 &c_hash, 292 &r_code, 293 &sat)); 294 } 295 if (-1 == result) 296 result = 0; 297 298 drop: 299 GNUNET_break (GNUNET_OK == 300 plugin->drop_tables (plugin->cls)); 301 ANASTASIS_DB_plugin_unload (plugin); 302 if (NULL != plugin) 303 { 304 plugin = NULL; 305 } 306 } 307 308 309 int 310 main (int argc, 311 char *const argv[]) 312 { 313 const char *plugin_name; 314 char *config_filename; 315 char *testname; 316 struct GNUNET_CONFIGURATION_Handle *cfg; 317 318 result = -1; 319 if (NULL == (plugin_name = strrchr (argv[0], (int) '-'))) 320 { 321 GNUNET_break (0); 322 return -1; 323 } 324 GNUNET_log_setup (argv[0], "DEBUG", NULL); 325 plugin_name++; 326 GNUNET_asprintf (&testname, 327 "%s", 328 plugin_name); 329 GNUNET_asprintf (&config_filename, 330 "test_anastasis_db_%s.conf", 331 testname); 332 cfg = GNUNET_CONFIGURATION_create (ANASTASIS_project_data ()); 333 if (GNUNET_OK != 334 GNUNET_CONFIGURATION_load (cfg, 335 config_filename)) 336 { 337 GNUNET_break (0); 338 GNUNET_free (config_filename); 339 GNUNET_free (testname); 340 return 2; 341 } 342 GNUNET_SCHEDULER_run (&run, 343 cfg); 344 GNUNET_CONFIGURATION_destroy (cfg); 345 GNUNET_free (config_filename); 346 GNUNET_free (testname); 347 return result; 348 } 349 350 351 /* end of test_anastasis_db.c */