aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Julien Boeuf <jboeuf@google.com>2016-01-28 17:04:42 -0800
committerGravatar Julien Boeuf <jboeuf@google.com>2016-01-28 17:04:42 -0800
commitaaebf7ae7467a43ba69f27943069613f23808461 (patch)
treeb5f08e32df8dcfa976bcf2f21862cf307993e247
parent564b9155031a0d00e3bd2da2360e617cfbf8342e (diff)
Changing the API to use a callback mechanism.
This is the agreed-upon solution.
-rw-r--r--include/grpc/grpc_security.h27
-rw-r--r--src/core/security/security_connector.c20
-rw-r--r--test/core/security/security_connector_test.c23
3 files changed, 55 insertions, 15 deletions
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index ff16e92c35..e280bf5391 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -143,14 +143,29 @@ grpc_channel_credentials *grpc_google_default_credentials_create(void);
#define GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR \
"GRPC_DEFAULT_SSL_ROOTS_FILE_PATH"
-/* Overrides the default TLS/SSL roots.
- The roots must be encoded as PEM and NULL-terminated.
+/* Results for the SSL roots override callback. */
+typedef enum {
+ GRPC_SSL_ROOTS_OVERRIDE_OK,
+ GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY, /* Do not try fallback options. */
+ GRPC_SSL_ROOTS_OVERRIDE_FAIL
+} grpc_ssl_roots_override_result;
+
+
+/* Callback for getting the SSL roots override from the application.
+ In case of success, *pem_roots_certs must be set to a NULL terminated string
+ containing the list of PEM encoded root certificates. The ownership is passed
+ to the core and freed (laster by the core) with gpr_free.
+ If this function fails and GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment is
+ set to a valid path, it will override the roots specified this func */
+typedef grpc_ssl_roots_override_result (*grpc_ssl_roots_override_callback)(
+ char **pem_root_certs);
+
+/* Setup a callback to override the default TLS/SSL roots.
This function is not thread-safe and must be called at initialization time
before any ssl credentials are created to have the desired side effect.
- It also does not do any checks about the validity of the encoding.
- If the GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment is set to a valid path,
- it will override the roots specified in this function. */
-void grpc_override_ssl_default_roots(const char *roots_pem);
+ If GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment is set to a valid path, the
+ callback will not be called. */
+void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb);
/* Object that holds a private key / certificate chain pair in PEM format. */
typedef struct {
diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c
index 8a67243a18..654866fd4e 100644
--- a/src/core/security/security_connector.c
+++ b/src/core/security/security_connector.c
@@ -63,10 +63,10 @@ static const char *installed_roots_path =
/* -- Overridden default roots. -- */
-static gpr_slice overridden_default_roots;
+static grpc_ssl_roots_override_callback ssl_roots_override_cb = NULL;
-void grpc_override_ssl_default_roots(const char *roots_pem) {
- overridden_default_roots = gpr_slice_from_copied_string(roots_pem);
+void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) {
+ ssl_roots_override_cb = cb;
}
/* -- Cipher suites. -- */
@@ -615,13 +615,19 @@ static gpr_slice compute_default_pem_root_certs_once(void) {
}
/* Try overridden roots path if needed. */
- if (GPR_SLICE_IS_EMPTY(result) &&
- !GPR_SLICE_IS_EMPTY(overridden_default_roots)) {
- result = gpr_slice_ref(overridden_default_roots);
+ 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)) {
+ 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;
diff --git a/test/core/security/security_connector_test.c b/test/core/security/security_connector_test.c
index bfebf209df..d9322f0257 100644
--- a/test/core/security/security_connector_test.c
+++ b/test/core/security/security_connector_test.c
@@ -47,6 +47,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
#include <grpc/support/useful.h>
static int check_transport_security_type(const grpc_auth_context *ctx) {
@@ -300,8 +301,20 @@ static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context(
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
+static const char *roots_for_override_api = "roots for override api";
+
+static grpc_ssl_roots_override_result override_roots_success(
+ char **pem_root_certs) {
+ *pem_root_certs = gpr_strdup(roots_for_override_api);
+ return GRPC_SSL_ROOTS_OVERRIDE_OK;
+}
+
+static grpc_ssl_roots_override_result override_roots_permanent_failure(
+ char **pem_root_certs) {
+ return GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY;
+}
+
static void test_default_ssl_roots(void) {
- const char *roots_for_override_api = "roots for override api";
const char *roots_for_env_var = "roots for env var";
char *roots_env_var_file_path;
@@ -311,7 +324,7 @@ static void test_default_ssl_roots(void) {
fclose(roots_env_var_file);
/* First let's get the root through the override (no env are set). */
- grpc_override_ssl_default_roots(roots_for_override_api);
+ 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);
@@ -336,6 +349,12 @@ static void test_default_ssl_roots(void) {
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);