static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context(
    void) {
  tsi_peer peer;
  grpc_auth_context *ctx;
  const char *expected_cn = "cn1";
  const char *expected_sans[] = {"san1", "san2", "san3"};
  size_t i;
  GPR_ASSERT(tsi_construct_peer(4 + GPR_ARRAY_SIZE(expected_sans), &peer) ==
             TSI_OK);
  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                 TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
                 &peer.properties[0]) == TSI_OK);
  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                 "foo", "bar", &peer.properties[1]) == TSI_OK);
  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                 TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, expected_cn,
                 &peer.properties[2]) == TSI_OK);
  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                 "chapi", "chapo", &peer.properties[3]) == TSI_OK);
  for (i = 0; i < GPR_ARRAY_SIZE(expected_sans); i++) {
    GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                   TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY,
                   expected_sans[i], &peer.properties[4 + i]) == TSI_OK);
  }
  ctx = tsi_ssl_peer_to_auth_context(&peer);
  GPR_ASSERT(ctx != NULL);
  GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
  GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans,
                            GPR_ARRAY_SIZE(expected_sans)));
  GPR_ASSERT(check_transport_security_type(ctx));
  GPR_ASSERT(check_x509_cn(ctx, expected_cn));

  tsi_peer_destruct(&peer);
  GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
Exemple #2
0
static void fake_check_peer(grpc_exec_ctx *exec_ctx,
                            grpc_security_connector *sc, tsi_peer peer,
                            grpc_security_peer_check_cb cb, void *user_data) {
  const char *prop_name;
  grpc_security_status status = GRPC_SECURITY_OK;
  grpc_auth_context *auth_context = NULL;
  if (peer.property_count != 1) {
    gpr_log(GPR_ERROR, "Fake peers should only have 1 property.");
    status = GRPC_SECURITY_ERROR;
    goto end;
  }
  prop_name = peer.properties[0].name;
  if (prop_name == NULL ||
      strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) {
    gpr_log(GPR_ERROR, "Unexpected property in fake peer: %s.",
            prop_name == NULL ? "<EMPTY>" : prop_name);
    status = GRPC_SECURITY_ERROR;
    goto end;
  }
  if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE,
              peer.properties[0].value.length)) {
    gpr_log(GPR_ERROR, "Invalid value for cert type property.");
    status = GRPC_SECURITY_ERROR;
    goto end;
  }
  auth_context = grpc_auth_context_create(NULL);
  grpc_auth_context_add_cstring_property(
      auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
      GRPC_FAKE_TRANSPORT_SECURITY_TYPE);

end:
  cb(exec_ctx, user_data, status, auth_context);
  grpc_auth_context_unref(auth_context);
  tsi_peer_destruct(&peer);
}
static void test_cn_only_ssl_peer_to_auth_context(void) {
  tsi_peer peer;
  tsi_peer rpeer;
  grpc_auth_context *ctx;
  const char *expected_cn = "cn1";
  const char *expected_pem_cert = "pem_cert1";
  GPR_ASSERT(tsi_construct_peer(3, &peer) == TSI_OK);
  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                 TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
                 &peer.properties[0]) == TSI_OK);
  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                 TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, expected_cn,
                 &peer.properties[1]) == TSI_OK);
  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                 TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert,
                 &peer.properties[2]) == TSI_OK);
  ctx = tsi_ssl_peer_to_auth_context(&peer);
  GPR_ASSERT(ctx != NULL);
  GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
  GPR_ASSERT(check_identity(ctx, GRPC_X509_CN_PROPERTY_NAME, &expected_cn, 1));
  GPR_ASSERT(check_transport_security_type(ctx));
  GPR_ASSERT(check_x509_cn(ctx, expected_cn));
  GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert));

  rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
  GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));

  tsi_shallow_peer_destruct(&rpeer);
  tsi_peer_destruct(&peer);
  GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
