Support SSL server certificate reloading.

pull/12644/head
Justin Burke 8 years ago
parent bf3f4be8f3
commit c1d354d7f2
  1. 6
      grpc.def
  2. 74
      include/grpc/grpc_security.h
  3. 7
      include/grpc/grpc_security_constants.h
  4. 156
      src/core/lib/security/credentials/ssl/ssl_credentials.cc
  5. 12
      src/core/lib/security/credentials/ssl/ssl_credentials.h
  6. 251
      src/core/lib/security/transport/security_connector.cc
  7. 4
      src/core/lib/security/transport/security_connector.h
  8. 12
      src/ruby/ext/grpc/rb_grpc_imports.generated.c
  9. 18
      src/ruby/ext/grpc/rb_grpc_imports.generated.h

@ -132,8 +132,14 @@ EXPORTS
grpc_metadata_credentials_create_from_plugin
grpc_secure_channel_create
grpc_server_credentials_release
grpc_ssl_server_certificate_config_create
grpc_ssl_server_certificate_config_destroy
grpc_ssl_server_credentials_create
grpc_ssl_server_credentials_create_ex
grpc_ssl_server_credentials_create_options_using_config
grpc_ssl_server_credentials_create_options_using_config_fetcher
grpc_ssl_server_credentials_options_destroy
grpc_ssl_server_credentials_create_with_options
grpc_server_add_secure_http2_port
grpc_call_set_credentials
grpc_server_credentials_set_auth_metadata_processor

