Example #1
0
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;
}
Example #2
0
File: ocsp.c Project: laggyluke/bud
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);
}