diff options
author | Julien Boeuf <jboeuf@google.com> | 2015-01-15 16:44:13 -0800 |
---|---|---|
committer | Julien Boeuf <jboeuf@google.com> | 2015-01-20 22:18:15 -0800 |
commit | 8fbcc4391ef8ea178520f2e15c07a505621244a6 (patch) | |
tree | fb55328c7de9e66c534a2e987f561794fc2e3ee3 /src | |
parent | 18d4a86982178ff7bbec345a9772184c713cda35 (diff) |
Changing the SSL (Server) Credentials API.
- Changed the unsigned char * + size to NULL terminated strings which
makes sense for the PEM format. I may change TSI later (but the impact
will hopefully be much more limited).
- Added a way to pass multiple key/cert pairs to servers which is needed
when hosting more than one domain.
- Removed the C++ SSL credentials tests as we are going to have an
option to not specify the roots which will then be derived from the
environment (well-known platform dependent locations and/or
environment variable).
- Fixed the php build which is the only one added in the run_test.py.
This change will certainly break node, python and ruby.
Diffstat (limited to 'src')
-rw-r--r-- | src/core/security/credentials.c | 113 | ||||
-rw-r--r-- | src/core/security/credentials.h | 13 | ||||
-rw-r--r-- | src/core/security/security_context.c | 19 | ||||
-rw-r--r-- | src/core/security/security_context.h | 2 | ||||
-rw-r--r-- | src/cpp/client/credentials.cc | 22 | ||||
-rw-r--r-- | src/cpp/server/server_credentials.cc | 23 | ||||
-rw-r--r-- | src/php/ext/grpc/credentials.c | 13 | ||||
-rw-r--r-- | src/php/ext/grpc/server_credentials.c | 14 |
8 files changed, 123 insertions, 96 deletions
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c index 006d863e27..628963e46c 100644 --- a/src/core/security/credentials.c +++ b/src/core/security/credentials.c @@ -139,7 +139,7 @@ typedef struct { typedef struct { grpc_server_credentials base; - grpc_ssl_config config; + grpc_ssl_server_config config; } grpc_ssl_server_credentials; static void ssl_destroy(grpc_credentials *creds) { @@ -152,9 +152,24 @@ static void ssl_destroy(grpc_credentials *creds) { static void ssl_server_destroy(grpc_server_credentials *creds) { grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds; + size_t i; + for (i = 0; i < c->config.num_key_cert_pairs; i++) { + if (c->config.pem_private_keys[i] != NULL) { + gpr_free(c->config.pem_private_keys[i]); + } + if (c->config.pem_cert_chains[i]!= NULL) { + gpr_free(c->config.pem_cert_chains[i]); + } + } + if (c->config.pem_private_keys != NULL) gpr_free(c->config.pem_private_keys); + if (c->config.pem_private_keys_sizes != NULL) { + gpr_free(c->config.pem_private_keys_sizes); + } + if (c->config.pem_cert_chains != NULL) gpr_free(c->config.pem_cert_chains); + if (c->config.pem_cert_chains_sizes != NULL) { + gpr_free(c->config.pem_cert_chains_sizes); + } if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs); - if (c->config.pem_private_key != NULL) gpr_free(c->config.pem_private_key); - if (c->config.pem_cert_chain != NULL) gpr_free(c->config.pem_cert_chain); gpr_free(creds); } @@ -179,7 +194,7 @@ const grpc_ssl_config *grpc_ssl_credentials_get_config( } } -const grpc_ssl_config *grpc_ssl_server_credentials_get_config( +const grpc_ssl_server_config *grpc_ssl_server_credentials_get_config( const grpc_server_credentials *creds) { if (creds == NULL || strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) { return NULL; @@ -189,57 +204,89 @@ const grpc_ssl_config *grpc_ssl_server_credentials_get_config( } } -static void ssl_build_config(const unsigned char *pem_root_certs, - size_t pem_root_certs_size, - const unsigned char *pem_private_key, - size_t pem_private_key_size, - const unsigned char *pem_cert_chain, - size_t pem_cert_chain_size, +static void ssl_copy_key_material(const char *input, unsigned char **output, + size_t *output_size) { + *output_size = strlen(input); + *output = gpr_malloc(*output_size); + memcpy(*output, input, *output_size); +} + +static void ssl_build_config(const char *pem_root_certs, + grpc_ssl_pem_key_cert_pair *pem_key_cert_pair, grpc_ssl_config *config) { + if (pem_root_certs == NULL) { + /* TODO(jboeuf): Get them from the environment. */ + gpr_log(GPR_ERROR, "Default SSL roots not yet implemented."); + } else { + ssl_copy_key_material(pem_root_certs, &config->pem_root_certs, + &config->pem_root_certs_size); + } + + if (pem_key_cert_pair != NULL) { + GPR_ASSERT(pem_key_cert_pair->private_key != NULL); + GPR_ASSERT(pem_key_cert_pair->cert_chain != NULL); + ssl_copy_key_material(pem_key_cert_pair->private_key, + &config->pem_private_key, + &config->pem_private_key_size); + ssl_copy_key_material(pem_key_cert_pair->cert_chain, + &config->pem_cert_chain, + &config->pem_cert_chain_size); + } +} + +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 i; if (pem_root_certs != NULL) { - config->pem_root_certs = gpr_malloc(pem_root_certs_size); - memcpy(config->pem_root_certs, pem_root_certs, pem_root_certs_size); - config->pem_root_certs_size = pem_root_certs_size; + ssl_copy_key_material(pem_root_certs, &config->pem_root_certs, + &config->pem_root_certs_size); } - if (pem_private_key != NULL) { - config->pem_private_key = gpr_malloc(pem_private_key_size); - memcpy(config->pem_private_key, pem_private_key, pem_private_key_size); - config->pem_private_key_size = pem_private_key_size; + if (num_key_cert_pairs > 0) { + GPR_ASSERT(pem_key_cert_pairs != NULL); + config->pem_private_keys = + gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *)); + config->pem_cert_chains = + gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *)); + config->pem_private_keys_sizes = + gpr_malloc(num_key_cert_pairs * sizeof(size_t)); + config->pem_cert_chains_sizes = + gpr_malloc(num_key_cert_pairs * sizeof(size_t)); } - if (pem_cert_chain != NULL) { - config->pem_cert_chain = gpr_malloc(pem_cert_chain_size); - memcpy(config->pem_cert_chain, pem_cert_chain, pem_cert_chain_size); - config->pem_cert_chain_size = pem_cert_chain_size; + config->num_key_cert_pairs = num_key_cert_pairs; + for (i = 0; i < num_key_cert_pairs; i++) { + GPR_ASSERT(pem_key_cert_pairs[i].private_key != NULL); + GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != NULL); + ssl_copy_key_material(pem_key_cert_pairs[i].private_key, + &config->pem_private_keys[i], + &config->pem_private_keys_sizes[i]); + ssl_copy_key_material(pem_key_cert_pairs[i].cert_chain, + &config->pem_cert_chains[i], + &config->pem_cert_chains_sizes[i]); } } grpc_credentials *grpc_ssl_credentials_create( - const unsigned char *pem_root_certs, size_t pem_root_certs_size, - const unsigned char *pem_private_key, size_t pem_private_key_size, - const unsigned char *pem_cert_chain, size_t pem_cert_chain_size) { + const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair) { grpc_ssl_credentials *c = gpr_malloc(sizeof(grpc_ssl_credentials)); memset(c, 0, sizeof(grpc_ssl_credentials)); c->base.type = GRPC_CREDENTIALS_TYPE_SSL; c->base.vtable = &ssl_vtable; gpr_ref_init(&c->base.refcount, 1); - ssl_build_config(pem_root_certs, pem_root_certs_size, pem_private_key, - pem_private_key_size, pem_cert_chain, pem_cert_chain_size, - &c->config); + ssl_build_config(pem_root_certs, pem_key_cert_pair, &c->config); return &c->base; } grpc_server_credentials *grpc_ssl_server_credentials_create( - const unsigned char *pem_root_certs, size_t pem_root_certs_size, - const unsigned char *pem_private_key, size_t pem_private_key_size, - const unsigned char *pem_cert_chain, size_t pem_cert_chain_size) { + const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, + size_t num_key_cert_pairs) { 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_config(pem_root_certs, pem_root_certs_size, pem_private_key, - pem_private_key_size, pem_cert_chain, pem_cert_chain_size, - &c->config); + ssl_build_server_config(pem_root_certs, pem_key_cert_pairs, + num_key_cert_pairs, &c->config); return &c->base; } diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h index 4a2532d7c4..8a9ff41e10 100644 --- a/src/core/security/credentials.h +++ b/src/core/security/credentials.h @@ -137,10 +137,17 @@ struct grpc_server_credentials { const char *type; }; -/* TODO(jboeuf): Have an ssl_server_config that can contain multiple key/cert - pairs. */ +typedef struct { + unsigned char **pem_private_keys; + size_t *pem_private_keys_sizes; + unsigned char **pem_cert_chains; + size_t *pem_cert_chains_sizes; + size_t num_key_cert_pairs; + unsigned char *pem_root_certs; + size_t pem_root_certs_size; +} grpc_ssl_server_config; -const grpc_ssl_config *grpc_ssl_server_credentials_get_config( +const grpc_ssl_server_config *grpc_ssl_server_credentials_get_config( const grpc_server_credentials *ssl_creds); #endif /* __GRPC_INTERNAL_SECURITY_CREDENTIALS_H__ */ diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c index 3a70f44a0a..cce3c7fe04 100644 --- a/src/core/security/security_context.c +++ b/src/core/security/security_context.c @@ -382,7 +382,7 @@ error: } grpc_security_status grpc_ssl_server_security_context_create( - const grpc_ssl_config *config, grpc_security_context **ctx) { + const grpc_ssl_server_config *config, grpc_security_context **ctx) { size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions(); const unsigned char **alpn_protocol_strings = gpr_malloc(sizeof(const char *) * num_alpn_protocols); @@ -399,8 +399,7 @@ grpc_security_status grpc_ssl_server_security_context_create( strlen(grpc_chttp2_get_alpn_version_index(i)); } - if (config == NULL || config->pem_private_key == NULL || - config->pem_cert_chain == NULL) { + if (config == NULL || config->num_key_cert_pairs == 0) { gpr_log(GPR_ERROR, "An SSL server needs a key and a cert."); goto error; } @@ -410,13 +409,13 @@ grpc_security_status grpc_ssl_server_security_context_create( gpr_ref_init(&c->base.refcount, 1); c->base.vtable = &ssl_server_vtable; result = tsi_create_ssl_server_handshaker_factory( - (const unsigned char **)&config->pem_private_key, - &config->pem_private_key_size, - (const unsigned char **)&config->pem_cert_chain, - &config->pem_cert_chain_size, 1, config->pem_root_certs, - config->pem_root_certs_size, GRPC_SSL_CIPHER_SUITES, - alpn_protocol_strings, alpn_protocol_string_lengths, num_alpn_protocols, - &c->handshaker_factory); + (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, + GRPC_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.", tsi_result_to_string(result)); diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h index 9ace7f1ccb..2caa2d3690 100644 --- a/src/core/security/security_context.h +++ b/src/core/security/security_context.h @@ -157,7 +157,7 @@ grpc_security_status grpc_ssl_channel_security_context_create( specific error code otherwise. */ grpc_security_status grpc_ssl_server_security_context_create( - const grpc_ssl_config *config, grpc_security_context **ctx); + const grpc_ssl_server_config *config, grpc_security_context **ctx); /* --- Creation of high level objects. --- */ diff --git a/src/cpp/client/credentials.cc b/src/cpp/client/credentials.cc index 0955fa28ae..8e3a988477 100644 --- a/src/cpp/client/credentials.cc +++ b/src/cpp/client/credentials.cc @@ -54,26 +54,12 @@ std::unique_ptr<Credentials> CredentialsFactory::DefaultCredentials() { // Builds SSL Credentials given SSL specific options std::unique_ptr<Credentials> CredentialsFactory::SslCredentials( const SslCredentialsOptions &options) { - const unsigned char *pem_root_certs = - options.pem_root_certs.empty() ? nullptr - : reinterpret_cast<const unsigned char *>( - options.pem_root_certs.c_str()); - if (pem_root_certs == nullptr) { - return std::unique_ptr<Credentials>(); - } - const unsigned char *pem_private_key = - options.pem_private_key.empty() ? nullptr - : reinterpret_cast<const unsigned char *>( - options.pem_private_key.c_str()); - const unsigned char *pem_cert_chain = - options.pem_cert_chain.empty() ? nullptr - : reinterpret_cast<const unsigned char *>( - options.pem_cert_chain.c_str()); + grpc_ssl_pem_key_cert_pair pem_key_cert_pair = { + options.pem_private_key.c_str(), options.pem_cert_chain.c_str()}; grpc_credentials *c_creds = grpc_ssl_credentials_create( - pem_root_certs, options.pem_root_certs.size(), pem_private_key, - options.pem_private_key.size(), pem_cert_chain, - options.pem_cert_chain.size()); + options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), + options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair); std::unique_ptr<Credentials> cpp_creds( c_creds == nullptr ? nullptr : new Credentials(c_creds)); return cpp_creds; diff --git a/src/cpp/server/server_credentials.cc b/src/cpp/server/server_credentials.cc index b82a2d821a..ce0271b6a0 100644 --- a/src/cpp/server/server_credentials.cc +++ b/src/cpp/server/server_credentials.cc @@ -48,23 +48,14 @@ grpc_server_credentials *ServerCredentials::GetRawCreds() { return creds_; } std::shared_ptr<ServerCredentials> ServerCredentialsFactory::SslCredentials( const SslServerCredentialsOptions &options) { - const unsigned char *pem_root_certs = - options.pem_root_certs.empty() ? nullptr - : reinterpret_cast<const unsigned char *>( - options.pem_root_certs.c_str()); - const unsigned char *pem_private_key = - options.pem_private_key.empty() ? nullptr - : reinterpret_cast<const unsigned char *>( - options.pem_private_key.c_str()); - const unsigned char *pem_cert_chain = - options.pem_cert_chain.empty() ? nullptr - : reinterpret_cast<const unsigned char *>( - options.pem_cert_chain.c_str()); - + std::vector<grpc_ssl_pem_key_cert_pair> pem_key_cert_pairs; + for (const auto &key_cert_pair : options.pem_key_cert_pairs) { + pem_key_cert_pairs.push_back( + {key_cert_pair.private_key.c_str(), key_cert_pair.cert_chain.c_str()}); + } grpc_server_credentials *c_creds = grpc_ssl_server_credentials_create( - pem_root_certs, options.pem_root_certs.size(), pem_private_key, - options.pem_private_key.size(), pem_cert_chain, - options.pem_cert_chain.size()); + options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), + &pem_key_cert_pairs[0], pem_key_cert_pairs.size()); return std::shared_ptr<ServerCredentials>(new ServerCredentials(c_creds)); } diff --git a/src/php/ext/grpc/credentials.c b/src/php/ext/grpc/credentials.c index 2a83d1cbc1..c63196bf90 100644 --- a/src/php/ext/grpc/credentials.c +++ b/src/php/ext/grpc/credentials.c @@ -77,24 +77,23 @@ PHP_METHOD(Credentials, createDefault) { */ PHP_METHOD(Credentials, createSsl) { char *pem_root_certs; - char *pem_private_key = NULL; - char *pem_cert_chain = NULL; + grpc_ssl_pem_key_cert_pair pem_key_cert_pair; int root_certs_length, private_key_length = 0, cert_chain_length = 0; /* "s|s!s! == 1 string, 2 optional nullable strings */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!s!", &pem_root_certs, &root_certs_length, - &pem_private_key, &private_key_length, - &pem_cert_chain, &cert_chain_length) == FAILURE) { + &pem_key_cert_pair.private_key, &private_key_length, + &pem_key_cert_pair.cert_chain, + &cert_chain_length) == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, "createSsl expects 1 to 3 strings", 1 TSRMLS_CC); return; } grpc_credentials *creds = grpc_ssl_credentials_create( - (unsigned char *)pem_root_certs, (size_t)root_certs_length, - (unsigned char *)pem_private_key, (size_t)private_key_length, - (unsigned char *)pem_cert_chain, (size_t)cert_chain_length); + pem_root_certs, + pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair); zval *creds_object = grpc_php_wrap_credentials(creds); RETURN_DESTROY_ZVAL(creds_object); } diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c index 1f8e58aa4d..3d43d6a78c 100644 --- a/src/php/ext/grpc/server_credentials.c +++ b/src/php/ext/grpc/server_credentials.c @@ -66,24 +66,22 @@ zval *grpc_php_wrap_server_credentials(grpc_server_credentials *wrapped) { */ PHP_METHOD(ServerCredentials, createSsl) { char *pem_root_certs = 0; - char *pem_private_key; - char *pem_cert_chain; + grpc_ssl_pem_key_cert_pair pem_key_cert_pair; int root_certs_length = 0, private_key_length, cert_chain_length; /* "s!ss" == 1 nullable string, 2 strings */ + /* TODO: support multiple key cert pairs. */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!ss", &pem_root_certs, - &root_certs_length, &pem_private_key, - &private_key_length, &pem_cert_chain, + &root_certs_length, &pem_key_cert_pair.private_key, + &private_key_length, &pem_key_cert_pair.cert_chain, &cert_chain_length) == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, "createSsl expects 3 strings", 1 TSRMLS_CC); return; } - grpc_server_credentials *creds = grpc_ssl_server_credentials_create( - (unsigned char *)pem_root_certs, (size_t)root_certs_length, - (unsigned char *)pem_private_key, (size_t)private_key_length, - (unsigned char *)pem_cert_chain, (size_t)cert_chain_length); + grpc_server_credentials *creds = + grpc_ssl_server_credentials_create(pem_root_certs, &pem_key_cert_pair, 1); zval *creds_object = grpc_php_wrap_server_credentials(creds); RETURN_DESTROY_ZVAL(creds_object); } |