diff options
Diffstat (limited to 'src/core/security/security_context.c')
-rw-r--r-- | src/core/security/security_context.c | 64 |
1 files changed, 49 insertions, 15 deletions
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c index 0a65480b2f..62264e4105 100644 --- a/src/core/security/security_context.c +++ b/src/core/security/security_context.c @@ -43,7 +43,9 @@ #include "src/core/support/file.h" #include "src/core/support/string.h" #include "src/core/transport/chttp2/alpn.h" + #include <grpc/support/alloc.h> +#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/slice_buffer.h> #include "src/core/tsi/fake_transport_security.h" @@ -51,20 +53,33 @@ /* -- Constants. -- */ -/* Defines the cipher suites that we accept. All these cipher suites are - compliant with TLS 1.2 and use an RSA public key. We prefer GCM over CBC - and ECDHE-RSA over just RSA. */ -#define GRPC_SSL_CIPHER_SUITES \ - "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:AES128-GCM-SHA256:" \ - "AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:AES128-" \ - "SHA256:AES256-SHA256" - #ifndef INSTALL_PREFIX static const char *installed_roots_path = "/usr/share/grpc/roots.pem"; #else static const char *installed_roots_path = INSTALL_PREFIX "/share/grpc/roots.pem"; #endif +/* -- Cipher suites. -- */ + +/* Defines the cipher suites that we accept by default. All these cipher suites + are compliant with HTTP2. */ +#define GRPC_SSL_CIPHER_SUITES \ + "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-" \ + "SHA384:ECDHE-RSA-AES256-GCM-SHA384" + +static gpr_once cipher_suites_once = GPR_ONCE_INIT; +static const char *cipher_suites = NULL; + +static void init_cipher_suites(void) { + char *overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES"); + cipher_suites = overridden != NULL ? overridden : GRPC_SSL_CIPHER_SUITES; +} + +static const char *ssl_cipher_suites(void) { + gpr_once_init(&cipher_suites_once, init_cipher_suites); + return cipher_suites; +} + /* -- Common methods. -- */ grpc_security_status grpc_security_context_create_handshaker( @@ -322,6 +337,24 @@ static grpc_security_status ssl_server_create_handshaker( return ssl_create_handshaker(c->handshaker_factory, 0, NULL, handshaker); } +static int ssl_host_matches_name(const tsi_peer *peer, + const char *peer_name) { + char *allocated_name = NULL; + int r; + + if (strchr(peer_name, ':') != NULL) { + char *ignored_port; + gpr_split_host_port(peer_name, &allocated_name, &ignored_port); + gpr_free(ignored_port); + peer_name = allocated_name; + if (!peer_name) return 0; + } + + r = tsi_ssl_peer_matches_name(peer, peer_name); + gpr_free(allocated_name); + return r; +} + static grpc_security_status ssl_check_peer(const char *peer_name, const tsi_peer *peer) { /* Check the ALPN. */ @@ -343,10 +376,11 @@ static grpc_security_status ssl_check_peer(const char *peer_name, /* Check the peer name if specified. */ if (peer_name != NULL && - !tsi_ssl_peer_matches_name(peer, peer_name)) { + !ssl_host_matches_name(peer, peer_name)) { gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", peer_name); return GRPC_SECURITY_ERROR; } + return GRPC_SECURITY_OK; } @@ -382,7 +416,7 @@ static grpc_security_status ssl_channel_check_call_host( grpc_ssl_channel_security_context *c = (grpc_ssl_channel_security_context *)ctx; - if (tsi_ssl_peer_matches_name(&c->peer, host)) return GRPC_SECURITY_OK; + if (ssl_host_matches_name(&c->peer, host)) return GRPC_SECURITY_OK; /* If the target name was overridden, then the original target_name was 'checked' transitively during the previous peer check at the end of the @@ -442,6 +476,7 @@ grpc_security_status grpc_ssl_channel_security_context_create( size_t i; const unsigned char *pem_root_certs; size_t pem_root_certs_size; + char *port; for (i = 0; i < num_alpn_protocols; i++) { alpn_protocol_strings[i] = @@ -467,9 +502,8 @@ grpc_security_status grpc_ssl_channel_security_context_create( c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; c->base.request_metadata_creds = grpc_credentials_ref(request_metadata_creds); c->base.check_call_host = ssl_channel_check_call_host; - if (target_name != NULL) { - c->target_name = gpr_strdup(target_name); - } + gpr_split_host_port(target_name, &c->target_name, &port); + gpr_free(port); if (overridden_target_name != NULL) { c->overridden_target_name = gpr_strdup(overridden_target_name); } @@ -486,7 +520,7 @@ grpc_security_status grpc_ssl_channel_security_context_create( result = tsi_create_ssl_client_handshaker_factory( config->pem_private_key, config->pem_private_key_size, config->pem_cert_chain, config->pem_cert_chain_size, pem_root_certs, - pem_root_certs_size, GRPC_SSL_CIPHER_SUITES, alpn_protocol_strings, + pem_root_certs_size, ssl_cipher_suites(), alpn_protocol_strings, alpn_protocol_string_lengths, num_alpn_protocols, &c->handshaker_factory); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", @@ -540,7 +574,7 @@ grpc_security_status grpc_ssl_server_security_context_create( (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, - GRPC_SSL_CIPHER_SUITES, alpn_protocol_strings, + ssl_cipher_suites(), alpn_protocol_strings, alpn_protocol_string_lengths, num_alpn_protocols, &c->handshaker_factory); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", |