upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/main/cashu.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/cashu.c')
-rw-r--r--main/cashu.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/main/cashu.c b/main/cashu.c
index bafd000..8dffacc 100644
--- a/main/cashu.c
+++ b/main/cashu.c
@@ -14,9 +14,9 @@ static const size_t V3_PREFIX_LEN = 6;
14 14
15static int b64url_decode(const char *input, size_t input_len, char *out, size_t out_size, size_t *out_len) 15static int b64url_decode(const char *input, size_t input_len, char *out, size_t out_size, size_t *out_len)
16{ 16{
17 char b64[1024]; 17 char *b64 = malloc(input_len + 4);
18 if (!b64) return -1;
18 size_t b64_len = input_len; 19 size_t b64_len = input_len;
19 if (b64_len >= sizeof(b64)) return -1;
20 memcpy(b64, input, b64_len); 20 memcpy(b64, input, b64_len);
21 b64[b64_len] = '\0'; 21 b64[b64_len] = '\0';
22 22
@@ -24,7 +24,7 @@ static int b64url_decode(const char *input, size_t input_len, char *out, size_t
24 if (b64[i] == '-') b64[i] = '+'; 24 if (b64[i] == '-') b64[i] = '+';
25 else if (b64[i] == '_') b64[i] = '/'; 25 else if (b64[i] == '_') b64[i] = '/';
26 } 26 }
27 while (b64_len % 4 != 0 && b64_len < sizeof(b64) - 1) { 27 while (b64_len % 4 != 0) {
28 b64[b64_len++] = '='; 28 b64[b64_len++] = '=';
29 } 29 }
30 b64[b64_len] = '\0'; 30 b64[b64_len] = '\0';
@@ -32,6 +32,7 @@ static int b64url_decode(const char *input, size_t input_len, char *out, size_t
32 size_t olen = 0; 32 size_t olen = 0;
33 int ret = mbedtls_base64_decode((unsigned char *)out, out_size, &olen, 33 int ret = mbedtls_base64_decode((unsigned char *)out, out_size, &olen,
34 (const unsigned char *)b64, b64_len); 34 (const unsigned char *)b64, b64_len);
35 free(b64);
35 if (ret != 0) return -1; 36 if (ret != 0) return -1;
36 *out_len = olen; 37 *out_len = olen;
37 return 0; 38 return 0;
@@ -86,16 +87,19 @@ esp_err_t cashu_decode_token(const char *token_str, cashu_token_t *out)
86 return ESP_FAIL; 87 return ESP_FAIL;
87 } 88 }
88 89
89 char json_buf[2048]; 90 char *json_buf = malloc(2048);
91 if (!json_buf) return ESP_FAIL;
90 size_t json_len = 0; 92 size_t json_len = 0;
91 if (b64url_decode(token_str + V3_PREFIX_LEN, len - V3_PREFIX_LEN, 93 if (b64url_decode(token_str + V3_PREFIX_LEN, len - V3_PREFIX_LEN,
92 json_buf, sizeof(json_buf) - 1, &json_len) != 0) { 94 json_buf, 2047, &json_len) != 0) {
93 ESP_LOGE(TAG, "Base64url decode failed"); 95 ESP_LOGE(TAG, "Base64url decode failed");
96 free(json_buf);
94 return ESP_FAIL; 97 return ESP_FAIL;
95 } 98 }
96 json_buf[json_len] = '\0'; 99 json_buf[json_len] = '\0';
97 100
98 cJSON *root = cJSON_Parse(json_buf); 101 cJSON *root = cJSON_Parse(json_buf);
102 free(json_buf);
99 if (!root) { 103 if (!root) {
100 ESP_LOGE(TAG, "JSON parse failed"); 104 ESP_LOGE(TAG, "JSON parse failed");
101 return ESP_FAIL; 105 return ESP_FAIL;
@@ -167,14 +171,16 @@ esp_err_t cashu_check_proof_states(const char *mint_url, const cashu_token_t *to
167 char *ys_json = cJSON_PrintUnformatted(ys_arr); 171 char *ys_json = cJSON_PrintUnformatted(ys_arr);
168 cJSON_Delete(ys_arr); 172 cJSON_Delete(ys_arr);
169 173
170 char post_body[2048]; 174 char *post_body = malloc(4096);
171 snprintf(post_body, sizeof(post_body), "{\"Ys\":%s}", ys_json); 175 if (!post_body) { cJSON_free(ys_json); return ESP_FAIL; }
176 snprintf(post_body, 4096, "{\"Ys\":%s}", ys_json);
172 cJSON_free(ys_json); 177 cJSON_free(ys_json);
173 178
174 char url[512]; 179 char url[512];
175 snprintf(url, sizeof(url), "%s/v1/checkstate", mint_url); 180 snprintf(url, sizeof(url), "%s/v1/checkstate", mint_url);
176 181
177 char resp_buf[4096]; 182 char *resp_buf = malloc(8192);
183 if (!resp_buf) { free(post_body); return ESP_FAIL; }
178 int resp_len = 0; 184 int resp_len = 0;
179 185
180 esp_http_client_config_t config = { 186 esp_http_client_config_t config = {
@@ -183,27 +189,32 @@ esp_err_t cashu_check_proof_states(const char *mint_url, const cashu_token_t *to
183 .timeout_ms = 10000, 189 .timeout_ms = 10000,
184 }; 190 };
185 esp_http_client_handle_t client = esp_http_client_init(&config); 191 esp_http_client_handle_t client = esp_http_client_init(&config);
186 if (!client) return ESP_FAIL; 192 if (!client) { free(post_body); free(resp_buf); return ESP_FAIL; }
187 193
188 esp_http_client_set_header(client, "Content-Type", "application/json"); 194 esp_http_client_set_header(client, "Content-Type", "application/json");
189 esp_err_t err = esp_http_client_open(client, strlen(post_body)); 195 esp_err_t err = esp_http_client_open(client, strlen(post_body));
190 if (err != ESP_OK) { 196 if (err != ESP_OK) {
191 esp_http_client_cleanup(client); 197 esp_http_client_cleanup(client);
198 free(post_body);
199 free(resp_buf);
192 return err; 200 return err;
193 } 201 }
194 esp_http_client_write(client, post_body, strlen(post_body)); 202 esp_http_client_write(client, post_body, strlen(post_body));
203 free(post_body);
195 204
196 resp_len = esp_http_client_read(client, resp_buf, sizeof(resp_buf) - 1); 205 resp_len = esp_http_client_read(client, resp_buf, 8191);
197 int status = esp_http_client_get_status_code(client); 206 int status = esp_http_client_get_status_code(client);
198 esp_http_client_cleanup(client); 207 esp_http_client_cleanup(client);
199 208
200 if (status != 200 || resp_len <= 0) { 209 if (status != 200 || resp_len <= 0) {
201 ESP_LOGE(TAG, "checkstate returned %d", status); 210 ESP_LOGE(TAG, "checkstate returned %d", status);
211 free(resp_buf);
202 return ESP_FAIL; 212 return ESP_FAIL;
203 } 213 }
204 resp_buf[resp_len] = '\0'; 214 resp_buf[resp_len] = '\0';
205 215
206 cJSON *root = cJSON_Parse(resp_buf); 216 cJSON *root = cJSON_Parse(resp_buf);
217 free(resp_buf);
207 if (!root) return ESP_FAIL; 218 if (!root) return ESP_FAIL;
208 219
209 cJSON *states_arr = cJSON_GetObjectItemCaseSensitive(root, "states"); 220 cJSON *states_arr = cJSON_GetObjectItemCaseSensitive(root, "states");