コード例 #1
0
ファイル: ticket.c プロジェクト: androdev4u/bud
bud_error_t bud_context_set_ticket(bud_context_t* context,
                                   const char* ticket,
                                   size_t size,
                                   bud_encoding_t enc) {
  bud_config_t* config;
  bud_context_t* root;
  size_t max_len;
  int i;

  config = context->config;
  root = &config->contexts[0];

  if (enc == kBudEncodingRaw) {
    if (size != sizeof(context->ticket_key_storage))
      return bud_error(kBudErrSmallTicketKey);

    memcpy(context->ticket_key_storage, ticket, size);
  } else {
    ASSERT(enc == kBudEncodingBase64, "Unexpected encoding of ticket key");

    max_len = sizeof(context->ticket_key_storage);
    if (bud_base64_decode(context->ticket_key_storage,
                          max_len,
                          ticket,
                          size) < max_len) {
      return bud_error(kBudErrSmallTicketKey);
    }
  }

  context->ticket_key_on = 1;
  if (context->ctx != NULL) {
    SSL_CTX_set_tlsext_ticket_keys(context->ctx,
                                   context->ticket_key_storage,
                                   sizeof(context->ticket_key_storage));
  }

  if (context != root)
    return bud_ok();

  /* Update ticket key in dependent contexts */
  for (i = 0; i < config->context_count + 1; i++) {
    bud_context_t* cur;

    cur = &config->contexts[i];
    if (cur->ticket_key_on || cur->ctx == NULL)
      continue;

    SSL_CTX_set_tlsext_ticket_keys(cur->ctx,
                                   cur->ticket_key_storage,
                                   sizeof(cur->ticket_key_storage));
  }

  return bud_ok();
}
コード例 #2
0
ファイル: ocsp.c プロジェクト: laggyluke/bud
int bud_client_staple_json(bud_client_t* client, JSON_Value* json) {
  JSON_Object* obj;
  const char* b64_body;
  size_t b64_body_len;
  char* body;
  const unsigned char* pbody;
  size_t body_len;
  OCSP_RESPONSE* resp;
  int status;
  int r;

  r = -1;
  body = NULL;

  obj = json_value_get_object(json);
  b64_body = json_object_get_string(obj, "response");
  if (b64_body == NULL)
    goto done;

  b64_body_len = strlen(b64_body);
  body_len = bud_base64_decoded_size_fast(b64_body_len);
  body = malloc(body_len);
  if (body == NULL)
    goto done;

  body_len = bud_base64_decode(body, body_len, b64_body, b64_body_len);
  pbody = (const unsigned char*) body;
  resp = d2i_OCSP_RESPONSE(NULL, &pbody, body_len);
  if (resp == NULL)
    goto done;

  /* Not successful response, do not waste bandwidth on it */
  status = OCSP_response_status(resp);
  OCSP_RESPONSE_free(resp);
  if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL)
    goto done;

  /* Set stapling! */
  client->stapling_ocsp_resp = body;
  client->stapling_ocsp_resp_len = body_len;
  body = NULL;
  r = 0;