@ -316,6 +316,43 @@ typedef struct grpc_server_credentials grpc_server_credentials;
*/
GRPCAPI void grpc_server_credentials_release(grpc_server_credentials *creds);
/** Server certificate config object holds the server's public certificates and
associated private keys, as well as any CA certificates needed for client
certificate validation (if applicable). Create using
grpc_ssl_server_certificate_config_create(). */
typedef struct grpc_ssl_server_certificate_config
grpc_ssl_server_certificate_config;
/** Creates a grpc_ssl_server_certificate_config object.
- pem_roots_cert is the NULL-terminated string containing the PEM encoding of
the client root certificates. This parameter may be NULL if the server does
not want the client to be authenticated with SSL.
- pem_key_cert_pairs is an array private key / certificate chains of the
server. This parameter cannot be NULL.
- num_key_cert_pairs indicates the number of items in the private_key_files
and cert_chain_files parameters. It must be at least 1.
- It is the caller's responsibility to free this object via
grpc_ssl_server_certificate_config_destroy(). */
GRPCAPI grpc_ssl_server_certificate_config *
grpc_ssl_server_certificate_config_create(
const char *pem_root_certs,
const grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs);
/** Destroys a grpc_ssl_server_certificate_config object. */
GRPCAPI void grpc_ssl_server_certificate_config_destroy(
grpc_ssl_server_certificate_config *config);
/** Callback to retrieve updated SSL server certificates, private keys, and
trusted CAs (for client authentication).
- user_data parameter, if not NULL, contains opaque data to be used by the
callback.
- Use grpc_ssl_server_certificate_config_create to create the config.
- The caller assumes ownership of the config. */
typedef grpc_ssl_certificate_config_reload_status (
*grpc_ssl_server_certificate_config_callback)(
void *user_data, grpc_ssl_server_certificate_config **config);
/** Deprecated in favor of grpc_ssl_server_credentials_create_ex.
Creates an SSL server_credentials object.
- pem_roots_cert is the NULL-terminated string containing the PEM encoding of
@ -332,7 +369,8 @@ GRPCAPI grpc_server_credentials *grpc_ssl_server_credentials_create(
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs, int force_client_auth, void *reserved);
/** Same as grpc_ssl_server_credentials_create method except uses
/** Deprecated in favor of grpc_ssl_server_credentials_create_with_options.
Same as grpc_ssl_server_credentials_create method except uses
grpc_ssl_client_certificate_request_type enum to support more ways to
authenticate client cerificates.*/
GRPCAPI grpc_server_credentials *grpc_ssl_server_credentials_create_ex(
@ -341,6 +379,40 @@ GRPCAPI grpc_server_credentials *grpc_ssl_server_credentials_create_ex(
grpc_ssl_client_certificate_request_type client_certificate_request,
void *reserved);
typedef struct grpc_ssl_server_credentials_options
grpc_ssl_server_credentials_options;
/** Creates an options object using a certificate config. Use this method when
the certificates and keys of the SSL server will not change during the
server's lifetime.
- Takes ownership of the certificate_config parameter. */
GRPCAPI grpc_ssl_server_credentials_options *
grpc_ssl_server_credentials_create_options_using_config(
grpc_ssl_client_certificate_request_type client_certificate_request,
grpc_ssl_server_certificate_config *certificate_config);
/** Creates an options object using a certificate config fetcher. Use this
method to reload the certificates and keys of the SSL server without
interrupting the operation of the server. Initial certificate config will be
fetched during server initialization.
- user_data parameter, if not NULL, contains opaque data which will be passed
to the fetcher (see definition of
grpc_ssl_server_certificate_config_callback). */
GRPCAPI grpc_ssl_server_credentials_options *
grpc_ssl_server_credentials_create_options_using_config_fetcher(
grpc_ssl_client_certificate_request_type client_certificate_request,
grpc_ssl_server_certificate_config_callback cb, void *user_data);
/** Destroys a grpc_ssl_server_credentials_options object. */
GRPCAPI void grpc_ssl_server_credentials_options_destroy(
grpc_ssl_server_credentials_options *options);
/** Creates an SSL server_credentials object using the provided options struct.
- Takes ownership of the options parameter. */
GRPCAPI grpc_server_credentials *
grpc_ssl_server_credentials_create_with_options(
grpc_ssl_server_credentials_options *options);
/** --- Server-side secure ports. --- */
/** Add a HTTP2 over an encrypted link over tcp listener.

@ -48,6 +48,13 @@ typedef enum {
GRPC_SSL_ROOTS_OVERRIDE_FAIL
} grpc_ssl_roots_override_result;
/** Callback results for dynamically loading a SSL certificate config. */
typedef enum {
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED,
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW,
GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL
} grpc_ssl_certificate_config_reload_status;
typedef enum {
/** Server does not request client certificate. A client can present a self
signed or signed certificates if it wishes to do so and they would be

@ -119,6 +119,12 @@ grpc_channel_credentials *grpc_ssl_credentials_create(
// SSL Server Credentials.
//
struct grpc_ssl_server_credentials_options {
grpc_ssl_client_certificate_request_type client_certificate_request;
grpc_ssl_server_certificate_config *certificate_config;
grpc_ssl_server_certificate_config_fetcher *certificate_config_fetcher;
};
static void ssl_server_destruct(grpc_exec_ctx *exec_ctx,
grpc_server_credentials *creds) {
grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
@ -130,9 +136,7 @@ static void ssl_server_destruct(grpc_exec_ctx *exec_ctx,
static grpc_security_status ssl_server_create_security_connector(
grpc_exec_ctx *exec_ctx, grpc_server_credentials *creds,
grpc_server_security_connector **sc) {
grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
return grpc_ssl_server_security_connector_create(exec_ctx, creds, &c->config,
sc);
return grpc_ssl_server_security_connector_create(exec_ctx, creds, sc);
}
static grpc_server_credentials_vtable ssl_server_vtable = {
@ -170,6 +174,86 @@ static void ssl_build_server_config(
config->num_key_cert_pairs = num_key_cert_pairs;
}
grpc_ssl_server_certificate_config *grpc_ssl_server_certificate_config_create(
const char *pem_root_certs,
const grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs) {
grpc_ssl_server_certificate_config *config =
(grpc_ssl_server_certificate_config *)gpr_zalloc(
sizeof(grpc_ssl_server_certificate_config));
if (pem_root_certs != NULL) {
config->pem_root_certs = gpr_strdup(pem_root_certs);
}
if (num_key_cert_pairs > 0) {
GPR_ASSERT(pem_key_cert_pairs != NULL);
config->pem_key_cert_pairs = (grpc_ssl_pem_key_cert_pair *)gpr_zalloc(
num_key_cert_pairs * sizeof(grpc_ssl_pem_key_cert_pair));
}
config->num_key_cert_pairs = num_key_cert_pairs;
for (size_t i = 0; i < num_key_cert_pairs; i++) {
GPR_ASSERT(pem_key_cert_pairs[i].private_key != NULL);
GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != NULL);
config->pem_key_cert_pairs[i].cert_chain =
gpr_strdup(pem_key_cert_pairs[i].cert_chain);
config->pem_key_cert_pairs[i].private_key =
gpr_strdup(pem_key_cert_pairs[i].private_key);
}
return config;
}
void grpc_ssl_server_certificate_config_destroy(
grpc_ssl_server_certificate_config *config) {
if (config == NULL) return;
for (size_t i = 0; i < config->num_key_cert_pairs; i++) {
gpr_free((void *)config->pem_key_cert_pairs[i].private_key);
gpr_free((void *)config->pem_key_cert_pairs[i].cert_chain);
}
gpr_free(config->pem_key_cert_pairs);
gpr_free(config->pem_root_certs);
gpr_free(config);
}
grpc_ssl_server_credentials_options *
grpc_ssl_server_credentials_create_options_using_config(
grpc_ssl_client_certificate_request_type client_certificate_request,
grpc_ssl_server_certificate_config *config) {
grpc_ssl_server_credentials_options *options = NULL;
if (config == NULL) {
gpr_log(GPR_ERROR, "Certificate config must not be NULL.");
goto done;
}
options = (grpc_ssl_server_credentials_options *)gpr_zalloc(
sizeof(grpc_ssl_server_credentials_options));
options->client_certificate_request = client_certificate_request;
options->certificate_config = config;
done:
return options;
}
grpc_ssl_server_credentials_options *
grpc_ssl_server_credentials_create_options_using_config_fetcher(
grpc_ssl_client_certificate_request_type client_certificate_request,
grpc_ssl_server_certificate_config_callback cb, void *user_data) {
if (cb == NULL) {
gpr_log(GPR_ERROR, "Invalid certificate config callback parameter.");
return NULL;
}
grpc_ssl_server_certificate_config_fetcher *fetcher =
(grpc_ssl_server_certificate_config_fetcher *)gpr_zalloc(
sizeof(grpc_ssl_server_certificate_config_fetcher));
fetcher->cb = cb;
fetcher->user_data = user_data;
grpc_ssl_server_credentials_options *options =
(grpc_ssl_server_credentials_options *)gpr_zalloc(
sizeof(grpc_ssl_server_credentials_options));
options->client_certificate_request = client_certificate_request;
options->certificate_config_fetcher = fetcher;
return options;
}
grpc_server_credentials *grpc_ssl_server_credentials_create(
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs, int force_client_auth, void *reserved) {
@ -186,8 +270,6 @@ grpc_server_credentials *grpc_ssl_server_credentials_create_ex(
size_t num_key_cert_pairs,
grpc_ssl_client_certificate_request_type client_certificate_request,
void *reserved) {
grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)gpr_zalloc(
sizeof(grpc_ssl_server_credentials));
GRPC_API_TRACE(
"grpc_ssl_server_credentials_create_ex("
"pem_root_certs=%s, pem_key_cert_pairs=%p, num_key_cert_pairs=%lu, "
@ -195,11 +277,67 @@ grpc_server_credentials *grpc_ssl_server_credentials_create_ex(
5, (pem_root_certs, pem_key_cert_pairs, (unsigned long)num_key_cert_pairs,
client_certificate_request, reserved));
GPR_ASSERT(reserved == NULL);
grpc_ssl_server_certificate_config *cert_config =
grpc_ssl_server_certificate_config_create(
pem_root_certs, pem_key_cert_pairs, num_key_cert_pairs);
grpc_ssl_server_credentials_options *options =
grpc_ssl_server_credentials_create_options_using_config(
client_certificate_request, cert_config);
return grpc_ssl_server_credentials_create_with_options(options);
}
grpc_server_credentials *grpc_ssl_server_credentials_create_with_options(
grpc_ssl_server_credentials_options *options) {
grpc_server_credentials *retval = NULL;
grpc_ssl_server_credentials *c = NULL;
if (options == NULL) {
gpr_log(GPR_ERROR,
"Invalid options trying to create SSL server credentials.");
goto done;
}
if (options->certificate_config == NULL &&
options->certificate_config_fetcher == NULL) {
gpr_log(GPR_ERROR,
"SSL server credentials options must specify either "
"certificate config or fetcher.");
goto done;
} else if (options->certificate_config_fetcher != NULL &&
options->certificate_config_fetcher->cb == NULL) {
gpr_log(GPR_ERROR, "Certificate config fetcher callback must not be NULL.");
goto done;
}
c = (grpc_ssl_server_credentials *)gpr_zalloc(
sizeof(grpc_ssl_server_credentials));
c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
gpr_ref_init(&c->base.refcount, 1);
c->base.vtable = &ssl_server_vtable;
ssl_build_server_config(pem_root_certs, pem_key_cert_pairs,
num_key_cert_pairs, client_certificate_request,
&c->config);
return &c->base;
if (options->certificate_config_fetcher != NULL) {
c->config.client_certificate_request = options->client_certificate_request;
c->certificate_config_fetcher = *options->certificate_config_fetcher;
} else {
ssl_build_server_config(options->certificate_config->pem_root_certs,
options->certificate_config->pem_key_cert_pairs,
options->certificate_config->num_key_cert_pairs,
options->client_certificate_request, &c->config);
}
retval = &c->base;
done:
grpc_ssl_server_credentials_options_destroy(options);
return retval;
}
void grpc_ssl_server_credentials_options_destroy(
grpc_ssl_server_credentials_options *o) {
if (o == NULL) return;
gpr_free(o->certificate_config_fetcher);
grpc_ssl_server_certificate_config_destroy(o->certificate_config);
gpr_free(o);
}

@ -29,9 +29,21 @@ typedef struct {
grpc_ssl_config config;
} grpc_ssl_credentials;
struct grpc_ssl_server_certificate_config {
grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs;
size_t num_key_cert_pairs;
char *pem_root_certs;
};
typedef struct {
grpc_ssl_server_certificate_config_callback cb;
void *user_data;
} grpc_ssl_server_certificate_config_fetcher;
typedef struct {
grpc_server_credentials base;
grpc_ssl_server_config config;
grpc_ssl_server_certificate_config_fetcher certificate_config_fetcher;
} grpc_ssl_server_credentials;
tsi_ssl_pem_key_cert_pair *grpc_convert_grpc_to_tsi_cert_pairs(

@ -34,6 +34,7 @@
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
#include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
#include "src/core/lib/security/transport/lb_targets_info.h"
#include "src/core/lib/security/transport/secure_endpoint.h"
#include "src/core/lib/security/transport/security_handshaker.h"
@ -277,6 +278,30 @@ grpc_security_connector *grpc_security_connector_find_in_args(
return NULL;
}
static tsi_client_certificate_request_type
get_tsi_client_certificate_request_type(
grpc_ssl_client_certificate_request_type grpc_request_type) {
switch (grpc_request_type) {
case GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE:
return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
return TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
return TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY;
case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY;
default:
return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
}
}
/* -- Fake implementation. -- */
typedef struct {
@ -533,6 +558,15 @@ typedef struct {
tsi_ssl_server_handshaker_factory *server_handshaker_factory;
} grpc_ssl_server_security_connector;
static bool server_connector_has_cert_config_fetcher(
grpc_ssl_server_security_connector *c) {
GPR_ASSERT(c != NULL);
grpc_ssl_server_credentials *server_creds =
(grpc_ssl_server_credentials *)c->base.server_creds;
GPR_ASSERT(server_creds != NULL);
return server_creds->certificate_config_fetcher.cb != NULL;
}
static void ssl_channel_destroy(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc) {
grpc_ssl_channel_security_connector *c =
@ -573,7 +607,6 @@ static void ssl_channel_add_handshakers(grpc_exec_ctx *exec_ctx,
tsi_result_to_string(result));
return;
}
// Create handshakers.
grpc_handshake_manager_add(
handshake_mgr,
@ -581,12 +614,102 @@ static void ssl_channel_add_handshakers(grpc_exec_ctx *exec_ctx,
exec_ctx, tsi_create_adapter_handshaker(tsi_hs), &sc->base));
}
static const char **fill_alpn_protocol_strings(size_t *num_alpn_protocols) {
GPR_ASSERT(num_alpn_protocols != NULL);
*num_alpn_protocols = grpc_chttp2_num_alpn_versions();
const char **alpn_protocol_strings =
(const char **)gpr_malloc(sizeof(const char *) * (*num_alpn_protocols));
for (size_t i = 0; i < *num_alpn_protocols; i++) {
alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
}
return alpn_protocol_strings;
}
/* Attempts to replace the server_handshaker_factory with a new factory using
* the provided grpc_ssl_server_certificate_config. Should new factory creation
* fail, the existing factory will not be replaced. Returns true on success (new
* factory created). */
static bool try_replace_server_handshaker_factory(
grpc_ssl_server_security_connector *sc,
const grpc_ssl_server_certificate_config *config) {
if (config == NULL) {
gpr_log(GPR_ERROR,
"Server certificate config callback returned invalid (NULL) "
"config.");
return false;
}
gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config);
size_t num_alpn_protocols = 0;
const char **alpn_protocol_strings =
fill_alpn_protocol_strings(&num_alpn_protocols);
tsi_ssl_pem_key_cert_pair *cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs(
config->pem_key_cert_pairs, config->num_key_cert_pairs);
tsi_ssl_server_handshaker_factory *new_handshaker_factory = NULL;
grpc_ssl_server_credentials *server_creds =
(grpc_ssl_server_credentials *)sc->base.server_creds;
tsi_result result = tsi_create_ssl_server_handshaker_factory_ex(
cert_pairs, config->num_key_cert_pairs, config->pem_root_certs,
get_tsi_client_certificate_request_type(
server_creds->config.client_certificate_request),
ssl_cipher_suites(), alpn_protocol_strings, (uint16_t)num_alpn_protocols,
&new_handshaker_factory);
gpr_free(cert_pairs);
gpr_free((void *)alpn_protocol_strings);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
return false;
}
tsi_ssl_server_handshaker_factory_unref(sc->server_handshaker_factory);
sc->server_handshaker_factory = new_handshaker_factory;
return true;
}
/* Attempts to fetch the server certificate config if a callback is available.
* Current certificate config will continue to be used if the callback returns
* an error. Returns true if new credentials were sucessfully loaded. */
static bool try_fetch_ssl_server_credentials(
grpc_ssl_server_security_connector *sc) {
grpc_ssl_server_certificate_config *certificate_config = NULL;
bool status;
GPR_ASSERT(sc != NULL);
if (!server_connector_has_cert_config_fetcher(sc)) return false;
grpc_ssl_server_credentials *server_creds =
(grpc_ssl_server_credentials *)sc->base.server_creds;
grpc_ssl_certificate_config_reload_status cb_result =
server_creds->certificate_config_fetcher.cb(
server_creds->certificate_config_fetcher.user_data,
&certificate_config);
if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) {
gpr_log(GPR_DEBUG, "No change in SSL server credentials.");
status = false;
} else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) {
status = try_replace_server_handshaker_factory(sc, certificate_config);
} else {
// Log error, continue using previously-loaded credentials.
gpr_log(GPR_ERROR,
"Failed fetching new server credentials, continuing to "
"use previously-loaded credentials.");
status = false;
}
if (certificate_config != NULL) {
grpc_ssl_server_certificate_config_destroy(certificate_config);
}
return status;
}
static void ssl_server_add_handshakers(grpc_exec_ctx *exec_ctx,
grpc_server_security_connector *sc,
grpc_handshake_manager *handshake_mgr) {
grpc_ssl_server_security_connector *c =
(grpc_ssl_server_security_connector *)sc;
// Instantiate TSI handshaker.
try_fetch_ssl_server_credentials(c);
tsi_handshaker *tsi_hs = NULL;
tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
c->server_handshaker_factory, &tsi_hs);
@ -595,7 +718,6 @@ static void ssl_server_add_handshakers(grpc_exec_ctx *exec_ctx,
tsi_result_to_string(result));
return;
}
// Create handshakers.
grpc_handshake_manager_add(
handshake_mgr,
@ -857,31 +979,6 @@ grpc_slice grpc_get_default_ssl_roots_for_testing(void) {
return compute_default_pem_root_certs_once();
}
static tsi_client_certificate_request_type
get_tsi_client_certificate_request_type(
grpc_ssl_client_certificate_request_type grpc_request_type) {
switch (grpc_request_type) {
case GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE:
return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
return TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
return TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY;
case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY;
default:
// Is this a sane default
return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
}
}
const char *grpc_get_default_ssl_roots(void) {
/* TODO(jboeuf@google.com): Maybe revisit the approach which consists in
loading all the roots once for the lifetime of the process. */
@ -897,18 +994,14 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
grpc_call_credentials *request_metadata_creds,
const grpc_ssl_config *config, const char *target_name,
const char *overridden_target_name, grpc_channel_security_connector **sc) {
size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
size_t num_alpn_protocols = 0;
const char **alpn_protocol_strings =
(const char **)gpr_malloc(sizeof(const char *) * num_alpn_protocols);
fill_alpn_protocol_strings(&num_alpn_protocols);
tsi_result result = TSI_OK;
grpc_ssl_channel_security_connector *c;
size_t i;
const char *pem_root_certs;
char *port;
bool has_key_cert_pair;
for (i = 0; i < num_alpn_protocols; i++) {
alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
}
if (config == NULL || target_name == NULL) {
gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name.");
@ -965,50 +1058,64 @@ error:
return GRPC_SECURITY_ERROR;
}
static grpc_ssl_server_security_connector *
grpc_ssl_server_security_connector_initialize(
grpc_server_credentials *server_creds) {
grpc_ssl_server_security_connector *c =
(grpc_ssl_server_security_connector *)gpr_zalloc(
sizeof(grpc_ssl_server_security_connector));
gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
c->base.base.vtable = &ssl_server_vtable;
c->base.add_handshakers = ssl_server_add_handshakers;
c->base.server_creds = grpc_server_credentials_ref(server_creds);
return c;
}
grpc_security_status grpc_ssl_server_security_connector_create(
grpc_exec_ctx *exec_ctx, grpc_server_credentials *server_creds,
const grpc_ssl_server_config *config, grpc_server_security_connector **sc) {
size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
const char **alpn_protocol_strings =
(const char **)gpr_malloc(sizeof(const char *) * num_alpn_protocols);
grpc_exec_ctx *exec_ctx, grpc_server_credentials *gsc,
grpc_server_security_connector **sc) {
tsi_result result = TSI_OK;
grpc_ssl_server_security_connector *c;
size_t i;
grpc_ssl_server_credentials *server_credentials =
(grpc_ssl_server_credentials *)gsc;
grpc_security_status retval = GRPC_SECURITY_OK;
for (i = 0; i < num_alpn_protocols; i++) {
alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
}
GPR_ASSERT(server_credentials != NULL);
GPR_ASSERT(sc != NULL);
if (config == NULL || config->num_key_cert_pairs == 0) {
gpr_log(GPR_ERROR, "An SSL server needs a key and a cert.");
goto error;
grpc_ssl_server_security_connector *c =
grpc_ssl_server_security_connector_initialize(gsc);
if (server_connector_has_cert_config_fetcher(c)) {
// Load initial credentials from certificate_config_fetcher:
if (!try_fetch_ssl_server_credentials(c)) {
gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher.");
retval = GRPC_SECURITY_ERROR;
}
} else {
size_t num_alpn_protocols = 0;
const char **alpn_protocol_strings =
fill_alpn_protocol_strings(&num_alpn_protocols);
result = tsi_create_ssl_server_handshaker_factory_ex(
server_credentials->config.pem_key_cert_pairs,
server_credentials->config.num_key_cert_pairs,
server_credentials->config.pem_root_certs,
get_tsi_client_certificate_request_type(
server_credentials->config.client_certificate_request),
ssl_cipher_suites(), alpn_protocol_strings,
(uint16_t)num_alpn_protocols, &c->server_handshaker_factory);
gpr_free((void *)alpn_protocol_strings);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
retval = GRPC_SECURITY_ERROR;
}
}
c = (grpc_ssl_server_security_connector *)gpr_zalloc(
sizeof(grpc_ssl_server_security_connector));
gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
c->base.base.vtable = &ssl_server_vtable;
c->base.server_creds = grpc_server_credentials_ref(server_creds);
result = tsi_create_ssl_server_handshaker_factory_ex(
config->pem_key_cert_pairs, config->num_key_cert_pairs,
config->pem_root_certs, get_tsi_client_certificate_request_type(
config->client_certificate_request),
ssl_cipher_suites(), alpn_protocol_strings, (uint16_t)num_alpn_protocols,
&c->server_handshaker_factory);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
ssl_server_destroy(exec_ctx, &c->base.base);
*sc = NULL;
goto error;
if (retval == GRPC_SECURITY_OK) {
*sc = &c->base;
} else {
if (c != NULL) ssl_server_destroy(exec_ctx, &c->base.base);
if (sc != NULL) *sc = NULL;
}
c->base.add_handshakers = ssl_server_add_handshakers;
*sc = &c->base;
gpr_free((void *)alpn_protocol_strings);
return GRPC_SECURITY_OK;
error:
gpr_free((void *)alpn_protocol_strings);
return GRPC_SECURITY_ERROR;
return retval;
}

@ -248,8 +248,8 @@ typedef struct {
specific error code otherwise.
*/
grpc_security_status grpc_ssl_server_security_connector_create(
grpc_exec_ctx *exec_ctx, grpc_server_credentials *server_creds,
const grpc_ssl_server_config *config, grpc_server_security_connector **sc);
grpc_exec_ctx *exec_ctx, grpc_server_credentials *server_credentials,
grpc_server_security_connector **sc);
/* Util. */
const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,

@ -155,8 +155,14 @@ grpc_google_iam_credentials_create_type grpc_google_iam_credentials_create_impor
grpc_metadata_credentials_create_from_plugin_type grpc_metadata_credentials_create_from_plugin_import;
grpc_secure_channel_create_type grpc_secure_channel_create_import;
grpc_server_credentials_release_type grpc_server_credentials_release_import;
grpc_ssl_server_certificate_config_create_type grpc_ssl_server_certificate_config_create_import;
grpc_ssl_server_certificate_config_destroy_type grpc_ssl_server_certificate_config_destroy_import;
grpc_ssl_server_credentials_create_type grpc_ssl_server_credentials_create_import;
grpc_ssl_server_credentials_create_ex_type grpc_ssl_server_credentials_create_ex_import;
grpc_ssl_server_credentials_create_options_using_config_type grpc_ssl_server_credentials_create_options_using_config_import;
grpc_ssl_server_credentials_create_options_using_config_fetcher_type grpc_ssl_server_credentials_create_options_using_config_fetcher_import;
grpc_ssl_server_credentials_options_destroy_type grpc_ssl_server_credentials_options_destroy_import;
grpc_ssl_server_credentials_create_with_options_type grpc_ssl_server_credentials_create_with_options_import;
grpc_server_add_secure_http2_port_type grpc_server_add_secure_http2_port_import;
grpc_call_set_credentials_type grpc_call_set_credentials_import;
grpc_server_credentials_set_auth_metadata_processor_type grpc_server_credentials_set_auth_metadata_processor_import;
@ -465,8 +471,14 @@ void grpc_rb_load_imports(HMODULE library) {
grpc_metadata_credentials_create_from_plugin_import = (grpc_metadata_credentials_create_from_plugin_type) GetProcAddress(library, "grpc_metadata_credentials_create_from_plugin");
grpc_secure_channel_create_import = (grpc_secure_channel_create_type) GetProcAddress(library, "grpc_secure_channel_create");
grpc_server_credentials_release_import = (grpc_server_credentials_release_type) GetProcAddress(library, "grpc_server_credentials_release");
grpc_ssl_server_certificate_config_create_import = (grpc_ssl_server_certificate_config_create_type) GetProcAddress(library, "grpc_ssl_server_certificate_config_create");
grpc_ssl_server_certificate_config_destroy_import = (grpc_ssl_server_certificate_config_destroy_type) GetProcAddress(library, "grpc_ssl_server_certificate_config_destroy");
grpc_ssl_server_credentials_create_import = (grpc_ssl_server_credentials_create_type) GetProcAddress(library, "grpc_ssl_server_credentials_create");
grpc_ssl_server_credentials_create_ex_import = (grpc_ssl_server_credentials_create_ex_type) GetProcAddress(library, "grpc_ssl_server_credentials_create_ex");
grpc_ssl_server_credentials_create_options_using_config_import = (grpc_ssl_server_credentials_create_options_using_config_type) GetProcAddress(library, "grpc_ssl_server_credentials_create_options_using_config");
grpc_ssl_server_credentials_create_options_using_config_fetcher_import = (grpc_ssl_server_credentials_create_options_using_config_fetcher_type) GetProcAddress(library, "grpc_ssl_server_credentials_create_options_using_config_fetcher");
grpc_ssl_server_credentials_options_destroy_import = (grpc_ssl_server_credentials_options_destroy_type) GetProcAddress(library, "grpc_ssl_server_credentials_options_destroy");
grpc_ssl_server_credentials_create_with_options_import = (grpc_ssl_server_credentials_create_with_options_type) GetProcAddress(library, "grpc_ssl_server_credentials_create_with_options");
grpc_server_add_secure_http2_port_import = (grpc_server_add_secure_http2_port_type) GetProcAddress(library, "grpc_server_add_secure_http2_port");
grpc_call_set_credentials_import = (grpc_call_set_credentials_type) GetProcAddress(library, "grpc_call_set_credentials");
grpc_server_credentials_set_auth_metadata_processor_import = (grpc_server_credentials_set_auth_metadata_processor_type) GetProcAddress(library, "grpc_server_credentials_set_auth_metadata_processor");

@ -446,12 +446,30 @@ extern grpc_secure_channel_create_type grpc_secure_channel_create_import;
typedef void(*grpc_server_credentials_release_type)(grpc_server_credentials *creds);
extern grpc_server_credentials_release_type grpc_server_credentials_release_import;
#define grpc_server_credentials_release grpc_server_credentials_release_import
typedef grpc_ssl_server_certificate_config *(*grpc_ssl_server_certificate_config_create_type)(const char *pem_root_certs, const grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, size_t num_key_cert_pairs);
extern grpc_ssl_server_certificate_config_create_type grpc_ssl_server_certificate_config_create_import;
#define grpc_ssl_server_certificate_config_create grpc_ssl_server_certificate_config_create_import
typedef void(*grpc_ssl_server_certificate_config_destroy_type)(grpc_ssl_server_certificate_config *config);
extern grpc_ssl_server_certificate_config_destroy_type grpc_ssl_server_certificate_config_destroy_import;
#define grpc_ssl_server_certificate_config_destroy grpc_ssl_server_certificate_config_destroy_import
typedef grpc_server_credentials *(*grpc_ssl_server_credentials_create_type)(const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, size_t num_key_cert_pairs, int force_client_auth, void *reserved);
extern grpc_ssl_server_credentials_create_type grpc_ssl_server_credentials_create_import;
#define grpc_ssl_server_credentials_create grpc_ssl_server_credentials_create_import
typedef grpc_server_credentials *(*grpc_ssl_server_credentials_create_ex_type)(const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, size_t num_key_cert_pairs, grpc_ssl_client_certificate_request_type client_certificate_request, void *reserved);
extern grpc_ssl_server_credentials_create_ex_type grpc_ssl_server_credentials_create_ex_import;
#define grpc_ssl_server_credentials_create_ex grpc_ssl_server_credentials_create_ex_import
typedef grpc_ssl_server_credentials_options *(*grpc_ssl_server_credentials_create_options_using_config_type)(grpc_ssl_client_certificate_request_type client_certificate_request, grpc_ssl_server_certificate_config *certificate_config);
extern grpc_ssl_server_credentials_create_options_using_config_type grpc_ssl_server_credentials_create_options_using_config_import;
#define grpc_ssl_server_credentials_create_options_using_config grpc_ssl_server_credentials_create_options_using_config_import
typedef grpc_ssl_server_credentials_options *(*grpc_ssl_server_credentials_create_options_using_config_fetcher_type)(grpc_ssl_client_certificate_request_type client_certificate_request, grpc_ssl_server_certificate_config_callback cb, void *user_data);
extern grpc_ssl_server_credentials_create_options_using_config_fetcher_type grpc_ssl_server_credentials_create_options_using_config_fetcher_import;
#define grpc_ssl_server_credentials_create_options_using_config_fetcher grpc_ssl_server_credentials_create_options_using_config_fetcher_import
typedef void(*grpc_ssl_server_credentials_options_destroy_type)(grpc_ssl_server_credentials_options *options);
extern grpc_ssl_server_credentials_options_destroy_type grpc_ssl_server_credentials_options_destroy_import;
#define grpc_ssl_server_credentials_options_destroy grpc_ssl_server_credentials_options_destroy_import
typedef grpc_server_credentials *(*grpc_ssl_server_credentials_create_with_options_type)(grpc_ssl_server_credentials_options *options);
extern grpc_ssl_server_credentials_create_with_options_type grpc_ssl_server_credentials_create_with_options_import;
#define grpc_ssl_server_credentials_create_with_options grpc_ssl_server_credentials_create_with_options_import
typedef int(*grpc_server_add_secure_http2_port_type)(grpc_server *server, const char *addr, grpc_server_credentials *creds);
extern grpc_server_add_secure_http2_port_type grpc_server_add_secure_http2_port_import;
#define grpc_server_add_secure_http2_port grpc_server_add_secure_http2_port_import

Loading…
Cancel
Save