Ejemplo n.º 1
0
static gpr_slice compute_default_pem_root_certs_once(void) {
  gpr_slice result = gpr_empty_slice();

  /* First try to load the roots from the environment. */
  char *default_root_certs_path =
      gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR);
  if (default_root_certs_path != NULL) {
    result = gpr_load_file(default_root_certs_path, 0, NULL);
    gpr_free(default_root_certs_path);
  }

  /* Try overridden roots if needed. */
  grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL;
  if (GPR_SLICE_IS_EMPTY(result) && ssl_roots_override_cb != NULL) {
    char *pem_root_certs = NULL;
    ovrd_res = ssl_roots_override_cb(&pem_root_certs);
    if (ovrd_res == GRPC_SSL_ROOTS_OVERRIDE_OK) {
      GPR_ASSERT(pem_root_certs != NULL);
      result = gpr_slice_new(pem_root_certs, strlen(pem_root_certs), gpr_free);
    }
  }

  /* Fall back to installed certs if needed. */
  if (GPR_SLICE_IS_EMPTY(result) &&
      ovrd_res != GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY) {
    result = gpr_load_file(installed_roots_path, 0, NULL);
  }
  return result;
}
Ejemplo n.º 2
0
static void connected(grpc_exec_ctx *exec_ctx, void *arg, int success) {
  connector *c = arg;
  grpc_closure *notify;
  grpc_endpoint *tcp = c->newly_connecting_endpoint;
  if (tcp != NULL) {
    gpr_mu_lock(&c->mu);
    GPR_ASSERT(c->connecting_endpoint == NULL);
    c->connecting_endpoint = tcp;
    gpr_mu_unlock(&c->mu);
    if (!GPR_SLICE_IS_EMPTY(c->args.initial_connect_string)) {
      grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent,
                        c);
      gpr_slice_buffer_init(&c->initial_string_buffer);
      gpr_slice_buffer_add(&c->initial_string_buffer,
                           c->args.initial_connect_string);
      grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer,
                          &c->initial_string_sent);
    } else {
      grpc_security_connector_do_handshake(exec_ctx,
                                           &c->security_connector->base, tcp,
                                           on_secure_handshake_done, c);
    }
  } else {
    memset(c->result, 0, sizeof(*c->result));
    notify = c->notify;
    c->notify = NULL;
    notify->cb(exec_ctx, notify->cb_arg, 1);
  }
}
Ejemplo n.º 3
0
static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
  connector *c = arg;
  grpc_closure *notify;
  grpc_endpoint *tcp = c->newly_connecting_endpoint;
  if (tcp != NULL) {
    gpr_mu_lock(&c->mu);
    GPR_ASSERT(c->connecting_endpoint == NULL);
    c->connecting_endpoint = tcp;
    gpr_mu_unlock(&c->mu);
    if (!GPR_SLICE_IS_EMPTY(c->args.initial_connect_string)) {
      grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent,
                        c);
      gpr_slice_buffer_init(&c->initial_string_buffer);
      gpr_slice_buffer_add(&c->initial_string_buffer,
                           c->args.initial_connect_string);
      grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer,
                          &c->initial_string_sent);
    } else {
      grpc_channel_security_connector_do_handshake(
          exec_ctx, c->security_connector, tcp, c->args.deadline,
          on_secure_handshake_done, c);
    }
  } else {
    memset(c->result, 0, sizeof(*c->result));
    notify = c->notify;
    c->notify = NULL;
    grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL);
  }
}
Ejemplo n.º 4
0
static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
  connector *c = arg;
  grpc_closure *notify;
  grpc_endpoint *tcp = c->tcp;
  if (tcp != NULL) {
    if (!GPR_SLICE_IS_EMPTY(c->args.initial_connect_string)) {
      grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent,
                        c);
      gpr_slice_buffer_init(&c->initial_string_buffer);
      gpr_slice_buffer_add(&c->initial_string_buffer,
                           c->args.initial_connect_string);
      connector_ref(arg);
      grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer,
                          &c->initial_string_sent);
    }
    c->result->transport =
        grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, tcp, 1);
    grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL,
                                        0);
    GPR_ASSERT(c->result->transport);
    c->result->channel_args = c->args.channel_args;
  } else {
    memset(c->result, 0, sizeof(*c->result));
  }
  notify = c->notify;
  c->notify = NULL;
  notify->cb(exec_ctx, notify->cb_arg, 1);
}
Ejemplo n.º 5
0
static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
  connector *c = arg;
  grpc_endpoint *tcp = c->tcp;
  if (tcp != NULL) {
    if (!GPR_SLICE_IS_EMPTY(c->args.initial_connect_string)) {
      grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent,
                        c);
      gpr_slice_buffer_init(&c->initial_string_buffer);
      gpr_slice_buffer_add(&c->initial_string_buffer,
                           c->args.initial_connect_string);
      connector_ref(arg);
      grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer,
                          &c->initial_string_sent);
    } else {
      grpc_handshake_manager_do_handshake(
          exec_ctx, c->handshake_mgr, tcp, c->args.channel_args,
          c->args.deadline, NULL /* acceptor */, on_handshake_done, c);
    }
  } else {
    memset(c->result, 0, sizeof(*c->result));
    grpc_closure *notify = c->notify;
    c->notify = NULL;
    grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL);
  }
}
Ejemplo n.º 6
0
static void test_url_safe_unsafe_mismtach_failure(void) {
  unsigned char orig[256];
  size_t i;
  char *b64;
  gpr_slice orig_decoded;
  int url_safe = 1;
  for (i = 0; i < sizeof(orig); i++) orig[i] = (char)i;

  b64 = grpc_base64_encode(orig, sizeof(orig), url_safe, 0);
  orig_decoded = grpc_base64_decode(b64, !url_safe);
  GPR_ASSERT(GPR_SLICE_IS_EMPTY(orig_decoded));
  gpr_free(b64);
  gpr_slice_unref(orig_decoded);

  b64 = grpc_base64_encode(orig, sizeof(orig), !url_safe, 0);
  orig_decoded = grpc_base64_decode(b64, url_safe);
  GPR_ASSERT(GPR_SLICE_IS_EMPTY(orig_decoded));
  gpr_free(b64);
  gpr_slice_unref(orig_decoded);
}
Ejemplo n.º 7
0
static BIGNUM *bignum_from_base64(const char *b64) {
  BIGNUM *result = NULL;
  gpr_slice bin;

  if (b64 == NULL) return NULL;
  bin = grpc_base64_decode(b64, 1);
  if (GPR_SLICE_IS_EMPTY(bin)) {
    gpr_log(GPR_ERROR, "Invalid base64 for big num.");
    return NULL;
  }
  result = BN_bin2bn(GPR_SLICE_START_PTR(bin), GPR_SLICE_LENGTH(bin), NULL);
  gpr_slice_unref(bin);
  return result;
}
Ejemplo n.º 8
0
static void init_default_pem_root_certs(void) {
  /* First try to load the roots from the environment. */
  char *default_root_certs_path =
      gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR);
  if (default_root_certs_path == NULL) {
    default_pem_root_certs = gpr_empty_slice();
  } else {
    default_pem_root_certs = gpr_load_file(default_root_certs_path, 0, NULL);
    gpr_free(default_root_certs_path);
  }

  /* Fall back to installed certs if needed. */
  if (GPR_SLICE_IS_EMPTY(default_pem_root_certs)) {
    default_pem_root_certs = gpr_load_file(installed_roots_path, 0, NULL);
  }
}
Ejemplo n.º 9
0
static void corrupt_jwt_sig(char *jwt) {
  gpr_slice sig;
  char *bad_b64_sig;
  uint8_t *sig_bytes;
  char *last_dot = strrchr(jwt, '.');
  GPR_ASSERT(last_dot != NULL);
  sig = grpc_base64_decode(last_dot + 1, 1);
  GPR_ASSERT(!GPR_SLICE_IS_EMPTY(sig));
  sig_bytes = GPR_SLICE_START_PTR(sig);
  (*sig_bytes)++; /* Corrupt first byte. */
  bad_b64_sig =
      grpc_base64_encode(GPR_SLICE_START_PTR(sig), GPR_SLICE_LENGTH(sig), 1, 0);
  memcpy(last_dot + 1, bad_b64_sig, strlen(bad_b64_sig));
  gpr_free(bad_b64_sig);
  gpr_slice_unref(sig);
}
Ejemplo n.º 10
0
void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx,
                              grpc_jwt_verifier *verifier,
                              grpc_pollset *pollset, const char *jwt,
                              const char *audience,
                              grpc_jwt_verification_done_cb cb,
                              void *user_data) {
  const char *dot = NULL;
  grpc_json *json;
  jose_header *header = NULL;
  grpc_jwt_claims *claims = NULL;
  gpr_slice header_buffer;
  gpr_slice claims_buffer;
  gpr_slice signature;
  size_t signed_jwt_len;
  const char *cur = jwt;

  GPR_ASSERT(verifier != NULL && jwt != NULL && audience != NULL && cb != NULL);
  dot = strchr(cur, '.');
  if (dot == NULL) goto error;
  json = parse_json_part_from_jwt(cur, (size_t)(dot - cur), &header_buffer);
  if (json == NULL) goto error;
  header = jose_header_from_json(json, header_buffer);
  if (header == NULL) goto error;

  cur = dot + 1;
  dot = strchr(cur, '.');
  if (dot == NULL) goto error;
  json = parse_json_part_from_jwt(cur, (size_t)(dot - cur), &claims_buffer);
  if (json == NULL) goto error;
  claims = grpc_jwt_claims_from_json(json, claims_buffer);
  if (claims == NULL) goto error;

  signed_jwt_len = (size_t)(dot - jwt);
  cur = dot + 1;
  signature = grpc_base64_decode(cur, 1);
  if (GPR_SLICE_IS_EMPTY(signature)) goto error;
  retrieve_key_and_verify(
      exec_ctx,
      verifier_cb_ctx_create(verifier, pollset, header, claims, audience,
                             signature, jwt, signed_jwt_len, user_data, cb));
  return;

error:
  if (header != NULL) jose_header_destroy(header);
  if (claims != NULL) grpc_jwt_claims_destroy(claims);
  cb(user_data, GRPC_JWT_VERIFIER_BAD_FORMAT, NULL);
}
Ejemplo n.º 11
0
static void test_default_ssl_roots(void) {
  const char *roots_for_env_var = "roots for env var";

  char *roots_env_var_file_path;
  FILE *roots_env_var_file =
      gpr_tmpfile("test_roots_for_env_var", &roots_env_var_file_path);
  fwrite(roots_for_env_var, 1, strlen(roots_for_env_var), roots_env_var_file);
  fclose(roots_env_var_file);

  /* First let's get the root through the override: set the env to an invalid
     value. */
  gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, "");
  grpc_set_ssl_roots_override_callback(override_roots_success);
  gpr_slice roots = grpc_get_default_ssl_roots_for_testing();
  char *roots_contents = gpr_dump_slice(roots, GPR_DUMP_ASCII);
  gpr_slice_unref(roots);
  GPR_ASSERT(strcmp(roots_contents, roots_for_override_api) == 0);
  gpr_free(roots_contents);

  /* Now let's set the env var: We should get the contents pointed value
     instead. */
  gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_env_var_file_path);
  roots = grpc_get_default_ssl_roots_for_testing();
  roots_contents = gpr_dump_slice(roots, GPR_DUMP_ASCII);
  gpr_slice_unref(roots);
  GPR_ASSERT(strcmp(roots_contents, roots_for_env_var) == 0);
  gpr_free(roots_contents);

  /* Now reset the env var. We should fall back to the value overridden using
     the api. */
  gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, "");
  roots = grpc_get_default_ssl_roots_for_testing();
  roots_contents = gpr_dump_slice(roots, GPR_DUMP_ASCII);
  gpr_slice_unref(roots);
  GPR_ASSERT(strcmp(roots_contents, roots_for_override_api) == 0);
  gpr_free(roots_contents);

  /* Now setup a permanent failure for the overridden roots and we should get
     an empty slice. */
  grpc_set_ssl_roots_override_callback(override_roots_permanent_failure);
  roots = grpc_get_default_ssl_roots_for_testing();
  GPR_ASSERT(GPR_SLICE_IS_EMPTY(roots));

  /* Cleanup. */
  remove(roots_env_var_file_path);
  gpr_free(roots_env_var_file_path);
}
Ejemplo n.º 12
0
static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
                                           gpr_slice *buffer) {
  grpc_json *json;

  *buffer = grpc_base64_decode_with_len(str, len, 1);
  if (GPR_SLICE_IS_EMPTY(*buffer)) {
    gpr_log(GPR_ERROR, "Invalid base64.");
    return NULL;
  }
  json = grpc_json_parse_string_with_len((char *)GPR_SLICE_START_PTR(*buffer),
                                         GPR_SLICE_LENGTH(*buffer));
  if (json == NULL) {
    gpr_slice_unref(*buffer);
    gpr_log(GPR_ERROR, "JSON parsing error.");
  }
  return json;
}
Ejemplo n.º 13
0
static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
                                           char **scratchpad) {
  char *b64;
  char *decoded;
  grpc_json *json;
  gpr_slice slice;
  b64 = gpr_malloc(len + 1);
  strncpy(b64, str, len);
  b64[len] = '\0';
  slice = grpc_base64_decode(b64, 1);
  GPR_ASSERT(!GPR_SLICE_IS_EMPTY(slice));
  decoded = gpr_malloc(GPR_SLICE_LENGTH(slice) + 1);
  strncpy(decoded, (const char *)GPR_SLICE_START_PTR(slice),
          GPR_SLICE_LENGTH(slice));
  decoded[GPR_SLICE_LENGTH(slice)] = '\0';
  json = grpc_json_parse_string(decoded);
  gpr_free(b64);
  *scratchpad = decoded;
  gpr_slice_unref(slice);
  return json;
}
Ejemplo n.º 14
0
static void check_jwt_signature(const char *b64_signature, RSA *rsa_key,
                                const char *signed_data,
                                size_t signed_data_size) {
  EVP_MD_CTX *md_ctx = EVP_MD_CTX_create();
  EVP_PKEY *key = EVP_PKEY_new();

  gpr_slice sig = grpc_base64_decode(b64_signature, 1);
  GPR_ASSERT(!GPR_SLICE_IS_EMPTY(sig));
  GPR_ASSERT(GPR_SLICE_LENGTH(sig) == 128);

  GPR_ASSERT(md_ctx != NULL);
  GPR_ASSERT(key != NULL);
  EVP_PKEY_set1_RSA(key, rsa_key);

  GPR_ASSERT(EVP_DigestVerifyInit(md_ctx, NULL, EVP_sha256(), NULL, key) == 1);
  GPR_ASSERT(EVP_DigestVerifyUpdate(md_ctx, signed_data, signed_data_size) ==
             1);
  GPR_ASSERT(EVP_DigestVerifyFinal(md_ctx, GPR_SLICE_START_PTR(sig),
                                   GPR_SLICE_LENGTH(sig)) == 1);

  gpr_slice_unref(sig);
  if (key != NULL) EVP_PKEY_free(key);
  if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx);
}