done:
  free(body);
  return r;
}
コード例 #3
0
bud_error_t bud_config_new_ssl_ctx(bud_config_t* config,
                                   bud_context_t* context) {
  SSL_CTX* ctx;
  int ecdh_nid;
  EC_KEY* ecdh;
  bud_error_t err;
  int options;
  int r;
  const char* ticket_key;
  size_t max_len;

  if (context->backend != NULL) {
    if (context->backend->keepalive == -1)
      context->backend->keepalive = kBudDefaultKeepalive;
    r = bud_config_str_to_addr(context->backend->host,
                               context->backend->port,
                               &context->backend->addr);
    if (r != 0)
      return bud_error_num(kBudErrPton, r);
  }

  /* Decode ticket_key */
  ticket_key = context->ticket_key == NULL ? config->frontend.ticket_key :
                                             context->ticket_key;
  if (ticket_key != NULL) {
    max_len = sizeof(context->ticket_key_storage);
    if (bud_base64_decode(context->ticket_key_storage,
                          max_len,
                          ticket_key,
                          strlen(ticket_key)) < max_len) {
      return bud_error(kBudErrSmallTicketKey);
    }
  }

  /* Choose method, tlsv1_2 by default */
  if (config->frontend.method == NULL) {
    if (strcmp(config->frontend.security, "tls1.1") == 0)
      config->frontend.method = TLSv1_1_server_method();
    else if (strcmp(config->frontend.security, "tls1.0") == 0)
      config->frontend.method = TLSv1_server_method();
    else if (strcmp(config->frontend.security, "tls1.2") == 0)
      config->frontend.method = TLSv1_2_server_method();
    else if (strcmp(config->frontend.security, "ssl3") == 0)
      config->frontend.method = SSLv3_server_method();
    else
      config->frontend.method = SSLv23_server_method();
  }

  ctx = SSL_CTX_new(config->frontend.method);
  if (ctx == NULL)
    return bud_error_str(kBudErrNoMem, "SSL_CTX");

  /* Disable sessions, they won't work with cluster anyway */
  SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);

  if (config->frontend.max_send_fragment)
    SSL_CTX_set_max_send_fragment(ctx, config->frontend.max_send_fragment);

  if (ticket_key != NULL) {
    SSL_CTX_set_tlsext_ticket_keys(ctx,
                                   context->ticket_key_storage,
                                   sizeof(context->ticket_key_storage));
  }

  /* ECDH curve selection */
  if (context->ecdh != NULL || config->frontend.ecdh != NULL) {
    if (context->ecdh != NULL)
      ecdh_nid = OBJ_sn2nid(context->ecdh);
    else
      ecdh_nid = OBJ_sn2nid(config->frontend.ecdh);

    if (ecdh_nid == NID_undef) {
      ecdh = NULL;
      err = bud_error_str(kBudErrECDHNotFound,
                          context->ecdh == NULL ? config->frontend.ecdh :
                                                  context->ecdh);
      goto fatal;
    }

    ecdh = EC_KEY_new_by_curve_name(ecdh_nid);
    if (ecdh == NULL) {
      err = bud_error_str(kBudErrNoMem, "EC_KEY");
      goto fatal;
    }

    SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
    SSL_CTX_set_tmp_ecdh(ctx, ecdh);
    EC_KEY_free(ecdh);
  }
  ecdh = NULL;

  /* Cipher suites */
  if (context->ciphers != NULL)
    SSL_CTX_set_cipher_list(ctx, context->ciphers);
  else if (config->frontend.ciphers != NULL)
    SSL_CTX_set_cipher_list(ctx, config->frontend.ciphers);

  /* Disable SSL2 */
  options = SSL_OP_NO_SSLv2 | SSL_OP_ALL;
  if (!config->frontend.ssl3)
    options |= SSL_OP_NO_SSLv3;

  if (config->frontend.server_preference)
    options |= SSL_OP_CIPHER_SERVER_PREFERENCE;
  SSL_CTX_set_options(ctx, options);

#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
  if (config->context_count != 0) {
    SSL_CTX_set_tlsext_servername_callback(ctx,
                                           bud_config_select_sni_context);
    SSL_CTX_set_tlsext_servername_arg(ctx, config);
  }
#endif  /* SSL_CTRL_SET_TLSEXT_SERVERNAME_CB */

#ifdef OPENSSL_NPN_NEGOTIATED
  context->npn_line = bud_config_encode_npn(config,
                                            context->npn,
                                            &context->npn_line_len,
                                            &err);
  if (!bud_is_ok(err))
    goto fatal;

  if (context->npn_line != NULL) {
    SSL_CTX_set_next_protos_advertised_cb(ctx,
                                          bud_config_advertise_next_proto,
                                          context);
  }
#else  /* !OPENSSL_NPN_NEGOTIATED */
  err = bud_error(kBudErrNPNNotSupported);
  goto fatal;
#endif  /* OPENSSL_NPN_NEGOTIATED */

  SSL_CTX_set_tlsext_status_cb(ctx, bud_client_stapling_cb);

  context->ctx = ctx;
  return bud_ok();

fatal:
  if (ecdh != NULL)
    EC_KEY_free(ecdh);

  SSL_CTX_free(ctx);
  return err;
}