Exemple #4
0
/* Gets information about the peer's X509 cert as a tsi_peer object. */
static tsi_result peer_from_x509(X509* cert, int include_certificate_type,
                                 tsi_peer* peer) {
  /* TODO(jboeuf): Maybe add more properties. */
  GENERAL_NAMES* subject_alt_names =
      X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0);
  int subject_alt_name_count =
      (subject_alt_names != NULL) ? sk_GENERAL_NAME_num(subject_alt_names) : 0;
  size_t property_count = (include_certificate_type ? 1 : 0) +
                          1 /* common name */ + subject_alt_name_count;
  tsi_result result = tsi_construct_peer(property_count, peer);
  if (result != TSI_OK) return result;
  do {
    if (include_certificate_type) {
      result = tsi_construct_string_peer_property_from_cstring(
          TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
          &peer->properties[0]);
      if (result != TSI_OK) break;
    }
    result = peer_property_from_x509_common_name(
        cert, &peer->properties[include_certificate_type ? 1 : 0]);
    if (result != TSI_OK) break;

    if (subject_alt_name_count != 0) {
      result = add_subject_alt_names_properties_to_peer(peer, subject_alt_names,
                                                        subject_alt_name_count);
      if (result != TSI_OK) break;
    }
  } while (0);

  if (subject_alt_names != NULL) {
    sk_GENERAL_NAME_pop_free(subject_alt_names, GENERAL_NAME_free);
  }
  if (result != TSI_OK) tsi_peer_destruct(peer);
  return result;
}
static void test_cn_and_one_san_ssl_peer_to_auth_context(void) {
  tsi_peer peer;
  grpc_auth_context *ctx;
  const char *expected_cn = "cn1";
  const char *expected_san = "san1";
  GPR_ASSERT(tsi_construct_peer(3, &peer) == TSI_OK);
  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                 TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
                 &peer.properties[0]) == TSI_OK);
  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                 TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, expected_cn,
                 &peer.properties[1]) == TSI_OK);
  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                 TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, expected_san,
                 &peer.properties[2]) == TSI_OK);
  ctx = tsi_ssl_peer_to_auth_context(&peer);
  GPR_ASSERT(ctx != NULL);
  GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
  GPR_ASSERT(
      check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, &expected_san, 1));
  GPR_ASSERT(check_transport_security_type(ctx));
  GPR_ASSERT(check_x509_cn(ctx, expected_cn));

  tsi_peer_destruct(&peer);
  GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
Exemple #6
0
static grpc_security_status fake_check_peer(grpc_security_context *ctx,
                                            tsi_peer peer,
                                            grpc_security_check_cb cb,
                                            void *user_data) {
  const char *prop_name;
  grpc_security_status status = GRPC_SECURITY_OK;
  if (peer.property_count != 1) {
    gpr_log(GPR_ERROR, "Fake peers should only have 1 property.");
    status = GRPC_SECURITY_ERROR;
    goto end;
  }
  prop_name = peer.properties[0].name;
  if (prop_name == NULL ||
      strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) {
    gpr_log(GPR_ERROR, "Unexpected property in fake peer: %s.",
            prop_name == NULL ? "<EMPTY>" : prop_name);
    status = GRPC_SECURITY_ERROR;
    goto end;
  }
  if (peer.properties[0].type != TSI_PEER_PROPERTY_TYPE_STRING) {
    gpr_log(GPR_ERROR, "Invalid type of cert type property.");
    status = GRPC_SECURITY_ERROR;
    goto end;
  }
  if (strncmp(peer.properties[0].value.string.data, TSI_FAKE_CERTIFICATE_TYPE,
              peer.properties[0].value.string.length)) {
    gpr_log(GPR_ERROR, "Invalid value for cert type property.");
    status = GRPC_SECURITY_ERROR;
    goto end;
  }
end:
  tsi_peer_destruct(&peer);
  return status;
}
Exemple #7
0
static grpc_security_status fake_check_peer(grpc_security_connector *sc,
                                            tsi_peer peer,
                                            grpc_security_check_cb cb,
                                            void *user_data) {
  const char *prop_name;
  grpc_security_status status = GRPC_SECURITY_OK;
  if (peer.property_count != 1) {
    gpr_log(GPR_ERROR, "Fake peers should only have 1 property.");
    status = GRPC_SECURITY_ERROR;
    goto end;
  }
  prop_name = peer.properties[0].name;
  if (prop_name == NULL ||
      strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) {
    gpr_log(GPR_ERROR, "Unexpected property in fake peer: %s.",
            prop_name == NULL ? "<EMPTY>" : prop_name);
    status = GRPC_SECURITY_ERROR;
    goto end;
  }
  if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE,
              peer.properties[0].value.length)) {
    gpr_log(GPR_ERROR, "Invalid value for cert type property.");
    status = GRPC_SECURITY_ERROR;
    goto end;
  }
  GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
  sc->auth_context = grpc_auth_context_create(NULL, 1);
  sc->auth_context->properties[0] = grpc_auth_property_init_from_cstring(
      GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
      GRPC_FAKE_TRANSPORT_SECURITY_TYPE);

