const char* bud_context_get_ocsp_id(bud_context_t* context, size_t* size) { char* encoded; unsigned char* pencoded; size_t encoded_len; char* base64; size_t base64_len; if (context->ocsp_id == NULL) return NULL; base64 = NULL; encoded = NULL; /* Return cached id */ if (context->ocsp_der_id != NULL) goto done; encoded_len = i2d_OCSP_CERTID(context->ocsp_id, NULL); base64_len = bud_base64_encoded_size(encoded_len); encoded = malloc(encoded_len); base64 = malloc(base64_len); if (encoded == NULL || base64 == NULL) { encoded_len = 0; goto done; } pencoded = (unsigned char*) encoded; i2d_OCSP_CERTID(context->ocsp_id, &pencoded); bud_base64_encode(encoded, encoded_len, base64, base64_len); context->ocsp_der_id = base64; context->ocsp_der_id_len = base64_len; base64 = NULL; done: free(encoded); free(base64); *size = context->ocsp_der_id_len; return context->ocsp_der_id; }
void bud_client_stapling_cache_req_cb(bud_http_request_t* req, bud_error_t err) { bud_client_t* client; bud_config_t* config; bud_context_t* context; const char* id; size_t id_size; const char* url; size_t url_size; char* ocsp; size_t ocsp_size; char* json; size_t json_size; size_t offset; client = req->data; config = client->config; context = SSL_get_ex_data(client->ssl, kBudSSLSNIIndex); client->hello_parse = kBudProgressDone; client->stapling_cache_req = NULL; json = NULL; ocsp = NULL; ASSERT(context != NULL, "Context disappeared"); if (!bud_is_ok(err)) { WARNING(&client->frontend, "OCSP cache cb failed: %d - \"%s\"", err.code, err.str); goto done; } /* Cache hit, success */ if ((req->code >= 200 && req->code < 400) && bud_client_staple_json(client, req->response) == 0) { DBG_LN(&client->frontend, "stapling cache hit"); goto done; } DBG_LN(&client->frontend, "stapling cache miss"); id = bud_context_get_ocsp_id(context, &id_size); url = bud_context_get_ocsp_req(context, &url_size, &ocsp, &ocsp_size); /* Certificate has no OCSP url */ if (url == NULL) goto done; /* Format JSON request */ json_size = 2 + bud_base64_encoded_size(ocsp_size) + 2 + url_size; json_size += /* "ocsp": */ 7 + /* "url": */ 6 + /* {,}\0 */ 4; json = malloc(json_size); if (json == NULL) goto done; offset = snprintf(json, json_size, "{\"url\":\"%.*s\",\"ocsp\":\"", (int) url_size, url); bud_base64_encode(ocsp, ocsp_size, json + offset, json_size - offset); offset += bud_base64_encoded_size(ocsp_size); snprintf(json + offset, json_size - offset, "\"}"); /* Request OCSP response */ client->stapling_req = bud_http_post(config->stapling.pool, config->stapling.query_fmt, id, id_size, json, json_size - 1, bud_client_stapling_req_cb, &err); client->stapling_req->data = client; if (!bud_is_ok(err)) goto done; client->hello_parse = kBudProgressRunning; done: free(ocsp); free(json); json_value_free(req->response); bud_client_cycle(client); }