diff options
Diffstat (limited to 'src/core/lib/security/credentials/ssl/ssl_credentials.cc')
-rw-r--r-- | src/core/lib/security/credentials/ssl/ssl_credentials.cc | 289 |
1 files changed, 218 insertions, 71 deletions
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.cc b/src/core/lib/security/credentials/ssl/ssl_credentials.cc index 290336adc0..39dd38cf88 100644 --- a/src/core/lib/security/credentials/ssl/ssl_credentials.cc +++ b/src/core/lib/security/credentials/ssl/ssl_credentials.cc @@ -31,30 +31,33 @@ // SSL Channel Credentials. // -static void ssl_config_pem_key_cert_pair_destroy( - tsi_ssl_pem_key_cert_pair *kp) { - if (kp == NULL) return; - gpr_free((void *)kp->private_key); - gpr_free((void *)kp->cert_chain); +void grpc_tsi_ssl_pem_key_cert_pairs_destroy(tsi_ssl_pem_key_cert_pair* kp, + size_t num_key_cert_pairs) { + if (kp == nullptr) return; + for (size_t i = 0; i < num_key_cert_pairs; i++) { + gpr_free((void*)kp[i].private_key); + gpr_free((void*)kp[i].cert_chain); + } + gpr_free(kp); } -static void ssl_destruct(grpc_exec_ctx *exec_ctx, - grpc_channel_credentials *creds) { - grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds; +static void ssl_destruct(grpc_exec_ctx* exec_ctx, + grpc_channel_credentials* creds) { + grpc_ssl_credentials* c = (grpc_ssl_credentials*)creds; gpr_free(c->config.pem_root_certs); - ssl_config_pem_key_cert_pair_destroy(&c->config.pem_key_cert_pair); + grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pair, 1); } static grpc_security_status ssl_create_security_connector( - grpc_exec_ctx *exec_ctx, grpc_channel_credentials *creds, - grpc_call_credentials *call_creds, const char *target, - const grpc_channel_args *args, grpc_channel_security_connector **sc, - grpc_channel_args **new_args) { - grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds; + grpc_exec_ctx* exec_ctx, grpc_channel_credentials* creds, + grpc_call_credentials* call_creds, const char* target, + const grpc_channel_args* args, grpc_channel_security_connector** sc, + grpc_channel_args** new_args) { + grpc_ssl_credentials* c = (grpc_ssl_credentials*)creds; grpc_security_status status = GRPC_SECURITY_OK; - const char *overridden_target_name = NULL; + const char* overridden_target_name = nullptr; for (size_t i = 0; args && i < args->num_args; i++) { - grpc_arg *arg = &args->args[i]; + grpc_arg* arg = &args->args[i]; if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 && arg->type == GRPC_ARG_STRING) { overridden_target_name = arg->value.string; @@ -68,41 +71,43 @@ static grpc_security_status ssl_create_security_connector( return status; } grpc_arg new_arg = grpc_channel_arg_string_create( - (char *)GRPC_ARG_HTTP2_SCHEME, (char *)"https"); + (char*)GRPC_ARG_HTTP2_SCHEME, (char*)"https"); *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1); return status; } static grpc_channel_credentials_vtable ssl_vtable = { - ssl_destruct, ssl_create_security_connector, NULL}; + ssl_destruct, ssl_create_security_connector, nullptr}; -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) { +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 != nullptr) { config->pem_root_certs = gpr_strdup(pem_root_certs); } - if (pem_key_cert_pair != NULL) { - GPR_ASSERT(pem_key_cert_pair->private_key != NULL); - GPR_ASSERT(pem_key_cert_pair->cert_chain != NULL); - config->pem_key_cert_pair.cert_chain = + if (pem_key_cert_pair != nullptr) { + GPR_ASSERT(pem_key_cert_pair->private_key != nullptr); + GPR_ASSERT(pem_key_cert_pair->cert_chain != nullptr); + config->pem_key_cert_pair = (tsi_ssl_pem_key_cert_pair*)gpr_zalloc( + sizeof(tsi_ssl_pem_key_cert_pair)); + config->pem_key_cert_pair->cert_chain = gpr_strdup(pem_key_cert_pair->cert_chain); - config->pem_key_cert_pair.private_key = + config->pem_key_cert_pair->private_key = gpr_strdup(pem_key_cert_pair->private_key); } } -grpc_channel_credentials *grpc_ssl_credentials_create( - const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair, - void *reserved) { - grpc_ssl_credentials *c = - (grpc_ssl_credentials *)gpr_zalloc(sizeof(grpc_ssl_credentials)); +grpc_channel_credentials* grpc_ssl_credentials_create( + const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + void* reserved) { + grpc_ssl_credentials* c = + (grpc_ssl_credentials*)gpr_zalloc(sizeof(grpc_ssl_credentials)); GRPC_API_TRACE( "grpc_ssl_credentials_create(pem_root_certs=%s, " "pem_key_cert_pair=%p, " "reserved=%p)", 3, (pem_root_certs, pem_key_cert_pair, reserved)); - GPR_ASSERT(reserved == NULL); + GPR_ASSERT(reserved == nullptr); c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL; c->base.vtable = &ssl_vtable; gpr_ref_init(&c->base.refcount, 1); @@ -114,57 +119,144 @@ grpc_channel_credentials *grpc_ssl_credentials_create( // SSL Server Credentials. // -static void ssl_server_destruct(grpc_exec_ctx *exec_ctx, - 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++) { - ssl_config_pem_key_cert_pair_destroy(&c->config.pem_key_cert_pairs[i]); - } - gpr_free(c->config.pem_key_cert_pairs); +struct grpc_ssl_server_credentials_options { + grpc_ssl_client_certificate_request_type client_certificate_request; + grpc_ssl_server_certificate_config* certificate_config; + grpc_ssl_server_certificate_config_fetcher* certificate_config_fetcher; +}; + +static void ssl_server_destruct(grpc_exec_ctx* exec_ctx, + grpc_server_credentials* creds) { + grpc_ssl_server_credentials* c = (grpc_ssl_server_credentials*)creds; + grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pairs, + c->config.num_key_cert_pairs); gpr_free(c->config.pem_root_certs); } static grpc_security_status ssl_server_create_security_connector( - grpc_exec_ctx *exec_ctx, grpc_server_credentials *creds, - grpc_server_security_connector **sc) { - grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds; - return grpc_ssl_server_security_connector_create(exec_ctx, creds, &c->config, - sc); + grpc_exec_ctx* exec_ctx, grpc_server_credentials* creds, + grpc_server_security_connector** sc) { + return grpc_ssl_server_security_connector_create(exec_ctx, creds, sc); } static grpc_server_credentials_vtable ssl_server_vtable = { ssl_server_destruct, ssl_server_create_security_connector}; +tsi_ssl_pem_key_cert_pair* grpc_convert_grpc_to_tsi_cert_pairs( + const grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, + size_t num_key_cert_pairs) { + tsi_ssl_pem_key_cert_pair* tsi_pairs = nullptr; + if (num_key_cert_pairs > 0) { + GPR_ASSERT(pem_key_cert_pairs != nullptr); + tsi_pairs = (tsi_ssl_pem_key_cert_pair*)gpr_zalloc( + num_key_cert_pairs * sizeof(tsi_ssl_pem_key_cert_pair)); + } + for (size_t i = 0; i < num_key_cert_pairs; i++) { + GPR_ASSERT(pem_key_cert_pairs[i].private_key != nullptr); + GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != nullptr); + tsi_pairs[i].cert_chain = gpr_strdup(pem_key_cert_pairs[i].cert_chain); + tsi_pairs[i].private_key = gpr_strdup(pem_key_cert_pairs[i].private_key); + } + return tsi_pairs; +} + static void ssl_build_server_config( - const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, + 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, - grpc_ssl_server_config *config) { - size_t i; + grpc_ssl_server_config* config) { config->client_certificate_request = client_certificate_request; - if (pem_root_certs != NULL) { + if (pem_root_certs != nullptr) { + config->pem_root_certs = gpr_strdup(pem_root_certs); + } + config->pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( + pem_key_cert_pairs, num_key_cert_pairs); + config->num_key_cert_pairs = num_key_cert_pairs; +} + +grpc_ssl_server_certificate_config* grpc_ssl_server_certificate_config_create( + const char* pem_root_certs, + const grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, + size_t num_key_cert_pairs) { + grpc_ssl_server_certificate_config* config = + (grpc_ssl_server_certificate_config*)gpr_zalloc( + sizeof(grpc_ssl_server_certificate_config)); + if (pem_root_certs != nullptr) { config->pem_root_certs = gpr_strdup(pem_root_certs); } if (num_key_cert_pairs > 0) { - GPR_ASSERT(pem_key_cert_pairs != NULL); - config->pem_key_cert_pairs = (tsi_ssl_pem_key_cert_pair *)gpr_zalloc( - num_key_cert_pairs * sizeof(tsi_ssl_pem_key_cert_pair)); + GPR_ASSERT(pem_key_cert_pairs != nullptr); + config->pem_key_cert_pairs = (grpc_ssl_pem_key_cert_pair*)gpr_zalloc( + num_key_cert_pairs * sizeof(grpc_ssl_pem_key_cert_pair)); } 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); + for (size_t i = 0; i < num_key_cert_pairs; i++) { + GPR_ASSERT(pem_key_cert_pairs[i].private_key != nullptr); + GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != nullptr); config->pem_key_cert_pairs[i].cert_chain = gpr_strdup(pem_key_cert_pairs[i].cert_chain); config->pem_key_cert_pairs[i].private_key = gpr_strdup(pem_key_cert_pairs[i].private_key); } + return config; +} + +void grpc_ssl_server_certificate_config_destroy( + grpc_ssl_server_certificate_config* config) { + if (config == nullptr) return; + for (size_t i = 0; i < config->num_key_cert_pairs; i++) { + gpr_free((void*)config->pem_key_cert_pairs[i].private_key); + gpr_free((void*)config->pem_key_cert_pairs[i].cert_chain); + } + gpr_free(config->pem_key_cert_pairs); + gpr_free(config->pem_root_certs); + gpr_free(config); } -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) { +grpc_ssl_server_credentials_options* +grpc_ssl_server_credentials_create_options_using_config( + grpc_ssl_client_certificate_request_type client_certificate_request, + grpc_ssl_server_certificate_config* config) { + grpc_ssl_server_credentials_options* options = nullptr; + if (config == nullptr) { + gpr_log(GPR_ERROR, "Certificate config must not be NULL."); + goto done; + } + options = (grpc_ssl_server_credentials_options*)gpr_zalloc( + sizeof(grpc_ssl_server_credentials_options)); + options->client_certificate_request = client_certificate_request; + options->certificate_config = config; +done: + return options; +} + +grpc_ssl_server_credentials_options* +grpc_ssl_server_credentials_create_options_using_config_fetcher( + grpc_ssl_client_certificate_request_type client_certificate_request, + grpc_ssl_server_certificate_config_callback cb, void* user_data) { + if (cb == nullptr) { + gpr_log(GPR_ERROR, "Invalid certificate config callback parameter."); + return nullptr; + } + + grpc_ssl_server_certificate_config_fetcher* fetcher = + (grpc_ssl_server_certificate_config_fetcher*)gpr_zalloc( + sizeof(grpc_ssl_server_certificate_config_fetcher)); + fetcher->cb = cb; + fetcher->user_data = user_data; + + grpc_ssl_server_credentials_options* options = + (grpc_ssl_server_credentials_options*)gpr_zalloc( + sizeof(grpc_ssl_server_credentials_options)); + options->client_certificate_request = client_certificate_request; + options->certificate_config_fetcher = fetcher; + + return options; +} + +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 @@ -173,25 +265,80 @@ grpc_server_credentials *grpc_ssl_server_credentials_create( 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, +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 = (grpc_ssl_server_credentials *)gpr_zalloc( - sizeof(grpc_ssl_server_credentials)); + void* reserved) { GRPC_API_TRACE( "grpc_ssl_server_credentials_create_ex(" "pem_root_certs=%s, pem_key_cert_pairs=%p, num_key_cert_pairs=%lu, " "client_certificate_request=%d, reserved=%p)", - 5, (pem_root_certs, pem_key_cert_pairs, (unsigned long)num_key_cert_pairs, - client_certificate_request, reserved)); - GPR_ASSERT(reserved == NULL); + 5, + (pem_root_certs, pem_key_cert_pairs, (unsigned long)num_key_cert_pairs, + client_certificate_request, reserved)); + GPR_ASSERT(reserved == nullptr); + + grpc_ssl_server_certificate_config* cert_config = + grpc_ssl_server_certificate_config_create( + pem_root_certs, pem_key_cert_pairs, num_key_cert_pairs); + grpc_ssl_server_credentials_options* options = + grpc_ssl_server_credentials_create_options_using_config( + client_certificate_request, cert_config); + + return grpc_ssl_server_credentials_create_with_options(options); +} + +grpc_server_credentials* grpc_ssl_server_credentials_create_with_options( + grpc_ssl_server_credentials_options* options) { + grpc_server_credentials* retval = nullptr; + grpc_ssl_server_credentials* c = nullptr; + + if (options == nullptr) { + gpr_log(GPR_ERROR, + "Invalid options trying to create SSL server credentials."); + goto done; + } + + if (options->certificate_config == nullptr && + options->certificate_config_fetcher == nullptr) { + gpr_log(GPR_ERROR, + "SSL server credentials options must specify either " + "certificate config or fetcher."); + goto done; + } else if (options->certificate_config_fetcher != nullptr && + options->certificate_config_fetcher->cb == nullptr) { + gpr_log(GPR_ERROR, "Certificate config fetcher callback must not be NULL."); + goto done; + } + + c = (grpc_ssl_server_credentials*)gpr_zalloc( + 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, client_certificate_request, - &c->config); - return &c->base; + + if (options->certificate_config_fetcher != nullptr) { + c->config.client_certificate_request = options->client_certificate_request; + c->certificate_config_fetcher = *options->certificate_config_fetcher; + } else { + ssl_build_server_config(options->certificate_config->pem_root_certs, + options->certificate_config->pem_key_cert_pairs, + options->certificate_config->num_key_cert_pairs, + options->client_certificate_request, &c->config); + } + + retval = &c->base; + +done: + grpc_ssl_server_credentials_options_destroy(options); + return retval; +} + +void grpc_ssl_server_credentials_options_destroy( + grpc_ssl_server_credentials_options* o) { + if (o == nullptr) return; + gpr_free(o->certificate_config_fetcher); + grpc_ssl_server_certificate_config_destroy(o->certificate_config); + gpr_free(o); } |