diff options
author | Craig Tiller <ctiller@google.com> | 2016-04-21 17:07:36 -0700 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2016-04-21 17:07:36 -0700 |
commit | 7beea147e506b57a9656976001a1360e755a2e9b (patch) | |
tree | 57d098e53d213dfe21e1bf40b7693ff2936901d4 /src/core/lib | |
parent | 788a25365d022d9797de444799c57842a6fa0603 (diff) | |
parent | 5a56891eb6b1591e97d36072ac067d762aecf07e (diff) |
Merge github.com:grpc/grpc into strong-includes
Diffstat (limited to 'src/core/lib')
-rw-r--r-- | src/core/lib/iomgr/tcp_server_posix.c | 2 | ||||
-rw-r--r-- | src/core/lib/iomgr/tcp_server_windows.c | 2 | ||||
-rw-r--r-- | src/core/lib/iomgr/udp_server.c | 2 | ||||
-rw-r--r-- | src/core/lib/profiling/basic_timers.c | 1 | ||||
-rw-r--r-- | src/core/lib/security/credentials.c | 27 | ||||
-rw-r--r-- | src/core/lib/security/security_connector.c | 34 | ||||
-rw-r--r-- | src/core/lib/security/security_connector.h | 2 | ||||
-rw-r--r-- | src/core/lib/support/alloc.c | 2 | ||||
-rw-r--r-- | src/core/lib/support/log.c | 33 | ||||
-rw-r--r-- | src/core/lib/support/log_linux.c | 1 | ||||
-rw-r--r-- | src/core/lib/support/thd_posix.c | 1 | ||||
-rw-r--r-- | src/core/lib/surface/byte_buffer.c | 6 | ||||
-rw-r--r-- | src/core/lib/surface/init.c | 2 | ||||
-rw-r--r-- | src/core/lib/tsi/fake_transport_security.c | 22 | ||||
-rw-r--r-- | src/core/lib/tsi/ssl_transport_security.c | 123 | ||||
-rw-r--r-- | src/core/lib/tsi/ssl_transport_security.h | 17 | ||||
-rw-r--r-- | src/core/lib/tsi/transport_security.c | 38 | ||||
-rw-r--r-- | src/core/lib/tsi/transport_security_interface.h | 9 |
18 files changed, 230 insertions, 94 deletions
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index cfb5251684..aaeb384f6e 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -450,7 +450,7 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, &sockname_len)) { port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); if (port > 0) { - allocated_addr = malloc(addr_len); + allocated_addr = gpr_malloc(addr_len); memcpy(allocated_addr, addr, addr_len); grpc_sockaddr_set_port(allocated_addr, port); addr = allocated_addr; diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c index 9f9d7dcb54..6940dec7b0 100644 --- a/src/core/lib/iomgr/tcp_server_windows.c +++ b/src/core/lib/iomgr/tcp_server_windows.c @@ -467,7 +467,7 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, (struct sockaddr *)&sockname_temp, &sockname_len)) { port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); if (port > 0) { - allocated_addr = malloc(addr_len); + allocated_addr = gpr_malloc(addr_len); memcpy(allocated_addr, addr, addr_len); grpc_sockaddr_set_port(allocated_addr, port); addr = allocated_addr; diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c index 93366eb269..df6cf956d9 100644 --- a/src/core/lib/iomgr/udp_server.c +++ b/src/core/lib/iomgr/udp_server.c @@ -325,7 +325,7 @@ int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr, &sockname_len)) { port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); if (port > 0) { - allocated_addr = malloc(addr_len); + allocated_addr = gpr_malloc(addr_len); memcpy(allocated_addr, addr, addr_len); grpc_sockaddr_set_port(allocated_addr, port); addr = allocated_addr; diff --git a/src/core/lib/profiling/basic_timers.c b/src/core/lib/profiling/basic_timers.c index 93e0b99e90..50082cd7ee 100644 --- a/src/core/lib/profiling/basic_timers.c +++ b/src/core/lib/profiling/basic_timers.c @@ -208,6 +208,7 @@ static void init_output() { } static void rotate_log() { + /* Using malloc here, as this code could end up being called by gpr_malloc */ gpr_timer_log *new = malloc(sizeof(*new)); gpr_once_init(&g_once_init, init_output); new->num_entries = 0; diff --git a/src/core/lib/security/credentials.c b/src/core/lib/security/credentials.c index 2c7d31519c..fd5ad3589b 100644 --- a/src/core/lib/security/credentials.c +++ b/src/core/lib/security/credentials.c @@ -338,10 +338,11 @@ static void ssl_build_config(const char *pem_root_certs, static void ssl_build_server_config( 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, + size_t num_key_cert_pairs, + grpc_ssl_client_certificate_request_type client_certificate_request, grpc_ssl_server_config *config) { size_t i; - config->force_client_auth = force_client_auth; + config->client_certificate_request = client_certificate_request; if (pem_root_certs != NULL) { ssl_copy_key_material(pem_root_certs, &config->pem_root_certs, &config->pem_root_certs_size); @@ -391,21 +392,35 @@ grpc_channel_credentials *grpc_ssl_credentials_create( 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) { + return grpc_ssl_server_credentials_create_ex( + pem_root_certs, pem_key_cert_pairs, num_key_cert_pairs, + force_client_auth + ? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY + : GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, + reserved); +} + +grpc_server_credentials *grpc_ssl_server_credentials_create_ex( + 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) { grpc_ssl_server_credentials *c = gpr_malloc(sizeof(grpc_ssl_server_credentials)); GRPC_API_TRACE( - "grpc_ssl_server_credentials_create(" + "grpc_ssl_server_credentials_create_ex(" "pem_root_certs=%s, pem_key_cert_pairs=%p, num_key_cert_pairs=%lu, " - "force_client_auth=%d, reserved=%p)", + "client_certificate_request=%d, reserved=%p)", 5, (pem_root_certs, pem_key_cert_pairs, (unsigned long)num_key_cert_pairs, - force_client_auth, reserved)); + client_certificate_request, reserved)); GPR_ASSERT(reserved == NULL); memset(c, 0, 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, force_client_auth, &c->config); + num_key_cert_pairs, client_certificate_request, + &c->config); return &c->base; } diff --git a/src/core/lib/security/security_connector.c b/src/core/lib/security/security_connector.c index 59863ba064..2d2023bdf5 100644 --- a/src/core/lib/security/security_connector.c +++ b/src/core/lib/security/security_connector.c @@ -668,6 +668,31 @@ gpr_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; + } +} + size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs) { /* TODO(jboeuf@google.com): Maybe revisit the approach which consists in loading all the roots once for the lifetime of the process. */ @@ -782,15 +807,16 @@ grpc_security_status grpc_ssl_server_security_connector_create( gpr_ref_init(&c->base.base.refcount, 1); c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; c->base.base.vtable = &ssl_server_vtable; - result = tsi_create_ssl_server_handshaker_factory( + result = tsi_create_ssl_server_handshaker_factory_ex( (const unsigned char **)config->pem_private_keys, config->pem_private_keys_sizes, (const unsigned char **)config->pem_cert_chains, config->pem_cert_chains_sizes, config->num_key_cert_pairs, config->pem_root_certs, config->pem_root_certs_size, - config->force_client_auth, ssl_cipher_suites(), alpn_protocol_strings, - alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols, - &c->handshaker_factory); + get_tsi_client_certificate_request_type( + config->client_certificate_request), + ssl_cipher_suites(), alpn_protocol_strings, alpn_protocol_string_lengths, + (uint16_t)num_alpn_protocols, &c->handshaker_factory); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", tsi_result_to_string(result)); diff --git a/src/core/lib/security/security_connector.h b/src/core/lib/security/security_connector.h index c9e262b1ad..2c893cd5e9 100644 --- a/src/core/lib/security/security_connector.h +++ b/src/core/lib/security/security_connector.h @@ -241,7 +241,7 @@ typedef struct { size_t num_key_cert_pairs; unsigned char *pem_root_certs; size_t pem_root_certs_size; - int force_client_auth; + grpc_ssl_client_certificate_request_type client_certificate_request; } grpc_ssl_server_config; /* Creates an SSL server_security_connector. diff --git a/src/core/lib/support/alloc.c b/src/core/lib/support/alloc.c index 020917f79c..618c3f6acd 100644 --- a/src/core/lib/support/alloc.c +++ b/src/core/lib/support/alloc.c @@ -53,6 +53,7 @@ void gpr_set_allocation_functions(gpr_allocation_functions functions) { void *gpr_malloc(size_t size) { void *p; + if (size == 0) return NULL; GPR_TIMER_BEGIN("gpr_malloc", 0); p = g_alloc_functions.malloc_fn(size); if (!p) { @@ -69,6 +70,7 @@ void gpr_free(void *p) { } void *gpr_realloc(void *p, size_t size) { + if ((size == 0) && (p == NULL)) return NULL; GPR_TIMER_BEGIN("gpr_realloc", 0); p = g_alloc_functions.realloc_fn(p, size); if (!p) { diff --git a/src/core/lib/support/log.c b/src/core/lib/support/log.c index 04156a5b1f..882abf673c 100644 --- a/src/core/lib/support/log.c +++ b/src/core/lib/support/log.c @@ -31,14 +31,20 @@ * */ +#include <grpc/support/alloc.h> +#include <grpc/support/atm.h> #include <grpc/support/log.h> #include <grpc/support/port_platform.h> +#include "src/core/lib/support/env.h" +#include "src/core/lib/support/string.h" + #include <stdio.h> #include <string.h> extern void gpr_default_log(gpr_log_func_args *args); static gpr_log_func g_log_func = gpr_default_log; +static gpr_atm g_min_severity_to_print = GPR_LOG_VERBOSITY_UNSET; const char *gpr_log_severity_string(gpr_log_severity severity) { switch (severity) { @@ -54,6 +60,9 @@ const char *gpr_log_severity_string(gpr_log_severity severity) { void gpr_log_message(const char *file, int line, gpr_log_severity severity, const char *message) { + if ((gpr_atm)severity < gpr_atm_no_barrier_load(&g_min_severity_to_print)) + return; + gpr_log_func_args lfargs; memset(&lfargs, 0, sizeof(lfargs)); lfargs.file = file; @@ -63,4 +72,28 @@ void gpr_log_message(const char *file, int line, gpr_log_severity severity, g_log_func(&lfargs); } +void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print) { + gpr_atm_no_barrier_store(&g_min_severity_to_print, + (gpr_atm)min_severity_to_print); +} + +void gpr_log_verbosity_init() { + char *verbosity = gpr_getenv("GRPC_VERBOSITY"); + if (verbosity == NULL) return; + + gpr_atm min_severity_to_print = GPR_LOG_VERBOSITY_UNSET; + if (strcmp(verbosity, "DEBUG") == 0) { + min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_DEBUG; + } else if (strcmp(verbosity, "INFO") == 0) { + min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_INFO; + } else if (strcmp(verbosity, "ERROR") == 0) { + min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_ERROR; + } + gpr_free(verbosity); + if ((gpr_atm_no_barrier_load(&g_min_severity_to_print)) == + GPR_LOG_VERBOSITY_UNSET) { + gpr_atm_no_barrier_store(&g_min_severity_to_print, min_severity_to_print); + } +} + void gpr_set_log_function(gpr_log_func f) { g_log_func = f; } diff --git a/src/core/lib/support/log_linux.c b/src/core/lib/support/log_linux.c index 6d4b63bbe0..ff3febb38e 100644 --- a/src/core/lib/support/log_linux.c +++ b/src/core/lib/support/log_linux.c @@ -68,6 +68,7 @@ void gpr_log(const char *file, int line, gpr_log_severity severity, } va_end(args); gpr_log_message(file, line, severity, message); + /* message has been allocated by vasprintf above, and needs free */ free(message); } diff --git a/src/core/lib/support/thd_posix.c b/src/core/lib/support/thd_posix.c index 89832e3ce1..2fc23bffaf 100644 --- a/src/core/lib/support/thd_posix.c +++ b/src/core/lib/support/thd_posix.c @@ -81,6 +81,7 @@ int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg, thread_started = (pthread_create(&p, &attr, &thread_body, a) == 0); GPR_ASSERT(pthread_attr_destroy(&attr) == 0); if (!thread_started) { + /* don't use gpr_free, as this was allocated using malloc (see above) */ free(a); } *t = (gpr_thd_id)p; diff --git a/src/core/lib/surface/byte_buffer.c b/src/core/lib/surface/byte_buffer.c index fb39c4531d..a093a37af3 100644 --- a/src/core/lib/surface/byte_buffer.c +++ b/src/core/lib/surface/byte_buffer.c @@ -44,7 +44,7 @@ grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices, grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create( gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression) { size_t i; - grpc_byte_buffer *bb = malloc(sizeof(grpc_byte_buffer)); + grpc_byte_buffer *bb = gpr_malloc(sizeof(grpc_byte_buffer)); bb->type = GRPC_BB_RAW; bb->data.raw.compression = compression; gpr_slice_buffer_init(&bb->data.raw.slice_buffer); @@ -57,7 +57,7 @@ grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create( grpc_byte_buffer *grpc_raw_byte_buffer_from_reader( grpc_byte_buffer_reader *reader) { - grpc_byte_buffer *bb = malloc(sizeof(grpc_byte_buffer)); + grpc_byte_buffer *bb = gpr_malloc(sizeof(grpc_byte_buffer)); gpr_slice slice; bb->type = GRPC_BB_RAW; bb->data.raw.compression = GRPC_COMPRESS_NONE; @@ -85,7 +85,7 @@ void grpc_byte_buffer_destroy(grpc_byte_buffer *bb) { gpr_slice_buffer_destroy(&bb->data.raw.slice_buffer); break; } - free(bb); + gpr_free(bb); } size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) { diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c index e48e6db69f..03f379aba8 100644 --- a/src/core/lib/surface/init.c +++ b/src/core/lib/surface/init.c @@ -38,6 +38,7 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> +#include <grpc/support/log.h> #include <grpc/support/time.h> #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/channel/compress_filter.h" @@ -70,6 +71,7 @@ static gpr_mu g_init_mu; static int g_initializations; static void do_basic_init(void) { + gpr_log_verbosity_init(); gpr_mu_init(&g_init_mu); grpc_register_built_in_plugins(); g_initializations = 0; diff --git a/src/core/lib/tsi/fake_transport_security.c b/src/core/lib/tsi/fake_transport_security.c index 4b045b8cd9..0e20d6fd71 100644 --- a/src/core/lib/tsi/fake_transport_security.c +++ b/src/core/lib/tsi/fake_transport_security.c @@ -36,6 +36,7 @@ #include <stdlib.h> #include <string.h> +#include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/port_platform.h> #include <grpc/support/useful.h> @@ -134,12 +135,12 @@ static void tsi_fake_frame_reset(tsi_fake_frame *frame, int needs_draining) { static int tsi_fake_frame_ensure_size(tsi_fake_frame *frame) { if (frame->data == NULL) { frame->allocated_size = frame->size; - frame->data = malloc(frame->allocated_size); + frame->data = gpr_malloc(frame->allocated_size); if (frame->data == NULL) return 0; } else if (frame->size > frame->allocated_size) { - unsigned char *new_data = realloc(frame->data, frame->size); + unsigned char *new_data = gpr_realloc(frame->data, frame->size); if (new_data == NULL) { - free(frame->data); + gpr_free(frame->data); frame->data = NULL; return 0; } @@ -160,7 +161,7 @@ static tsi_result fill_frame_from_bytes(const unsigned char *incoming_bytes, if (frame->needs_draining) return TSI_INTERNAL_ERROR; if (frame->data == NULL) { frame->allocated_size = TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE; - frame->data = malloc(frame->allocated_size); + frame->data = gpr_malloc(frame->allocated_size); if (frame->data == NULL) return TSI_OUT_OF_RESOURCES; } @@ -226,7 +227,7 @@ static tsi_result bytes_to_frame(unsigned char *bytes, size_t bytes_size, } static void tsi_fake_frame_destruct(tsi_fake_frame *frame) { - if (frame->data != NULL) free(frame->data); + if (frame->data != NULL) gpr_free(frame->data); } /* --- tsi_frame_protector methods implementation. ---*/ @@ -366,7 +367,7 @@ static void fake_protector_destroy(tsi_frame_protector *self) { tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self; tsi_fake_frame_destruct(&impl->protect_frame); tsi_fake_frame_destruct(&impl->unprotect_frame); - free(self); + gpr_free(self); } static const tsi_frame_protector_vtable frame_protector_vtable = { @@ -488,7 +489,7 @@ static void fake_handshaker_destroy(tsi_handshaker *self) { tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self; tsi_fake_frame_destruct(&impl->incoming); tsi_fake_frame_destruct(&impl->outgoing); - free(self); + gpr_free(self); } static const tsi_handshaker_vtable handshaker_vtable = { @@ -501,7 +502,8 @@ static const tsi_handshaker_vtable handshaker_vtable = { }; tsi_handshaker *tsi_create_fake_handshaker(int is_client) { - tsi_fake_handshaker *impl = calloc(1, sizeof(tsi_fake_handshaker)); + tsi_fake_handshaker *impl = gpr_malloc(sizeof(*impl)); + memset(impl, 0, sizeof(*impl)); impl->base.vtable = &handshaker_vtable; impl->is_client = is_client; impl->result = TSI_HANDSHAKE_IN_PROGRESS; @@ -517,8 +519,8 @@ tsi_handshaker *tsi_create_fake_handshaker(int is_client) { tsi_frame_protector *tsi_create_fake_protector( size_t *max_protected_frame_size) { - tsi_fake_frame_protector *impl = calloc(1, sizeof(tsi_fake_frame_protector)); - if (impl == NULL) return NULL; + tsi_fake_frame_protector *impl = gpr_malloc(sizeof(*impl)); + memset(impl, 0, sizeof(*impl)); impl->max_frame_size = (max_protected_frame_size == NULL) ? TSI_FAKE_DEFAULT_FRAME_SIZE : *max_protected_frame_size; diff --git a/src/core/lib/tsi/ssl_transport_security.c b/src/core/lib/tsi/ssl_transport_security.c index d98b3e1558..e91c6316e7 100644 --- a/src/core/lib/tsi/ssl_transport_security.c +++ b/src/core/lib/tsi/ssl_transport_security.c @@ -45,6 +45,7 @@ #include <arpa/inet.h> #endif +#include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> #include <grpc/support/thd.h> @@ -148,8 +149,7 @@ static void init_openssl(void) { OpenSSL_add_all_algorithms(); num_locks = CRYPTO_num_locks(); GPR_ASSERT(num_locks > 0); - openssl_mutexes = malloc((size_t)num_locks * sizeof(gpr_mu)); - GPR_ASSERT(openssl_mutexes != NULL); + openssl_mutexes = gpr_malloc((size_t)num_locks * sizeof(gpr_mu)); for (i = 0; i < CRYPTO_num_locks(); i++) { gpr_mu_init(&openssl_mutexes[i]); } @@ -701,7 +701,7 @@ static tsi_result build_alpn_protocol_name_list( } *protocol_name_list_length += (size_t)alpn_protocols_lengths[i] + 1; } - *protocol_name_list = malloc(*protocol_name_list_length); + *protocol_name_list = gpr_malloc(*protocol_name_list_length); if (*protocol_name_list == NULL) return TSI_OUT_OF_RESOURCES; current = *protocol_name_list; for (i = 0; i < num_alpn_protocols; i++) { @@ -718,6 +718,14 @@ static tsi_result build_alpn_protocol_name_list( return TSI_OK; } +// The verification callback is used for clients that don't really care about +// the server's certificate, but we need to pull it anyway, in case a higher +// layer wants to look at it. In this case the verification may fail, but +// we don't really care. +static int NullVerifyCallback(int preverify_ok, X509_STORE_CTX *ctx) { + return 1; +} + /* --- tsi_frame_protector methods implementation. ---*/ static tsi_result ssl_protector_protect(tsi_frame_protector *self, @@ -852,9 +860,9 @@ static tsi_result ssl_protector_unprotect( static void ssl_protector_destroy(tsi_frame_protector *self) { tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *)self; - if (impl->buffer != NULL) free(impl->buffer); + if (impl->buffer != NULL) gpr_free(impl->buffer); if (impl->ssl != NULL) SSL_free(impl->ssl); - free(self); + gpr_free(self); } static const tsi_frame_protector_vtable frame_protector_vtable = { @@ -966,8 +974,9 @@ static tsi_result ssl_handshaker_extract_peer(tsi_handshaker *self, if (alpn_selected != NULL) { size_t i; tsi_peer_property *new_properties = - calloc(1, sizeof(tsi_peer_property) * (peer->property_count + 1)); - if (new_properties == NULL) return TSI_OUT_OF_RESOURCES; + gpr_malloc(sizeof(*new_properties) * (peer->property_count + 1)); + memset(new_properties, 0, + sizeof(*new_properties) * (peer->property_count + 1)); for (i = 0; i < peer->property_count; i++) { new_properties[i] = peer->properties[i]; } @@ -975,10 +984,10 @@ static tsi_result ssl_handshaker_extract_peer(tsi_handshaker *self, TSI_SSL_ALPN_SELECTED_PROTOCOL, (const char *)alpn_selected, alpn_selected_len, &new_properties[peer->property_count]); if (result != TSI_OK) { - free(new_properties); + gpr_free(new_properties); return result; } - if (peer->properties != NULL) free(peer->properties); + if (peer->properties != NULL) gpr_free(peer->properties); peer->property_count++; peer->properties = new_properties; } @@ -991,11 +1000,8 @@ static tsi_result ssl_handshaker_create_frame_protector( size_t actual_max_output_protected_frame_size = TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND; tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; - tsi_ssl_frame_protector *protector_impl = - calloc(1, sizeof(tsi_ssl_frame_protector)); - if (protector_impl == NULL) { - return TSI_OUT_OF_RESOURCES; - } + tsi_ssl_frame_protector *protector_impl = gpr_malloc(sizeof(*protector_impl)); + memset(protector_impl, 0, sizeof(*protector_impl)); if (max_output_protected_frame_size != NULL) { if (*max_output_protected_frame_size > @@ -1011,11 +1017,11 @@ static tsi_result ssl_handshaker_create_frame_protector( } protector_impl->buffer_size = actual_max_output_protected_frame_size - TSI_SSL_MAX_PROTECTION_OVERHEAD; - protector_impl->buffer = malloc(protector_impl->buffer_size); + protector_impl->buffer = gpr_malloc(protector_impl->buffer_size); if (protector_impl->buffer == NULL) { gpr_log(GPR_ERROR, "Could not allocated buffer for tsi_ssl_frame_protector."); - free(protector_impl); + gpr_free(protector_impl); return TSI_INTERNAL_ERROR; } @@ -1034,7 +1040,7 @@ static tsi_result ssl_handshaker_create_frame_protector( static void ssl_handshaker_destroy(tsi_handshaker *self) { tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self; SSL_free(impl->ssl); /* The BIO objects are owned by ssl */ - free(impl); + gpr_free(impl); } static const tsi_handshaker_vtable handshaker_vtable = { @@ -1111,11 +1117,8 @@ static tsi_result create_tsi_ssl_handshaker(SSL_CTX *ctx, int is_client, SSL_set_accept_state(ssl); } - impl = calloc(1, sizeof(tsi_ssl_handshaker)); - if (impl == NULL) { - SSL_free(ssl); - return TSI_OUT_OF_RESOURCES; - } + impl = gpr_malloc(sizeof(*impl)); + memset(impl, 0, sizeof(*impl)); impl->ssl = ssl; impl->into_ssl = into_ssl; impl->from_ssl = from_ssl; @@ -1167,8 +1170,8 @@ static void ssl_client_handshaker_factory_destroy( tsi_ssl_client_handshaker_factory *impl = (tsi_ssl_client_handshaker_factory *)self; if (impl->ssl_context != NULL) SSL_CTX_free(impl->ssl_context); - if (impl->alpn_protocol_list != NULL) free(impl->alpn_protocol_list); - free(impl); + if (impl->alpn_protocol_list != NULL) gpr_free(impl->alpn_protocol_list); + gpr_free(impl); } static int client_handshaker_factory_npn_callback(SSL *ssl, unsigned char **out, @@ -1209,12 +1212,12 @@ static void ssl_server_handshaker_factory_destroy( tsi_peer_destruct(&impl->ssl_context_x509_subject_names[i]); } } - if (impl->ssl_contexts != NULL) free(impl->ssl_contexts); + if (impl->ssl_contexts != NULL) gpr_free(impl->ssl_contexts); if (impl->ssl_context_x509_subject_names != NULL) { - free(impl->ssl_context_x509_subject_names); + gpr_free(impl->ssl_context_x509_subject_names); } - if (impl->alpn_protocol_list != NULL) free(impl->alpn_protocol_list); - free(impl); + if (impl->alpn_protocol_list != NULL) gpr_free(impl->alpn_protocol_list); + gpr_free(impl); } static int does_entry_match_name(const char *entry, size_t entry_length, @@ -1333,11 +1336,8 @@ tsi_result tsi_create_ssl_client_handshaker_factory( return TSI_INVALID_ARGUMENT; } - impl = calloc(1, sizeof(tsi_ssl_client_handshaker_factory)); - if (impl == NULL) { - SSL_CTX_free(ssl_context); - return TSI_OUT_OF_RESOURCES; - } + impl = gpr_malloc(sizeof(*impl)); + memset(impl, 0, sizeof(*impl)); impl->ssl_context = ssl_context; do { @@ -1398,6 +1398,26 @@ tsi_result tsi_create_ssl_server_handshaker_factory( const char *cipher_list, const unsigned char **alpn_protocols, const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, tsi_ssl_handshaker_factory **factory) { + return tsi_create_ssl_server_handshaker_factory_ex( + pem_private_keys, pem_private_keys_sizes, pem_cert_chains, + pem_cert_chains_sizes, key_cert_pair_count, pem_client_root_certs, + pem_client_root_certs_size, + force_client_auth ? TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY + : TSI_DONT_REQUEST_CLIENT_CERTIFICATE, + cipher_list, alpn_protocols, alpn_protocols_lengths, num_alpn_protocols, + factory); +} + +tsi_result tsi_create_ssl_server_handshaker_factory_ex( + const unsigned char **pem_private_keys, + const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains, + const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count, + const unsigned char *pem_client_root_certs, + size_t pem_client_root_certs_size, + tsi_client_certificate_request_type client_certificate_request, + const char *cipher_list, const unsigned char **alpn_protocols, + const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, + tsi_ssl_handshaker_factory **factory) { tsi_ssl_server_handshaker_factory *impl = NULL; tsi_result result = TSI_OK; size_t i = 0; @@ -1411,14 +1431,17 @@ tsi_result tsi_create_ssl_server_handshaker_factory( return TSI_INVALID_ARGUMENT; } - impl = calloc(1, sizeof(tsi_ssl_server_handshaker_factory)); - if (impl == NULL) return TSI_OUT_OF_RESOURCES; + impl = gpr_malloc(sizeof(*impl)); + memset(impl, 0, sizeof(*impl)); impl->base.create_handshaker = ssl_server_handshaker_factory_create_handshaker; impl->base.destroy = ssl_server_handshaker_factory_destroy; - impl->ssl_contexts = calloc(key_cert_pair_count, sizeof(SSL_CTX *)); + impl->ssl_contexts = gpr_malloc(key_cert_pair_count * sizeof(SSL_CTX *)); + memset(impl->ssl_contexts, 0, key_cert_pair_count * sizeof(SSL_CTX *)); impl->ssl_context_x509_subject_names = - calloc(key_cert_pair_count, sizeof(tsi_peer)); + gpr_malloc(key_cert_pair_count * sizeof(tsi_peer)); + memset(impl->ssl_context_x509_subject_names, 0, + key_cert_pair_count * sizeof(tsi_peer)); if (impl->ssl_contexts == NULL || impl->ssl_context_x509_subject_names == NULL) { tsi_ssl_handshaker_factory_destroy(&impl->base); @@ -1450,7 +1473,6 @@ tsi_result tsi_create_ssl_server_handshaker_factory( if (result != TSI_OK) break; if (pem_client_root_certs != NULL) { - int flags = SSL_VERIFY_PEER; STACK_OF(X509_NAME) *root_names = NULL; result = ssl_ctx_load_verification_certs( impl->ssl_contexts[i], pem_client_root_certs, @@ -1460,8 +1482,29 @@ tsi_result tsi_create_ssl_server_handshaker_factory( break; } SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names); - if (force_client_auth) flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; - SSL_CTX_set_verify(impl->ssl_contexts[i], flags, NULL); + switch (client_certificate_request) { + case TSI_DONT_REQUEST_CLIENT_CERTIFICATE: + SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_NONE, NULL); + break; + case TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: + SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, + NullVerifyCallback); + break; + case TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY: + SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, NULL); + break; + case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: + SSL_CTX_set_verify( + impl->ssl_contexts[i], + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + NullVerifyCallback); + break; + case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY: + SSL_CTX_set_verify( + impl->ssl_contexts[i], + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); + break; + } /* TODO(jboeuf): Add revocation verification. */ } diff --git a/src/core/lib/tsi/ssl_transport_security.h b/src/core/lib/tsi/ssl_transport_security.h index 211c8f9656..7407246118 100644 --- a/src/core/lib/tsi/ssl_transport_security.h +++ b/src/core/lib/tsi/ssl_transport_security.h @@ -142,6 +142,23 @@ tsi_result tsi_create_ssl_server_handshaker_factory( const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, tsi_ssl_handshaker_factory **factory); +/* Same as tsi_create_ssl_server_handshaker_factory method except uses + tsi_client_certificate_request_type to support more ways to handle client + certificate authentication. + - client_certificate_request, if set to non-zero will force the client to + authenticate with an SSL cert. Note that this option is ignored if + pem_client_root_certs is NULL or pem_client_roots_certs_size is 0 */ +tsi_result tsi_create_ssl_server_handshaker_factory_ex( + const unsigned char **pem_private_keys, + const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains, + const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count, + const unsigned char *pem_client_root_certs, + size_t pem_client_root_certs_size, + tsi_client_certificate_request_type client_certificate_request, + const char *cipher_suites, const unsigned char **alpn_protocols, + const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, + tsi_ssl_handshaker_factory **factory); + /* Creates a handshaker. - self is the factory from which the handshaker will be created. - server_name_indication indicates the name of the server the client is diff --git a/src/core/lib/tsi/transport_security.c b/src/core/lib/tsi/transport_security.c index 861fc791bc..830cf09584 100644 --- a/src/core/lib/tsi/transport_security.c +++ b/src/core/lib/tsi/transport_security.c @@ -33,6 +33,9 @@ #include "src/core/lib/tsi/transport_security.h" +#include <grpc/support/alloc.h> +#include <grpc/support/string_util.h> + #include <stdlib.h> #include <string.h> @@ -40,19 +43,6 @@ int tsi_tracing_enabled = 0; -/* --- Utils. --- */ - -char *tsi_strdup(const char *src) { - char *dst; - size_t len; - if (!src) return NULL; - len = strlen(src) + 1; - dst = malloc(len); - if (!dst) return NULL; - memcpy(dst, src, len); - return dst; -} - /* --- tsi_result common implementation. --- */ const char *tsi_result_to_string(tsi_result result) { @@ -214,15 +204,15 @@ static void tsi_peer_destroy_list_property(tsi_peer_property *children, for (i = 0; i < child_count; i++) { tsi_peer_property_destruct(&children[i]); } - free(children); + gpr_free(children); } void tsi_peer_property_destruct(tsi_peer_property *property) { if (property->name != NULL) { - free(property->name); + gpr_free(property->name); } if (property->value.data != NULL) { - free(property->value.data); + gpr_free(property->value.data); } *property = tsi_init_peer_property(); /* Reset everything to 0. */ } @@ -239,16 +229,10 @@ void tsi_peer_destruct(tsi_peer *self) { tsi_result tsi_construct_allocated_string_peer_property( const char *name, size_t value_length, tsi_peer_property *property) { *property = tsi_init_peer_property(); - if (name != NULL) { - property->name = tsi_strdup(name); - if (property->name == NULL) return TSI_OUT_OF_RESOURCES; - } + if (name != NULL) property->name = gpr_strdup(name); if (value_length > 0) { - property->value.data = calloc(1, value_length); - if (property->value.data == NULL) { - tsi_peer_property_destruct(property); - return TSI_OUT_OF_RESOURCES; - } + property->value.data = gpr_malloc(value_length); + memset(property->value.data, 0, value_length); property->value.length = value_length; } return TSI_OK; @@ -276,8 +260,8 @@ tsi_result tsi_construct_string_peer_property(const char *name, tsi_result tsi_construct_peer(size_t property_count, tsi_peer *peer) { memset(peer, 0, sizeof(tsi_peer)); if (property_count > 0) { - peer->properties = calloc(property_count, sizeof(tsi_peer_property)); - if (peer->properties == NULL) return TSI_OUT_OF_RESOURCES; + peer->properties = gpr_malloc(property_count * sizeof(tsi_peer_property)); + memset(peer->properties, 0, property_count * sizeof(tsi_peer_property)); peer->property_count = property_count; } return TSI_OK; diff --git a/src/core/lib/tsi/transport_security_interface.h b/src/core/lib/tsi/transport_security_interface.h index d81ec0963a..3e8c9d7ffe 100644 --- a/src/core/lib/tsi/transport_security_interface.h +++ b/src/core/lib/tsi/transport_security_interface.h @@ -59,6 +59,15 @@ typedef enum { TSI_OUT_OF_RESOURCES = 12 } tsi_result; +typedef enum { + // Default option + TSI_DONT_REQUEST_CLIENT_CERTIFICATE, + TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY, + TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, + TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY, + TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY, +} tsi_client_certificate_request_type; + const char *tsi_result_to_string(tsi_result result); /* --- tsi tracing --- */ |