anastasis_meta.c (4592B)
1 /* 2 This file is part of Anastasis 3 Copyright (C) 2022 Anastasis SARL 4 5 Anastasis is free software; you can redistribute it and/or modify it under the 6 terms of the GNU 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 General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along with 14 Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @brief anastasis client api to get recovery document meta data 18 * @author Christian Grothoff 19 */ 20 #include "platform.h" 21 #include "anastasis.h" 22 #include <taler/taler_json_lib.h> 23 #include <gnunet/gnunet_util_lib.h> 24 #include <taler/taler_merchant_service.h> 25 #include <microhttpd.h> 26 27 /** 28 * Handle for a version check operation. 29 */ 30 struct ANASTASIS_VersionCheck 31 { 32 /** 33 * Function to call with results. 34 */ 35 ANASTASIS_MetaPolicyCallback mpc; 36 37 /** 38 * Closure for @e mpc. 39 */ 40 void *mpc_cls; 41 42 /** 43 * Handle for the actual REST operation. 44 */ 45 struct ANASTASIS_PolicyMetaLookupOperation *plm; 46 47 /** 48 * User identifier (needed to decrypt). 49 */ 50 struct ANASTASIS_CRYPTO_UserIdentifierP id; 51 }; 52 53 54 /** 55 * Function called with results from a GET /policy/$POL/meta request 56 * 57 * @param cls closure with the `struct ANASTASIS_VersionCheck *` 58 * @param dd the response details 59 */ 60 static void 61 meta_cb ( 62 void *cls, 63 const struct ANASTASIS_MetaDownloadDetails *dd) 64 { 65 struct ANASTASIS_VersionCheck *vc = cls; 66 67 vc->plm = NULL; 68 if (MHD_HTTP_OK != dd->http_status) 69 { 70 vc->mpc (vc->mpc_cls, 71 0, 72 GNUNET_TIME_UNIT_ZERO_TS, 73 NULL, 74 NULL); 75 ANASTASIS_recovery_get_versions_cancel (vc); 76 return; 77 } 78 for (size_t i = 0; i<dd->details.ok.metas_length; i++) 79 { 80 const struct ANASTASIS_MetaDataEntry *meta 81 = &dd->details.ok.metas[i]; 82 const char *secret_name = NULL; 83 const struct GNUNET_HashCode *eph; 84 void *dec; 85 size_t dec_len; 86 87 if (GNUNET_OK != 88 ANASTASIS_CRYPTO_recovery_metadata_decrypt ( 89 &vc->id, 90 meta->meta_data, 91 meta->meta_data_size, 92 &dec, 93 &dec_len)) 94 { 95 GNUNET_break_op (0); 96 continue; 97 } 98 if (sizeof (*eph) > dec_len) 99 { 100 GNUNET_break_op (0); 101 GNUNET_free (dec); 102 continue; 103 } 104 eph = dec; 105 if (sizeof (*eph) < dec_len) 106 { 107 secret_name = (const char *) &eph[1]; 108 dec_len -= sizeof (*eph); 109 if ('\0' != secret_name[dec_len - 1]) 110 { 111 GNUNET_break_op (0); 112 GNUNET_free (dec); 113 continue; 114 } 115 } 116 vc->mpc (vc->mpc_cls, 117 meta->version, 118 meta->server_time, 119 eph, 120 secret_name); 121 GNUNET_free (dec); 122 } 123 vc->mpc (vc->mpc_cls, 124 0, 125 GNUNET_TIME_UNIT_ZERO_TS, 126 NULL, 127 NULL); 128 ANASTASIS_recovery_get_versions_cancel (vc); 129 } 130 131 132 struct ANASTASIS_VersionCheck * 133 ANASTASIS_recovery_get_versions ( 134 struct GNUNET_CURL_Context *ctx, 135 const json_t *id_data, 136 unsigned int max_version, 137 const char *anastasis_provider_url, 138 const struct ANASTASIS_CRYPTO_ProviderSaltP *provider_salt, 139 ANASTASIS_MetaPolicyCallback mpc, 140 void *mpc_cls) 141 { 142 struct ANASTASIS_VersionCheck *vc; 143 struct ANASTASIS_CRYPTO_AccountPublicKeyP account_pub; 144 145 vc = GNUNET_new (struct ANASTASIS_VersionCheck); 146 vc->mpc = mpc; 147 vc->mpc_cls = mpc_cls; 148 ANASTASIS_CRYPTO_user_identifier_derive (id_data, 149 provider_salt, 150 &vc->id); 151 ANASTASIS_CRYPTO_account_public_key_derive (&vc->id, 152 &account_pub); 153 vc->plm = ANASTASIS_policy_meta_lookup (ctx, 154 anastasis_provider_url, 155 &account_pub, 156 max_version, 157 &meta_cb, 158 vc); 159 if (NULL == vc->plm) 160 { 161 GNUNET_break (0); 162 GNUNET_free (vc); 163 return NULL; 164 } 165 return vc; 166 } 167 168 169 void 170 ANASTASIS_recovery_get_versions_cancel (struct ANASTASIS_VersionCheck *vc) 171 { 172 if (NULL != vc->plm) 173 { 174 ANASTASIS_policy_meta_lookup_cancel (vc->plm); 175 vc->plm = NULL; 176 } 177 GNUNET_free (vc); 178 }