end:
  tsi_peer_destruct(&peer);
  return status;
}
Exemple #8
0
static grpc_security_status ssl_server_check_peer(grpc_security_connector *sc,
                                                  tsi_peer peer,
                                                  grpc_security_check_cb cb,
                                                  void *user_data) {
  grpc_security_status status = ssl_check_peer(sc, NULL, &peer);
  tsi_peer_destruct(&peer);
  return status;
}
Exemple #9
0
grpc_security_status grpc_security_connector_check_peer(
    grpc_security_connector *sc, tsi_peer peer, grpc_security_check_cb cb,
    void *user_data) {
  if (sc == NULL) {
    tsi_peer_destruct(&peer);
    return GRPC_SECURITY_ERROR;
  }
  return sc->vtable->check_peer(sc, peer, cb, user_data);
}
Exemple #10
0
grpc_security_status grpc_security_context_check_peer(
    grpc_security_context *ctx, tsi_peer peer, grpc_security_check_cb cb,
    void *user_data) {
  if (ctx == NULL) {
    tsi_peer_destruct(&peer);
    return GRPC_SECURITY_ERROR;
  }
  return ctx->vtable->check_peer(ctx, peer, cb, user_data);
}
Exemple #11
0
static grpc_security_status ssl_server_check_peer(grpc_security_context *ctx,
                                                  tsi_peer peer,
                                                  grpc_security_check_cb cb,
                                                  void *user_data) {
  /* TODO(jboeuf): Find a way to expose the peer to the authorization layer. */
  grpc_security_status status = ssl_check_peer(NULL, &peer);
  tsi_peer_destruct(&peer);
  return status;
}
Exemple #12
0
static void ssl_server_check_peer(grpc_exec_ctx *exec_ctx,
                                  grpc_security_connector *sc, tsi_peer peer,
                                  grpc_security_peer_check_cb cb,
                                  void *user_data) {
  grpc_auth_context *auth_context = NULL;
  grpc_security_status status = ssl_check_peer(sc, NULL, &peer, &auth_context);
  tsi_peer_destruct(&peer);
  cb(exec_ctx, user_data, status, auth_context);
  grpc_auth_context_unref(auth_context);
}
Exemple #13
0
void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx,
                                        grpc_security_connector *sc,
                                        tsi_peer peer,
                                        grpc_security_peer_check_cb cb,
                                        void *user_data) {
  if (sc == NULL) {
    cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL);
    tsi_peer_destruct(&peer);
  } else {
    sc->vtable->check_peer(exec_ctx, sc, peer, cb, user_data);
  }
}
Exemple #14
0
static void ssl_channel_destroy(grpc_security_context *ctx) {
  grpc_ssl_channel_security_context *c =
      (grpc_ssl_channel_security_context *)ctx;
  grpc_credentials_unref(c->base.request_metadata_creds);
  if (c->handshaker_factory != NULL) {
    tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
  }
  if (c->target_name != NULL) gpr_free(c->target_name);
  if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name);
  tsi_peer_destruct(&c->peer);
  gpr_free(ctx);
}
Exemple #15
0
static void ssl_channel_destroy(grpc_security_connector *sc) {
  grpc_ssl_channel_security_connector *c =
      (grpc_ssl_channel_security_connector *)sc;
  grpc_credentials_unref(c->base.request_metadata_creds);
  if (c->handshaker_factory != NULL) {
    tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
  }
  if (c->target_name != NULL) gpr_free(c->target_name);
  if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name);
  tsi_peer_destruct(&c->peer);
  GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
  gpr_free(sc);
}
static void test_unauthenticated_ssl_peer(void) {
  tsi_peer peer;
  grpc_auth_context *ctx;
  GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK);
  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                 TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
                 &peer.properties[0]) == TSI_OK);
  ctx = tsi_ssl_peer_to_auth_context(&peer);
  GPR_ASSERT(ctx != NULL);
  GPR_ASSERT(!grpc_auth_context_peer_is_authenticated(ctx));
  GPR_ASSERT(check_transport_security_type(ctx));

  tsi_peer_destruct(&peer);
  GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
