Line data Source code
1 : /* 2 : This file is part of TALER 3 : Copyright (C) 2015-2021 Taler Systems SA 4 : 5 : TALER 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 : TALER 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 : TALER; see the file COPYING. If not, see 15 : <http://www.gnu.org/licenses/> 16 : */ 17 : /** 18 : * @file lib/exchange_api_management_revoke_signing_key.c 19 : * @brief functions to revoke an exchange online signing key 20 : * @author Christian Grothoff 21 : */ 22 : #include "taler/platform.h" 23 : #include "taler/taler_json_lib.h" 24 : #include <gnunet/gnunet_curl_lib.h> 25 : #include <microhttpd.h> 26 : #include "taler/taler_exchange_service.h" 27 : #include "exchange_api_curl_defaults.h" 28 : #include "taler/taler_signatures.h" 29 : #include "taler/taler_curl_lib.h" 30 : #include "taler/taler_json_lib.h" 31 : 32 : 33 : struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle 34 : { 35 : 36 : /** 37 : * The url for this request. 38 : */ 39 : char *url; 40 : 41 : /** 42 : * Minor context that holds body and headers. 43 : */ 44 : struct TALER_CURL_PostContext post_ctx; 45 : 46 : /** 47 : * Handle for the request. 48 : */ 49 : struct GNUNET_CURL_Job *job; 50 : 51 : /** 52 : * Function to call with the result. 53 : */ 54 : TALER_EXCHANGE_ManagementRevokeSigningKeyCallback cb; 55 : 56 : /** 57 : * Closure for @a cb. 58 : */ 59 : void *cb_cls; 60 : 61 : /** 62 : * Reference to the execution context. 63 : */ 64 : struct GNUNET_CURL_Context *ctx; 65 : }; 66 : 67 : 68 : /** 69 : * Function called when we're done processing the 70 : * HTTP /management/signkeys/%s/revoke request. 71 : * 72 : * @param cls the `struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *` 73 : * @param response_code HTTP response code, 0 on error 74 : * @param response response body, NULL if not in JSON 75 : */ 76 : static void 77 0 : handle_revoke_signing_finished (void *cls, 78 : long response_code, 79 : const void *response) 80 : { 81 0 : struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *rh = cls; 82 0 : const json_t *json = response; 83 0 : struct TALER_EXCHANGE_ManagementRevokeSigningKeyResponse rsr = { 84 0 : .hr.http_status = (unsigned int) response_code, 85 : .hr.reply = json 86 : }; 87 : 88 0 : rh->job = NULL; 89 0 : switch (response_code) 90 : { 91 0 : case 0: 92 : /* no reply */ 93 0 : rsr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; 94 0 : rsr.hr.hint = "server offline?"; 95 0 : break; 96 0 : case MHD_HTTP_NO_CONTENT: 97 0 : break; 98 0 : case MHD_HTTP_FORBIDDEN: 99 0 : rsr.hr.ec = TALER_JSON_get_error_code (json); 100 0 : rsr.hr.hint = TALER_JSON_get_error_hint (json); 101 0 : break; 102 0 : default: 103 : /* unexpected response code */ 104 0 : GNUNET_break_op (0); 105 0 : rsr.hr.ec = TALER_JSON_get_error_code (json); 106 0 : rsr.hr.hint = TALER_JSON_get_error_hint (json); 107 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 108 : "Unexpected response code %u/%d for exchange management revoke signkey\n", 109 : (unsigned int) response_code, 110 : (int) rsr.hr.ec); 111 0 : break; 112 : } 113 0 : if (NULL != rh->cb) 114 : { 115 0 : rh->cb (rh->cb_cls, 116 : &rsr); 117 0 : rh->cb = NULL; 118 : } 119 0 : TALER_EXCHANGE_management_revoke_signing_key_cancel (rh); 120 0 : } 121 : 122 : 123 : struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle * 124 0 : TALER_EXCHANGE_management_revoke_signing_key ( 125 : struct GNUNET_CURL_Context *ctx, 126 : const char *url, 127 : const struct TALER_ExchangePublicKeyP *exchange_pub, 128 : const struct TALER_MasterSignatureP *master_sig, 129 : TALER_EXCHANGE_ManagementRevokeSigningKeyCallback cb, 130 : void *cb_cls) 131 : { 132 : struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *rh; 133 : CURL *eh; 134 : json_t *body; 135 : 136 0 : rh = GNUNET_new (struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle); 137 0 : rh->cb = cb; 138 0 : rh->cb_cls = cb_cls; 139 0 : rh->ctx = ctx; 140 : { 141 : char epub_str[sizeof (*exchange_pub) * 2]; 142 : char arg_str[sizeof (epub_str) + 64]; 143 : char *end; 144 : 145 0 : end = GNUNET_STRINGS_data_to_string (exchange_pub, 146 : sizeof (*exchange_pub), 147 : epub_str, 148 : sizeof (epub_str)); 149 0 : *end = '\0'; 150 0 : GNUNET_snprintf (arg_str, 151 : sizeof (arg_str), 152 : "management/signkeys/%s/revoke", 153 : epub_str); 154 0 : rh->url = TALER_url_join (url, 155 : arg_str, 156 : NULL); 157 : } 158 0 : if (NULL == rh->url) 159 : { 160 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 161 : "Could not construct request URL.\n"); 162 0 : GNUNET_free (rh); 163 0 : return NULL; 164 : } 165 0 : body = GNUNET_JSON_PACK ( 166 : GNUNET_JSON_pack_data_auto ("master_sig", 167 : master_sig)); 168 0 : eh = TALER_EXCHANGE_curl_easy_get_ (rh->url); 169 0 : if ( (NULL == eh) || 170 : (GNUNET_OK != 171 0 : TALER_curl_easy_post (&rh->post_ctx, 172 : eh, 173 : body)) ) 174 : { 175 0 : GNUNET_break (0); 176 0 : if (NULL != eh) 177 0 : curl_easy_cleanup (eh); 178 0 : json_decref (body); 179 0 : GNUNET_free (rh->url); 180 0 : GNUNET_free (rh); 181 0 : return NULL; 182 : } 183 0 : json_decref (body); 184 0 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 185 : "Requesting URL '%s'\n", 186 : rh->url); 187 0 : rh->job = GNUNET_CURL_job_add2 (ctx, 188 : eh, 189 0 : rh->post_ctx.headers, 190 : &handle_revoke_signing_finished, 191 : rh); 192 0 : if (NULL == rh->job) 193 : { 194 0 : TALER_EXCHANGE_management_revoke_signing_key_cancel (rh); 195 0 : return NULL; 196 : } 197 0 : return rh; 198 : } 199 : 200 : 201 : void 202 0 : TALER_EXCHANGE_management_revoke_signing_key_cancel ( 203 : struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *rh) 204 : { 205 0 : if (NULL != rh->job) 206 : { 207 0 : GNUNET_CURL_job_cancel (rh->job); 208 0 : rh->job = NULL; 209 : } 210 0 : TALER_curl_easy_post_finished (&rh->post_ctx); 211 0 : GNUNET_free (rh->url); 212 0 : GNUNET_free (rh); 213 0 : }