anastasis

Credential backup and recovery protocol and service
Log | Files | Refs | Submodules | README | LICENSE

test_anastasis_db.c (10102B)


      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 (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  * Main function that will be run by the scheduler.
     47  *
     48  * @param cls closure with config
     49  */
     50 static void
     51 run (void *cls)
     52 {
     53   struct GNUNET_CONFIGURATION_Handle *cfg = cls;
     54   struct TALER_Amount amount;
     55   struct ANASTASIS_PaymentSecretP paymentSecretP;
     56   struct ANASTASIS_CRYPTO_AccountPublicKeyP accountPubP;
     57   struct ANASTASIS_AccountSignatureP accountSig;
     58   struct ANASTASIS_AccountSignatureP res_account_sig;
     59   struct GNUNET_HashCode recoveryDataHash;
     60   struct GNUNET_HashCode res_recovery_data_hash;
     61   struct GNUNET_HashCode r;
     62   struct GNUNET_TIME_Relative rel_time;
     63   struct ANASTASIS_CRYPTO_TruthUUIDP truth_uuid;
     64   struct ANASTASIS_CRYPTO_EncryptedKeyShareP key_share;
     65   unsigned int post_counter;
     66   const char *mime_type;
     67   const char *method;
     68   uint32_t docVersion;
     69   uint32_t res_version;
     70   size_t recoverydatasize;
     71   void *res_recovery_data = NULL;
     72   struct ANASTASIS_CRYPTO_EncryptedKeyShareP res_key_share;
     73   bool paid;
     74   bool valid_counter;
     75   uint32_t recversion = 1;
     76   unsigned char aes_gcm_tag[16];
     77   const char *recovery_data = "RECOVERY_DATA";
     78   uint64_t challenge_code = 1234;
     79   struct GNUNET_HashCode c_hash;
     80   struct ANASTASIS_UploadSignaturePS usp = {
     81     .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST),
     82     .purpose.size = htonl (sizeof (usp))
     83   };
     84 
     85   if (GNUNET_OK !=
     86       ANASTASIS_DB_init (cfg))
     87   {
     88     result = 77;
     89     return;
     90   }
     91   (void) ANASTASIS_DB_drop_tables ();
     92   if (GNUNET_OK !=
     93       ANASTASIS_DB_create_tables ())
     94   {
     95     result = 77;
     96     return;
     97   }
     98   if (GNUNET_OK !=
     99       ANASTASIS_DB_preflight ())
    100   {
    101     result = 77;
    102     return;
    103   }
    104 
    105   GNUNET_CRYPTO_hash (recovery_data,
    106                       strlen (recovery_data),
    107                       &recoveryDataHash);
    108   RND_BLK (&paymentSecretP);
    109   RND_BLK (&aes_gcm_tag);
    110   post_counter = 2;
    111   mime_type = "Picture";
    112   method = "Method";
    113   TALER_string_to_amount ("EUR:30",&amount);
    114 
    115   GNUNET_CRYPTO_random_block (&truth_uuid,
    116                               sizeof (truth_uuid));
    117   rel_time = GNUNET_TIME_UNIT_MONTHS;
    118 
    119   GNUNET_assert (GNUNET_OK ==
    120                  TALER_string_to_amount ("EUR:1",
    121                                          &amount));
    122 
    123   memset (&key_share, 1, sizeof (key_share));
    124   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    125           ANASTASIS_DB_store_truth (
    126             &truth_uuid,
    127             &key_share,
    128             mime_type,
    129             "encrypted_truth",
    130             strlen ("encrypted_truth"),
    131             method,
    132             rel_time));
    133 
    134   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
    135           ANASTASIS_DB_check_payment_identifier (
    136             &paymentSecretP,
    137             &paid,
    138             &valid_counter));
    139 
    140   memset (&accountPubP, 2, sizeof (accountPubP));
    141   memset (&accountSig, 3, sizeof (accountSig));
    142   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    143           ANASTASIS_DB_record_recdoc_payment (
    144             &accountPubP,
    145             post_counter,
    146             &paymentSecretP,
    147             &amount));
    148   {
    149     struct GNUNET_TIME_Timestamp res_time;
    150 
    151     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    152             ANASTASIS_DB_increment_lifetime (
    153               &accountPubP,
    154               &paymentSecretP,
    155               rel_time,
    156               &res_time));
    157   }
    158   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    159           ANASTASIS_DB_check_payment_identifier (
    160             &paymentSecretP,
    161             &paid,
    162             &valid_counter));
    163   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
    164           ANASTASIS_DB_check_challenge_payment (
    165             &paymentSecretP,
    166             &truth_uuid,
    167             &paid));
    168   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    169           ANASTASIS_DB_record_challenge_payment (
    170             &truth_uuid,
    171             &paymentSecretP,
    172             &amount));
    173   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    174           ANASTASIS_DB_update_challenge_payment (
    175             &truth_uuid,
    176             &paymentSecretP));
    177   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    178           ANASTASIS_DB_check_challenge_payment (
    179             &paymentSecretP,
    180             &truth_uuid,
    181             &paid));
    182   FAILIF (! paid);
    183   FAILIF (ANASTASIS_DB_STORE_STATUS_SUCCESS !=
    184           ANASTASIS_DB_store_recovery_document (
    185             &accountPubP,
    186             &accountSig,
    187             &recoveryDataHash,
    188             recovery_data,
    189             strlen (recovery_data),
    190             "meta-data",
    191             strlen ("meta-data"),
    192             &paymentSecretP,
    193             &docVersion));
    194   {
    195     uint32_t vrs;
    196     struct GNUNET_TIME_Timestamp exp;
    197 
    198     FAILIF (ANASTASIS_DB_ACCOUNT_STATUS_VALID_HASH_RETURNED !=
    199             ANASTASIS_DB_lookup_account (
    200               &accountPubP,
    201               &exp,
    202               &r,
    203               &vrs));
    204   }
    205   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    206           ANASTASIS_DB_get_key_share (
    207             &truth_uuid,
    208             &res_key_share));
    209   FAILIF (0 !=
    210           GNUNET_memcmp (&res_key_share,
    211                          &key_share));
    212 
    213   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    214           ANASTASIS_DB_get_recovery_document (
    215             &accountPubP,
    216             recversion,
    217             &res_account_sig,
    218             &res_recovery_data_hash,
    219             &recoverydatasize,
    220             &res_recovery_data));
    221   FAILIF (0 != memcmp (res_recovery_data,
    222                        recovery_data,
    223                        strlen (recovery_data)));
    224   GNUNET_free (res_recovery_data);
    225 
    226   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    227           ANASTASIS_DB_get_latest_recovery_document (
    228             &accountPubP,
    229             &res_account_sig,
    230             &res_recovery_data_hash,
    231             &recoverydatasize,
    232             &res_recovery_data,
    233             &res_version));
    234   FAILIF (0 != memcmp (res_recovery_data,
    235                        recovery_data,
    236                        strlen (recovery_data)));
    237   GNUNET_free (res_recovery_data);
    238 
    239   {
    240     struct GNUNET_TIME_Timestamp rt;
    241 
    242     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    243             ANASTASIS_DB_create_challenge_code (
    244               &truth_uuid,
    245               GNUNET_TIME_UNIT_HOURS,
    246               GNUNET_TIME_UNIT_DAYS,
    247               3,                              /* retry counter */
    248               &rt,
    249               &challenge_code));
    250     FAILIF (! GNUNET_TIME_absolute_is_zero (rt.abs_time));
    251   }
    252   {
    253     struct GNUNET_TIME_Timestamp rt;
    254     uint64_t c2;
    255 
    256     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    257             ANASTASIS_DB_create_challenge_code (
    258               &truth_uuid,
    259               GNUNET_TIME_UNIT_HOURS,
    260               GNUNET_TIME_UNIT_DAYS,
    261               3,                              /* retry counter */
    262               &rt,
    263               &c2));
    264     FAILIF (c2 != challenge_code);
    265   }
    266   ANASTASIS_hash_answer (123,
    267                          &c_hash);
    268   {
    269     bool sat;
    270     uint64_t r_code;
    271 
    272     FAILIF (ANASTASIS_DB_CODE_STATUS_CHALLENGE_CODE_MISMATCH !=
    273             ANASTASIS_DB_verify_challenge_code (
    274               &truth_uuid,
    275               &c_hash,
    276               &r_code,
    277               &sat));
    278 
    279     ANASTASIS_hash_answer (challenge_code,
    280                            &c_hash);
    281     FAILIF (ANASTASIS_DB_CODE_STATUS_VALID_CODE_STORED !=
    282             ANASTASIS_DB_verify_challenge_code (
    283               &truth_uuid,
    284               &c_hash,
    285               &r_code,
    286               &sat));
    287   }
    288   if (-1 == result)
    289     result = 0;
    290 
    291 drop:
    292   GNUNET_break (GNUNET_OK ==
    293                 ANASTASIS_DB_drop_tables ());
    294   ANASTASIS_DB_fini ();
    295 }
    296 
    297 
    298 int
    299 main (int argc,
    300       char *const argv[])
    301 {
    302   const char *plugin_name;
    303   char *config_filename;
    304   char *testname;
    305   struct GNUNET_CONFIGURATION_Handle *cfg;
    306 
    307   result = -1;
    308   if (NULL == (plugin_name = strrchr (argv[0], (int) '-')))
    309   {
    310     GNUNET_break (0);
    311     return -1;
    312   }
    313   GNUNET_log_setup (argv[0], "DEBUG", NULL);
    314   plugin_name++;
    315   GNUNET_asprintf (&testname,
    316                    "%s",
    317                    plugin_name);
    318   GNUNET_asprintf (&config_filename,
    319                    "test_anastasis_db_%s.conf",
    320                    testname);
    321   cfg = GNUNET_CONFIGURATION_create (ANASTASIS_project_data ());
    322   if (GNUNET_OK !=
    323       GNUNET_CONFIGURATION_load (cfg,
    324                                  config_filename))
    325   {
    326     GNUNET_break (0);
    327     GNUNET_free (config_filename);
    328     GNUNET_free (testname);
    329     return 2;
    330   }
    331   GNUNET_SCHEDULER_run (&run,
    332                         cfg);
    333   GNUNET_CONFIGURATION_destroy (cfg);
    334   GNUNET_free (config_filename);
    335   GNUNET_free (testname);
    336   return result;
    337 }
    338 
    339 
    340 /* end of test_anastasis_db.c */