static void test_peer_matches_name(void) {
  size_t i = 0;
  for (i = 0; i < GPR_ARRAY_SIZE(cert_name_test_entries); i++) {
    const cert_name_test_entry *entry = &cert_name_test_entries[i];
    tsi_peer peer = peer_from_cert_name_test_entry(entry);
    int result = tsi_ssl_peer_matches_name(&peer, entry->host_name);
    if (result != entry->expected) {
      char *entry_str = cert_name_test_entry_to_string(entry);
      gpr_log(GPR_ERROR, "%s", entry_str);
      gpr_free(entry_str);
      GPR_ASSERT(0); /* Unexpected result. */
    }
    tsi_peer_destruct(&peer);
  }
}
Exemple #18
0
static grpc_security_status ssl_channel_check_peer(grpc_security_connector *sc,
                                                   tsi_peer peer,
                                                   grpc_security_check_cb cb,
                                                   void *user_data) {
  grpc_ssl_channel_security_connector *c =
      (grpc_ssl_channel_security_connector *)sc;
  grpc_security_status status;
  tsi_peer_destruct(&c->peer);
  c->peer = peer;
  status = ssl_check_peer(sc, c->overridden_target_name != NULL
                                  ? c->overridden_target_name
                                  : c->target_name,
                          &peer);
  return status;
}
Exemple #19
0
static void ssl_channel_check_peer(grpc_exec_ctx *exec_ctx,
                                   grpc_security_connector *sc, tsi_peer peer,
                                   grpc_security_peer_check_cb cb,
                                   void *user_data) {
  grpc_ssl_channel_security_connector *c =
      (grpc_ssl_channel_security_connector *)sc;
  grpc_security_status status;
  grpc_auth_context *auth_context = NULL;
  status = ssl_check_peer(sc, c->overridden_target_name != NULL
                                  ? c->overridden_target_name
                                  : c->target_name,
                          &peer, &auth_context);
  cb(exec_ctx, user_data, status, auth_context);
  grpc_auth_context_unref(auth_context);
  tsi_peer_destruct(&peer);
}
static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx,
                                   grpc_security_connector *sc, tsi_peer peer,
                                   grpc_security_peer_check_cb cb,
                                   void *user_data) {
  grpc_httpcli_ssl_channel_security_connector *c =
      (grpc_httpcli_ssl_channel_security_connector *)sc;
  grpc_security_status status = GRPC_SECURITY_OK;

  /* Check the peer name. */
  if (c->secure_peer_name != NULL &&
      !tsi_ssl_peer_matches_name(&peer, c->secure_peer_name)) {
    gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate",
            c->secure_peer_name);
    status = GRPC_SECURITY_ERROR;
  }
  cb(exec_ctx, user_data, status, NULL);
  tsi_peer_destruct(&peer);
}
static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx,
                                   grpc_security_connector *sc, tsi_peer peer,
                                   grpc_auth_context **auth_context,
                                   grpc_closure *on_peer_checked) {
  grpc_httpcli_ssl_channel_security_connector *c =
      (grpc_httpcli_ssl_channel_security_connector *)sc;
  grpc_error *error = GRPC_ERROR_NONE;

  /* Check the peer name. */
  if (c->secure_peer_name != NULL &&
      !tsi_ssl_peer_matches_name(&peer, c->secure_peer_name)) {
    char *msg;
    gpr_asprintf(&msg, "Peer name %s is not in peer certificate",
                 c->secure_peer_name);
    error = GRPC_ERROR_CREATE(msg);
    gpr_free(msg);
  }
  grpc_exec_ctx_sched(exec_ctx, on_peer_checked, error, NULL);
  tsi_peer_destruct(&peer);
}