aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2016-04-21 17:07:36 -0700
committerGravatar Craig Tiller <ctiller@google.com>2016-04-21 17:07:36 -0700
commit7beea147e506b57a9656976001a1360e755a2e9b (patch)
tree57d098e53d213dfe21e1bf40b7693ff2936901d4 /src/core/lib
parent788a25365d022d9797de444799c57842a6fa0603 (diff)
parent5a56891eb6b1591e97d36072ac067d762aecf07e (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.c2
-rw-r--r--src/core/lib/iomgr/tcp_server_windows.c2
-rw-r--r--src/core/lib/iomgr/udp_server.c2
-rw-r--r--src/core/lib/profiling/basic_timers.c1
-rw-r--r--src/core/lib/security/credentials.c27
-rw-r--r--src/core/lib/security/security_connector.c34
-rw-r--r--src/core/lib/security/security_connector.h2
-rw-r--r--src/core/lib/support/alloc.c2
-rw-r--r--src/core/lib/support/log.c33
-rw-r--r--src/core/lib/support/log_linux.c1
-rw-r--r--src/core/lib/support/thd_posix.c1
-rw-r--r--src/core/lib/surface/byte_buffer.c6
-rw-r--r--src/core/lib/surface/init.c2
-rw-r--r--src/core/lib/tsi/fake_transport_security.c22
-rw-r--r--src/core/lib/tsi/ssl_transport_security.c123
-rw-r--r--src/core/lib/tsi/ssl_transport_security.h17
-rw-r--r--src/core/lib/tsi/transport_security.c38
-rw-r--r--src/core/lib/tsi/transport_security_interface.h9
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 --- */