aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/channel/compress_filter.c10
-rw-r--r--src/core/channel/http_client_filter.c4
-rw-r--r--src/core/channel/http_server_filter.c6
-rw-r--r--src/core/security/client_auth_filter.c10
-rw-r--r--src/core/security/credentials.c8
-rw-r--r--src/core/security/security_connector.c7
-rw-r--r--src/core/security/security_connector.h1
-rw-r--r--src/core/surface/call.c6
-rw-r--r--src/core/surface/channel.c22
-rw-r--r--src/core/surface/channel_create.c4
-rw-r--r--src/core/surface/server.c8
-rw-r--r--src/core/transport/chttp2/stream_encoder.c4
-rw-r--r--src/core/transport/chttp2_transport.c2
-rw-r--r--src/core/transport/metadata.c41
-rw-r--r--src/core/transport/metadata.h5
-rw-r--r--src/core/tsi/ssl_transport_security.c8
-rw-r--r--src/core/tsi/ssl_transport_security.h16
17 files changed, 102 insertions, 60 deletions
diff --git a/src/core/channel/compress_filter.c b/src/core/channel/compress_filter.c
index 4bf24e7db3..9fc8589fbb 100644
--- a/src/core/channel/compress_filter.c
+++ b/src/core/channel/compress_filter.c
@@ -284,19 +284,19 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
grpc_channel_args_get_compression_algorithm(args);
channeld->mdstr_request_compression_algorithm_key =
- grpc_mdstr_from_string(mdctx, GRPC_COMPRESS_REQUEST_ALGORITHM_KEY);
+ grpc_mdstr_from_string(mdctx, GRPC_COMPRESS_REQUEST_ALGORITHM_KEY, 0);
channeld->mdstr_outgoing_compression_algorithm_key =
- grpc_mdstr_from_string(mdctx, "grpc-encoding");
+ grpc_mdstr_from_string(mdctx, "grpc-encoding", 0);
for (algo_idx = 0; algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) {
- char *algorith_name;
- GPR_ASSERT(grpc_compression_algorithm_name(algo_idx, &algorith_name) != 0);
+ char *algorithm_name;
+ GPR_ASSERT(grpc_compression_algorithm_name(algo_idx, &algorithm_name) != 0);
channeld->mdelem_compression_algorithms[algo_idx] =
grpc_mdelem_from_metadata_strings(
mdctx,
grpc_mdstr_ref(channeld->mdstr_outgoing_compression_algorithm_key),
- grpc_mdstr_from_string(mdctx, algorith_name));
+ grpc_mdstr_from_string(mdctx, algorithm_name, 0));
}
GPR_ASSERT(!is_last);
diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c
index 6ae8488070..91125cb149 100644
--- a/src/core/channel/http_client_filter.c
+++ b/src/core/channel/http_client_filter.c
@@ -233,7 +233,7 @@ static grpc_mdstr *user_agent_from_args(grpc_mdctx *mdctx,
tmp = gpr_strvec_flatten(&v, NULL);
gpr_strvec_destroy(&v);
- result = grpc_mdstr_from_string(mdctx, tmp);
+ result = grpc_mdstr_from_string(mdctx, tmp, 0);
gpr_free(tmp);
return result;
@@ -260,7 +260,7 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
grpc_mdelem_from_strings(mdctx, "content-type", "application/grpc");
channeld->status = grpc_mdelem_from_strings(mdctx, ":status", "200");
channeld->user_agent = grpc_mdelem_from_metadata_strings(
- mdctx, grpc_mdstr_from_string(mdctx, "user-agent"),
+ mdctx, grpc_mdstr_from_string(mdctx, "user-agent", 0),
user_agent_from_args(mdctx, args));
}
diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c
index 7c798d2fb4..9d89eb9bf2 100644
--- a/src/core/channel/http_server_filter.c
+++ b/src/core/channel/http_server_filter.c
@@ -250,9 +250,9 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
channeld->http_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "http");
channeld->https_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "https");
channeld->grpc_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "grpc");
- channeld->path_key = grpc_mdstr_from_string(mdctx, ":path");
- channeld->authority_key = grpc_mdstr_from_string(mdctx, ":authority");
- channeld->host_key = grpc_mdstr_from_string(mdctx, "host");
+ channeld->path_key = grpc_mdstr_from_string(mdctx, ":path", 0);
+ channeld->authority_key = grpc_mdstr_from_string(mdctx, ":authority", 0);
+ channeld->host_key = grpc_mdstr_from_string(mdctx, "host", 0);
channeld->content_type =
grpc_mdelem_from_strings(mdctx, "content-type", "application/grpc");
diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c
index 9a69f53a5a..e86b5430b2 100644
--- a/src/core/security/client_auth_filter.c
+++ b/src/core/security/client_auth_filter.c
@@ -80,7 +80,7 @@ static void bubble_up_error(grpc_call_element *elem, const char *error_msg) {
channel_data *chand = elem->channel_data;
grpc_transport_stream_op_add_cancellation(
&calld->op, GRPC_STATUS_UNAUTHENTICATED,
- grpc_mdstr_from_string(chand->md_ctx, error_msg));
+ grpc_mdstr_from_string(chand->md_ctx, error_msg, 0));
grpc_call_next_op(elem, &calld->op);
}
@@ -316,10 +316,10 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
(grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF(
sc, "client_auth_filter");
chand->md_ctx = metadata_context;
- chand->authority_string = grpc_mdstr_from_string(chand->md_ctx, ":authority");
- chand->path_string = grpc_mdstr_from_string(chand->md_ctx, ":path");
- chand->error_msg_key = grpc_mdstr_from_string(chand->md_ctx, "grpc-message");
- chand->status_key = grpc_mdstr_from_string(chand->md_ctx, "grpc-status");
+ chand->authority_string = grpc_mdstr_from_string(chand->md_ctx, ":authority", 0);
+ chand->path_string = grpc_mdstr_from_string(chand->md_ctx, ":path", 0);
+ chand->error_msg_key = grpc_mdstr_from_string(chand->md_ctx, "grpc-message", 0);
+ chand->status_key = grpc_mdstr_from_string(chand->md_ctx, "grpc-status", 0);
}
/* Destructor for channel data */
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index 38612cf308..15268cefbe 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -259,8 +259,10 @@ 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, grpc_ssl_server_config *config) {
+ size_t num_key_cert_pairs, int force_client_auth,
+ grpc_ssl_server_config *config) {
size_t i;
+ config->force_client_auth = force_client_auth;
if (pem_root_certs != NULL) {
ssl_copy_key_material(pem_root_certs, &config->pem_root_certs,
&config->pem_root_certs_size);
@@ -302,14 +304,14 @@ grpc_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) {
+ size_t num_key_cert_pairs, int force_client_auth) {
grpc_ssl_server_credentials *c =
gpr_malloc(sizeof(grpc_ssl_server_credentials));
memset(c, 0, sizeof(grpc_ssl_server_credentials));
c->base.type = GRPC_CREDENTIALS_TYPE_SSL;
c->base.vtable = &ssl_server_vtable;
ssl_build_server_config(pem_root_certs, pem_key_cert_pairs,
- num_key_cert_pairs, &c->config);
+ num_key_cert_pairs, force_client_auth, &c->config);
return &c->base;
}
diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c
index f6e423eb27..726b4c1e12 100644
--- a/src/core/security/security_connector.c
+++ b/src/core/security/security_connector.c
@@ -653,9 +653,10 @@ grpc_security_status grpc_ssl_server_security_connector_create(
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, ssl_cipher_suites(),
- alpn_protocol_strings, alpn_protocol_string_lengths,
- (uint16_t)num_alpn_protocols, &c->handshaker_factory);
+ 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);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h
index a4c723f026..2c9aa1c5a4 100644
--- a/src/core/security/security_connector.h
+++ b/src/core/security/security_connector.h
@@ -201,6 +201,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_server_config;
/* Creates an SSL server_security_connector.
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index a1da822113..12378f0066 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -932,7 +932,7 @@ static int prepare_application_metadata(grpc_call *call, size_t count,
GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
l->md = grpc_mdelem_from_string_and_buffer(call->metadata_context, md->key,
(const gpr_uint8 *)md->value,
- md->value_length);
+ md->value_length, 1);
if (!grpc_mdstr_is_legal_header(l->md->key)) {
gpr_log(GPR_ERROR, "attempt to send invalid metadata key");
return 0;
@@ -1203,7 +1203,7 @@ grpc_call_error grpc_call_cancel_with_status(grpc_call *c,
static grpc_call_error cancel_with_status(grpc_call *c, grpc_status_code status,
const char *description) {
grpc_mdstr *details =
- description ? grpc_mdstr_from_string(c->metadata_context, description)
+ description ? grpc_mdstr_from_string(c->metadata_context, description, 0)
: NULL;
GPR_ASSERT(status != GRPC_STATUS_OK);
@@ -1497,7 +1497,7 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
op->data.send_status_from_server.status_details != NULL
? grpc_mdstr_from_string(
call->metadata_context,
- op->data.send_status_from_server.status_details)
+ op->data.send_status_from_server.status_details, 0)
: NULL;
req = &reqs[out++];
req->op = GRPC_IOREQ_SEND_CLOSE;
diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c
index 4052c65cc6..583d350128 100644
--- a/src/core/surface/channel.c
+++ b/src/core/surface/channel.c
@@ -101,19 +101,19 @@ grpc_channel *grpc_channel_create_from_filters(
/* decremented by grpc_channel_destroy */
gpr_ref_init(&channel->refs, 1);
channel->metadata_context = mdctx;
- channel->grpc_status_string = grpc_mdstr_from_string(mdctx, "grpc-status");
+ channel->grpc_status_string = grpc_mdstr_from_string(mdctx, "grpc-status", 0);
channel->grpc_compression_algorithm_string =
- grpc_mdstr_from_string(mdctx, "grpc-encoding");
- channel->grpc_message_string = grpc_mdstr_from_string(mdctx, "grpc-message");
+ grpc_mdstr_from_string(mdctx, "grpc-encoding", 0);
+ channel->grpc_message_string = grpc_mdstr_from_string(mdctx, "grpc-message", 0);
for (i = 0; i < NUM_CACHED_STATUS_ELEMS; i++) {
char buf[GPR_LTOA_MIN_BUFSIZE];
gpr_ltoa(i, buf);
channel->grpc_status_elem[i] = grpc_mdelem_from_metadata_strings(
mdctx, GRPC_MDSTR_REF(channel->grpc_status_string),
- grpc_mdstr_from_string(mdctx, buf));
+ grpc_mdstr_from_string(mdctx, buf, 0));
}
- channel->path_string = grpc_mdstr_from_string(mdctx, ":path");
- channel->authority_string = grpc_mdstr_from_string(mdctx, ":authority");
+ channel->path_string = grpc_mdstr_from_string(mdctx, ":path", 0);
+ channel->authority_string = grpc_mdstr_from_string(mdctx, ":authority", 0);
gpr_mu_init(&channel->registered_call_mu);
channel->registered_calls = NULL;
@@ -167,10 +167,10 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
channel, cq,
grpc_mdelem_from_metadata_strings(
channel->metadata_context, GRPC_MDSTR_REF(channel->path_string),
- grpc_mdstr_from_string(channel->metadata_context, method)),
+ grpc_mdstr_from_string(channel->metadata_context, method, 0)),
grpc_mdelem_from_metadata_strings(
channel->metadata_context, GRPC_MDSTR_REF(channel->authority_string),
- grpc_mdstr_from_string(channel->metadata_context, host)),
+ grpc_mdstr_from_string(channel->metadata_context, host, 0)),
deadline);
}
@@ -179,10 +179,10 @@ void *grpc_channel_register_call(grpc_channel *channel, const char *method,
registered_call *rc = gpr_malloc(sizeof(registered_call));
rc->path = grpc_mdelem_from_metadata_strings(
channel->metadata_context, GRPC_MDSTR_REF(channel->path_string),
- grpc_mdstr_from_string(channel->metadata_context, method));
+ grpc_mdstr_from_string(channel->metadata_context, method, 0));
rc->authority = grpc_mdelem_from_metadata_strings(
channel->metadata_context, GRPC_MDSTR_REF(channel->authority_string),
- grpc_mdstr_from_string(channel->metadata_context, host));
+ grpc_mdstr_from_string(channel->metadata_context, host, 0));
gpr_mu_lock(&channel->registered_call_mu);
rc->next = channel->registered_calls;
channel->registered_calls = rc;
@@ -284,7 +284,7 @@ grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) {
gpr_ltoa(i, tmp);
return grpc_mdelem_from_metadata_strings(
channel->metadata_context, GRPC_MDSTR_REF(channel->grpc_status_string),
- grpc_mdstr_from_string(channel->metadata_context, tmp));
+ grpc_mdstr_from_string(channel->metadata_context, tmp, 0));
}
}
diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c
index fdc2185e14..707d615688 100644
--- a/src/core/surface/channel_create.c
+++ b/src/core/surface/channel_create.c
@@ -154,8 +154,8 @@ static const grpc_subchannel_factory_vtable subchannel_factory_vtable = {
Asynchronously: - resolve target
- connect to it (trying alternatives as presented)
- perform handshakes */
-grpc_channel *grpc_channel_create(const char *target,
- const grpc_channel_args *args) {
+grpc_channel *grpc_insecure_channel_create(const char *target,
+ const grpc_channel_args *args) {
grpc_channel *channel = NULL;
#define MAX_FILTERS 3
const grpc_channel_filter *filters[MAX_FILTERS];
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index 7b3e412db0..f19bcbd090 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -688,8 +688,8 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
GPR_ASSERT(!is_last);
chand->server = NULL;
chand->channel = NULL;
- chand->path_key = grpc_mdstr_from_string(metadata_context, ":path");
- chand->authority_key = grpc_mdstr_from_string(metadata_context, ":authority");
+ chand->path_key = grpc_mdstr_from_string(metadata_context, ":path", 0);
+ chand->authority_key = grpc_mdstr_from_string(metadata_context, ":authority", 0);
chand->next = chand->prev = chand;
chand->registered_methods = NULL;
chand->connectivity_state = GRPC_CHANNEL_IDLE;
@@ -911,8 +911,8 @@ void grpc_server_setup_transport(grpc_server *s, grpc_transport *transport,
chand->registered_methods = gpr_malloc(alloc);
memset(chand->registered_methods, 0, alloc);
for (rm = s->registered_methods; rm; rm = rm->next) {
- host = rm->host ? grpc_mdstr_from_string(mdctx, rm->host) : NULL;
- method = grpc_mdstr_from_string(mdctx, rm->method);
+ host = rm->host ? grpc_mdstr_from_string(mdctx, rm->host, 0) : NULL;
+ method = grpc_mdstr_from_string(mdctx, rm->method, 0);
hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
for (probes = 0; chand->registered_methods[(hash + probes) % slots]
.server_registered_method != NULL;
diff --git a/src/core/transport/chttp2/stream_encoder.c b/src/core/transport/chttp2/stream_encoder.c
index 65b31a5afd..0f04169741 100644
--- a/src/core/transport/chttp2/stream_encoder.c
+++ b/src/core/transport/chttp2/stream_encoder.c
@@ -441,7 +441,7 @@ static void deadline_enc(grpc_chttp2_hpack_compressor *c, gpr_timespec deadline,
gpr_time_sub(deadline, gpr_now(deadline.clock_type)), timeout_str);
mdelem = grpc_mdelem_from_metadata_strings(
c->mdctx, GRPC_MDSTR_REF(c->timeout_key_str),
- grpc_mdstr_from_string(c->mdctx, timeout_str));
+ grpc_mdstr_from_string(c->mdctx, timeout_str, 0));
mdelem = hpack_enc(c, mdelem, st);
if (mdelem) GRPC_MDELEM_UNREF(mdelem);
}
@@ -456,7 +456,7 @@ void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c,
grpc_mdctx *ctx) {
memset(c, 0, sizeof(*c));
c->mdctx = ctx;
- c->timeout_key_str = grpc_mdstr_from_string(ctx, "grpc-timeout");
+ c->timeout_key_str = grpc_mdstr_from_string(ctx, "grpc-timeout", 0);
}
void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c) {
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index ca100703d4..1ea4a82c16 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -232,7 +232,7 @@ static void init_transport(grpc_chttp2_transport *t,
t->global.pings.next = t->global.pings.prev = &t->global.pings;
t->parsing.is_client = is_client;
t->parsing.str_grpc_timeout =
- grpc_mdstr_from_string(t->metadata_context, "grpc-timeout");
+ grpc_mdstr_from_string(t->metadata_context, "grpc-timeout", 0);
t->parsing.deframe_state =
is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0;
t->writing.is_client = is_client;
diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c
index e95b7a21f9..967fd4898c 100644
--- a/src/core/transport/metadata.c
+++ b/src/core/transport/metadata.c
@@ -309,7 +309,37 @@ static void slice_unref(void *p) {
unlock(ctx);
}
-grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str) {
+grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str, int canonicalize_key) {
+ if (canonicalize_key) {
+ size_t len;
+ size_t i;
+ int canonical = 1;
+
+ for (i = 0; str[i]; i++) {
+ if (str[i] >= 'A' && str[i] <= 'Z') {
+ canonical = 0;
+ /* Keep going in loop just to get string length */
+ }
+ }
+ len = i;
+
+ if (canonical) {
+ return grpc_mdstr_from_buffer(ctx, (const gpr_uint8 *)str, len);
+ } else {
+ char *copy = gpr_malloc(len);
+ grpc_mdstr *ret;
+ for (i = 0; i < len; i++) {
+ if (str[i] >= 'A' && str[i] <= 'Z') {
+ copy[i] = str[i] - 'A' + 'a';
+ } else {
+ copy[i] = str[i];
+ }
+ }
+ ret = grpc_mdstr_from_buffer(ctx, (const gpr_uint8 *)copy, len);
+ gpr_free(copy);
+ return ret;
+ }
+ }
return grpc_mdstr_from_buffer(ctx, (const gpr_uint8 *)str, strlen(str));
}
@@ -491,8 +521,8 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdctx *ctx,
grpc_mdelem *grpc_mdelem_from_strings(grpc_mdctx *ctx, const char *key,
const char *value) {
return grpc_mdelem_from_metadata_strings(ctx,
- grpc_mdstr_from_string(ctx, key),
- grpc_mdstr_from_string(ctx, value));
+ grpc_mdstr_from_string(ctx, key, 0),
+ grpc_mdstr_from_string(ctx, value, 0));
}
grpc_mdelem *grpc_mdelem_from_slices(grpc_mdctx *ctx, gpr_slice key,
@@ -504,9 +534,10 @@ grpc_mdelem *grpc_mdelem_from_slices(grpc_mdctx *ctx, gpr_slice key,
grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_mdctx *ctx,
const char *key,
const gpr_uint8 *value,
- size_t value_length) {
+ size_t value_length,
+ int canonicalize_key) {
return grpc_mdelem_from_metadata_strings(
- ctx, grpc_mdstr_from_string(ctx, key),
+ ctx, grpc_mdstr_from_string(ctx, key, canonicalize_key),
grpc_mdstr_from_buffer(ctx, value, value_length));
}
diff --git a/src/core/transport/metadata.h b/src/core/transport/metadata.h
index 99b15322c3..15ef9bb555 100644
--- a/src/core/transport/metadata.h
+++ b/src/core/transport/metadata.h
@@ -95,7 +95,7 @@ size_t grpc_mdctx_get_mdtab_free_test_only(grpc_mdctx *mdctx);
/* Constructors for grpc_mdstr instances; take a variety of data types that
clients may have handy */
-grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str);
+grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str, int perform_key_canonicalization);
/* Unrefs the slice. */
grpc_mdstr *grpc_mdstr_from_slice(grpc_mdctx *ctx, gpr_slice slice);
grpc_mdstr *grpc_mdstr_from_buffer(grpc_mdctx *ctx, const gpr_uint8 *str,
@@ -117,7 +117,8 @@ grpc_mdelem *grpc_mdelem_from_slices(grpc_mdctx *ctx, gpr_slice key,
grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_mdctx *ctx,
const char *key,
const gpr_uint8 *value,
- size_t value_length);
+ size_t value_length,
+ int canonicalize_key);
/* Mutator and accessor for grpc_mdelem user data. The destructor function
is used as a type tag and is checked during user_data fetch. */
diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c
index 6156a39d09..609fc06ed5 100644
--- a/src/core/tsi/ssl_transport_security.c
+++ b/src/core/tsi/ssl_transport_security.c
@@ -1293,8 +1293,8 @@ tsi_result tsi_create_ssl_server_handshaker_factory(
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, const char* cipher_list,
- const unsigned char** alpn_protocols,
+ size_t pem_client_root_certs_size, int force_client_auth,
+ 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;
@@ -1349,6 +1349,7 @@ 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,
@@ -1358,7 +1359,8 @@ tsi_result tsi_create_ssl_server_handshaker_factory(
break;
}
SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names);
- SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, NULL);
+ if (force_client_auth) flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+ SSL_CTX_set_verify(impl->ssl_contexts[i], flags, NULL);
/* TODO(jboeuf): Add revocation verification. */
}
diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h
index b2aa2f393e..4bf6c81b75 100644
--- a/src/core/tsi/ssl_transport_security.h
+++ b/src/core/tsi/ssl_transport_security.h
@@ -107,10 +107,14 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
- key_cert_pair_count indicates the number of items in the private_key_files
and cert_chain_files parameters.
- pem_client_roots is the buffer containing the PEM encoding of the client
- root certificates. This parameter may be NULL in which case the server
- will not ask the client to authenticate itself with a certificate (server-
- only authentication mode).
- - pem_client_roots_size is the size of the associated buffer.
+ root certificates. This parameter may be NULL in which case the server will
+ not authenticate the client. If not NULL, the force_client_auth parameter
+ specifies if the server will accept only authenticated clients or both
+ authenticated and non-authenticated clients.
+ - pem_client_root_certs_size is the size of the associated buffer.
+ - force_client_auth, 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
- cipher_suites contains an optional list of the ciphers that the server
supports. The format of this string is described in:
https://www.openssl.org/docs/apps/ciphers.html.
@@ -131,8 +135,8 @@ tsi_result tsi_create_ssl_server_handshaker_factory(
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, const char* cipher_suites,
- const unsigned char** alpn_protocols,
+ size_t pem_client_root_certs_size, int force_client_auth,
+ 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);