sync_service.h (9126B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2019-2023 Taler Systems SA 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 Lesser General Public License for more details. 12 13 You should have received a copy of the GNU Lesser General Public License along with 14 Anastasis; see the file COPYING.LIB. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file include/sync_service.h 18 * @brief C interface of libsync, a C library to use sync's HTTP API 19 * @author Christian Grothoff 20 */ 21 #ifndef SYNC_SERVICE_H 22 #define SYNC_SERVICE_H 23 24 #include <gnunet/gnunet_util_lib.h> 25 #include <taler/taler_error_codes.h> 26 #include <gnunet/gnunet_curl_lib.h> 27 #include <jansson.h> 28 29 30 GNUNET_NETWORK_STRUCT_BEGIN 31 32 33 /** 34 * Private key identifying an account. 35 */ 36 struct SYNC_AccountPrivateKeyP 37 { 38 /** 39 * We use EdDSA. 40 */ 41 struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv; 42 }; 43 44 45 /** 46 * Public key identifying an account. 47 */ 48 struct SYNC_AccountPublicKeyP 49 { 50 /** 51 * We use EdDSA. 52 */ 53 struct GNUNET_CRYPTO_EddsaPublicKey eddsa_pub; 54 }; 55 56 57 /** 58 * Data signed by the account public key of a sync client to 59 * authorize the upload of the backup. 60 */ 61 struct SYNC_UploadSignaturePS 62 { 63 /** 64 * Set to #TALER_SIGNATURE_SYNC_BACKUP_UPLOAD. 65 */ 66 struct GNUNET_CRYPTO_SignaturePurpose purpose; 67 68 /** 69 * Hash of the previous backup, all zeros for none. 70 */ 71 struct GNUNET_HashCode old_backup_hash GNUNET_PACKED; 72 73 /** 74 * Hash of the new backup. 75 */ 76 struct GNUNET_HashCode new_backup_hash GNUNET_PACKED; 77 78 }; 79 80 81 /** 82 * Signature made with an account's public key. 83 */ 84 struct SYNC_AccountSignatureP 85 { 86 /** 87 * We use EdDSA. 88 */ 89 struct GNUNET_CRYPTO_EddsaSignature eddsa_sig; 90 }; 91 92 GNUNET_NETWORK_STRUCT_END 93 94 95 /** 96 * High-level ways how an upload may conclude. 97 */ 98 enum SYNC_UploadStatus 99 { 100 /** 101 * Backup was successfully made. 102 */ 103 SYNC_US_SUCCESS = 0, 104 105 /** 106 * Account expired or payment was explicitly requested 107 * by the client. 108 */ 109 SYNC_US_PAYMENT_REQUIRED = 1, 110 111 /** 112 * Conflicting backup existed on server. Client should 113 * reconcile and try again with (using the provided 114 * recovered backup as the previous backup). 115 */ 116 SYNC_US_CONFLICTING_BACKUP = 2, 117 118 /** 119 * HTTP interaction failed, see HTTP status. 120 */ 121 SYNC_US_HTTP_ERROR = 3, 122 123 /** 124 * We had an internal error (not sure this can happen, 125 * but reserved for HTTP 400 status codes). 126 */ 127 SYNC_US_CLIENT_ERROR = 4, 128 129 /** 130 * Server had an internal error. 131 */ 132 SYNC_US_SERVER_ERROR = 5 133 }; 134 135 136 /** 137 * Result of an upload. 138 */ 139 struct SYNC_UploadDetails 140 { 141 142 /** 143 * Taler error code. 144 */ 145 enum TALER_ErrorCode ec; 146 147 /** 148 * HTTP status of the request. 149 */ 150 unsigned int http_status; 151 152 /** 153 * High level status of the upload operation. 154 */ 155 enum SYNC_UploadStatus us; 156 157 /** 158 * Details depending on @e us. 159 */ 160 union 161 { 162 163 /** 164 * Data returned if @e us is #SYNC_US_SUCCESS. 165 */ 166 struct 167 { 168 169 /** 170 * Hash of the synchronized backup. 171 */ 172 const struct GNUNET_HashCode *curr_backup_hash; 173 174 } success; 175 176 /** 177 * Previous backup. Returned if @e us is 178 * #SYNC_US_CONFLICTING_BACKUP 179 */ 180 struct 181 { 182 /** 183 * Hash over @e existing_backup. 184 */ 185 struct GNUNET_HashCode existing_backup_hash; 186 187 /** 188 * Number of bytes in @e existing_backup. 189 */ 190 size_t existing_backup_size; 191 192 /** 193 * The backup on the server, which does not match the 194 * "previous" backup expected by the client and thus 195 * needs to be decrypted, reconciled and re-uploaded. 196 */ 197 const void *existing_backup; 198 199 } recovered_backup; 200 201 struct 202 { 203 /** 204 * A taler://pay/-URI with a request to pay the annual fee for 205 * the service. Returned if @e us is #SYNC_US_PAYMENT_REQUIRED. 206 */ 207 const char *payment_request; 208 209 } payment_required; 210 211 } details; 212 213 }; 214 215 216 /** 217 * Function called with the results of a #SYNC_upload(). 218 * 219 * @param cls closure 220 * @param ud details about the upload operation 221 */ 222 typedef void 223 (*SYNC_UploadCallback)(void *cls, 224 const struct SYNC_UploadDetails *ud); 225 226 227 /** 228 * Handle for an upload operatoin. 229 */ 230 struct SYNC_UploadOperation; 231 232 /** 233 * Options for payment. 234 */ 235 enum SYNC_PaymentOptions 236 { 237 /** 238 * No special options. 239 */ 240 SYNC_PO_NONE = 0, 241 242 /** 243 * Trigger payment even if sync does not require it 244 * yet (forced payment). 245 */ 246 SYNC_PO_FORCE_PAYMENT = 1, 247 248 /** 249 * Request a fresh order to be created, say because the 250 * existing one was claimed (but not paid) by another wallet. 251 */ 252 SYNC_PO_FRESH_ORDER = 2 253 }; 254 255 /** 256 * Upload a @a backup to a Sync server. Note that @a backup must 257 * have already been compressed, padded and encrypted by the 258 * client. 259 * 260 * While @a pub is theoretically protected by the HTTPS protocol and 261 * required to access the backup, it should be assumed that an 262 * adversary might be able to download the backups from the Sync 263 * server -- or even run the Sync server. Thus, strong encryption 264 * is essential and NOT implemented by this function. 265 * 266 * The use of Anastasis to safely store the Sync encryption keys and 267 * @a pub is recommended. Storing @a priv in Anastasis depends on 268 * your priorities: without @a priv, further updates to the backup are 269 * not possible, and the user would have to pay for another 270 * account. OTOH, without @a priv an adversary that compromised 271 * Anastasis can only read the backups, but not alter or destroy them. 272 * 273 * @param ctx for HTTP client request processing 274 * @param base_url base URL of the Sync server 275 * @param priv private key of an account with the server 276 * @param prev_backup_hash hash of the previous backup, NULL for the first upload ever 277 * @param backup_size number of bytes in @a backup 278 * @param backup the encrypted backup, must remain in 279 * memory until we are done with the operation! 280 * @param po payment options 281 * @param paid_order_id ID of the paid order, NULL if no payment was made so far 282 * @param cb function to call with the result 283 * @param cb_cls closure for @a cb 284 * @return handle for the operation 285 */ 286 struct SYNC_UploadOperation * 287 SYNC_upload (struct GNUNET_CURL_Context *ctx, 288 const char *base_url, 289 struct SYNC_AccountPrivateKeyP *priv, 290 const struct GNUNET_HashCode *prev_backup_hash, 291 size_t backup_size, 292 const void *backup, 293 enum SYNC_PaymentOptions po, 294 const char *paid_order_id, 295 SYNC_UploadCallback cb, 296 void *cb_cls); 297 298 299 /** 300 * Cancel the upload. Note that aborting an upload does NOT guarantee 301 * that it did not complete, it is possible that the server did 302 * receive the full request before the upload is aborted. 303 * 304 * @param[in] uo operation to cancel. 305 */ 306 void 307 SYNC_upload_cancel (struct SYNC_UploadOperation *uo); 308 309 310 /** 311 * Detailed results from the successful download. 312 */ 313 struct SYNC_DownloadDetails 314 { 315 316 /** 317 * HTTP status code. 318 */ 319 unsigned int http_status; 320 321 /** 322 * Details depending on @e http_status. 323 */ 324 union 325 { 326 327 /** 328 * Details if status is #MHD_HTTP_OK. 329 */ 330 struct 331 { 332 333 /** 334 * Signature (already verified). 335 */ 336 struct SYNC_AccountSignatureP sig; 337 338 /** 339 * Hash of the previous version. 340 */ 341 struct GNUNET_HashCode prev_backup_hash; 342 343 /** 344 * Hash over @e backup and @e backup_size. 345 */ 346 struct GNUNET_HashCode curr_backup_hash; 347 348 /** 349 * The backup we downloaded. 350 */ 351 const void *backup; 352 353 /** 354 * Number of bytes in @e backup. 355 */ 356 size_t backup_size; 357 } ok; 358 359 } details; 360 361 }; 362 363 364 /** 365 * Function called with the results of a #SYNC_download(). 366 * 367 * @param cls closure 368 * @param dd download details 369 */ 370 typedef void 371 (*SYNC_DownloadCallback)(void *cls, 372 const struct SYNC_DownloadDetails *dd); 373 374 375 /** 376 * Handle for a download operation. 377 */ 378 struct SYNC_DownloadOperation; 379 380 381 /** 382 * Download the latest version of a backup for account @a pub. 383 * 384 * @param ctx for HTTP client request processing 385 * @param base_url base URL of the Sync server 386 * @param pub account public key 387 * @param cb function to call with the backup 388 * @param cb_cls closure for @a cb 389 * @return handle for the operation 390 */ 391 struct SYNC_DownloadOperation * 392 SYNC_download (struct GNUNET_CURL_Context *ctx, 393 const char *base_url, 394 const struct SYNC_AccountPublicKeyP *pub, 395 SYNC_DownloadCallback cb, 396 void *cb_cls); 397 398 399 /** 400 * Cancel the download. 401 * 402 * @param[in] download operation to cancel. 403 */ 404 void 405 SYNC_download_cancel (struct SYNC_DownloadOperation *download); 406 407 408 #endif /* SYNC_SERVICE_H */