From c1d354d7f2621f467e2f37f36498c20e132c3a72 Mon Sep 17 00:00:00 2001 From: Justin Burke Date: Tue, 19 Sep 2017 15:06:01 -0700 Subject: Support SSL server certificate reloading. --- .../security/credentials/ssl/ssl_credentials.cc | 156 ++++++++++++- .../lib/security/credentials/ssl/ssl_credentials.h | 12 + .../lib/security/transport/security_connector.cc | 251 +++++++++++++++------ .../lib/security/transport/security_connector.h | 4 +- 4 files changed, 340 insertions(+), 83 deletions(-) (limited to 'src/core/lib') diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.cc b/src/core/lib/security/credentials/ssl/ssl_credentials.cc index 8e47aebedb..2085e2b8e7 100644 --- a/src/core/lib/security/credentials/ssl/ssl_credentials.cc +++ b/src/core/lib/security/credentials/ssl/ssl_credentials.cc @@ -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); } diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.h b/src/core/lib/security/credentials/ssl/ssl_credentials.h index 42e425d9f1..5542484aae 100644 --- a/src/core/lib/security/credentials/ssl/ssl_credentials.h +++ b/src/core/lib/security/credentials/ssl/ssl_credentials.h @@ -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( diff --git a/src/core/lib/security/transport/security_connector.cc b/src/core/lib/security/transport/security_connector.cc index b050be2129..06160d0caa 100644 --- a/src/core/lib/security/transport/security_connector.cc +++ b/src/core/lib/security/transport/security_connector.cc @@ -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; } diff --git a/src/core/lib/security/transport/security_connector.h b/src/core/lib/security/transport/security_connector.h index 8287151f44..54a563bb2c 100644 --- a/src/core/lib/security/transport/security_connector.h +++ b/src/core/lib/security/transport/security_connector.h @@ -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, -- cgit v1.2.3