1 /* 2 * 3 * Copyright 2016 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #include <grpc/support/port_platform.h> 20 21 #include "src/core/lib/security/credentials/ssl/ssl_credentials.h" 22 23 #include <string.h> 24 25 #include "src/core/lib/channel/channel_args.h" 26 #include "src/core/lib/surface/api_trace.h" 27 #include "src/core/tsi/ssl_transport_security.h" 28 29 #include <grpc/support/alloc.h> 30 #include <grpc/support/log.h> 31 #include <grpc/support/string_util.h> 32 33 // 34 // SSL Channel Credentials. 35 // 36 37 void grpc_tsi_ssl_pem_key_cert_pairs_destroy(tsi_ssl_pem_key_cert_pair* kp, 38 size_t num_key_cert_pairs) { 39 if (kp == nullptr) return; 40 for (size_t i = 0; i < num_key_cert_pairs; i++) { 41 gpr_free((void*)kp[i].private_key); 42 gpr_free((void*)kp[i].cert_chain); 43 } 44 gpr_free(kp); 45 } 46 47 static void ssl_destruct(grpc_channel_credentials* creds) { 48 grpc_ssl_credentials* c = reinterpret_cast<grpc_ssl_credentials*>(creds); 49 gpr_free(c->config.pem_root_certs); 50 grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pair, 1); 51 if (c->config.verify_options.verify_peer_destruct != nullptr) { 52 c->config.verify_options.verify_peer_destruct( 53 c->config.verify_options.verify_peer_callback_userdata); 54 } 55 } 56 57 static grpc_security_status ssl_create_security_connector( 58 grpc_channel_credentials* creds, grpc_call_credentials* call_creds, 59 const char* target, const grpc_channel_args* args, 60 grpc_channel_security_connector** sc, grpc_channel_args** new_args) { 61 grpc_ssl_credentials* c = reinterpret_cast<grpc_ssl_credentials*>(creds); 62 grpc_security_status status = GRPC_SECURITY_OK; 63 const char* overridden_target_name = nullptr; 64 tsi_ssl_session_cache* ssl_session_cache = nullptr; 65 for (size_t i = 0; args && i < args->num_args; i++) { 66 grpc_arg* arg = &args->args[i]; 67 if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 && 68 arg->type == GRPC_ARG_STRING) { 69 overridden_target_name = arg->value.string; 70 } 71 if (strcmp(arg->key, GRPC_SSL_SESSION_CACHE_ARG) == 0 && 72 arg->type == GRPC_ARG_POINTER) { 73 ssl_session_cache = 74 static_cast<tsi_ssl_session_cache*>(arg->value.pointer.p); 75 } 76 } 77 status = grpc_ssl_channel_security_connector_create( 78 creds, call_creds, &c->config, target, overridden_target_name, 79 ssl_session_cache, sc); 80 if (status != GRPC_SECURITY_OK) { 81 return status; 82 } 83 grpc_arg new_arg = grpc_channel_arg_string_create( 84 (char*)GRPC_ARG_HTTP2_SCHEME, (char*)"https"); 85 *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1); 86 return status; 87 } 88 89 static grpc_channel_credentials_vtable ssl_vtable = { 90 ssl_destruct, ssl_create_security_connector, nullptr}; 91 92 static void ssl_build_config(const char* pem_root_certs, 93 grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, 94 const verify_peer_options* verify_options, 95 grpc_ssl_config* config) { 96 if (pem_root_certs != nullptr) { 97 config->pem_root_certs = gpr_strdup(pem_root_certs); 98 } 99 if (pem_key_cert_pair != nullptr) { 100 GPR_ASSERT(pem_key_cert_pair->private_key != nullptr); 101 GPR_ASSERT(pem_key_cert_pair->cert_chain != nullptr); 102 config->pem_key_cert_pair = static_cast<tsi_ssl_pem_key_cert_pair*>( 103 gpr_zalloc(sizeof(tsi_ssl_pem_key_cert_pair))); 104 config->pem_key_cert_pair->cert_chain = 105 gpr_strdup(pem_key_cert_pair->cert_chain); 106 config->pem_key_cert_pair->private_key = 107 gpr_strdup(pem_key_cert_pair->private_key); 108 } 109 if (verify_options != nullptr) { 110 memcpy(&config->verify_options, verify_options, 111 sizeof(verify_peer_options)); 112 } else { 113 // Otherwise set all options to default values 114 memset(&config->verify_options, 0, sizeof(verify_peer_options)); 115 } 116 } 117 118 grpc_channel_credentials* grpc_ssl_credentials_create( 119 const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, 120 const verify_peer_options* verify_options, void* reserved) { 121 grpc_ssl_credentials* c = static_cast<grpc_ssl_credentials*>( 122 gpr_zalloc(sizeof(grpc_ssl_credentials))); 123 GRPC_API_TRACE( 124 "grpc_ssl_credentials_create(pem_root_certs=%s, " 125 "pem_key_cert_pair=%p, " 126 "verify_options=%p, " 127 "reserved=%p)", 128 4, (pem_root_certs, pem_key_cert_pair, verify_options, reserved)); 129 GPR_ASSERT(reserved == nullptr); 130 c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL; 131 c->base.vtable = &ssl_vtable; 132 gpr_ref_init(&c->base.refcount, 1); 133 ssl_build_config(pem_root_certs, pem_key_cert_pair, verify_options, 134 &c->config); 135 return &c->base; 136 } 137 138 // 139 // SSL Server Credentials. 140 // 141 142 struct grpc_ssl_server_credentials_options { 143 grpc_ssl_client_certificate_request_type client_certificate_request; 144 grpc_ssl_server_certificate_config* certificate_config; 145 grpc_ssl_server_certificate_config_fetcher* certificate_config_fetcher; 146 }; 147 148 static void ssl_server_destruct(grpc_server_credentials* creds) { 149 grpc_ssl_server_credentials* c = 150 reinterpret_cast<grpc_ssl_server_credentials*>(creds); 151 grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pairs, 152 c->config.num_key_cert_pairs); 153 gpr_free(c->config.pem_root_certs); 154 } 155 156 static grpc_security_status ssl_server_create_security_connector( 157 grpc_server_credentials* creds, grpc_server_security_connector** sc) { 158 return grpc_ssl_server_security_connector_create(creds, sc); 159 } 160 161 static grpc_server_credentials_vtable ssl_server_vtable = { 162 ssl_server_destruct, ssl_server_create_security_connector}; 163 164 tsi_ssl_pem_key_cert_pair* grpc_convert_grpc_to_tsi_cert_pairs( 165 const grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, 166 size_t num_key_cert_pairs) { 167 tsi_ssl_pem_key_cert_pair* tsi_pairs = nullptr; 168 if (num_key_cert_pairs > 0) { 169 GPR_ASSERT(pem_key_cert_pairs != nullptr); 170 tsi_pairs = static_cast<tsi_ssl_pem_key_cert_pair*>( 171 gpr_zalloc(num_key_cert_pairs * sizeof(tsi_ssl_pem_key_cert_pair))); 172 } 173 for (size_t i = 0; i < num_key_cert_pairs; i++) { 174 GPR_ASSERT(pem_key_cert_pairs[i].private_key != nullptr); 175 GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != nullptr); 176 tsi_pairs[i].cert_chain = gpr_strdup(pem_key_cert_pairs[i].cert_chain); 177 tsi_pairs[i].private_key = gpr_strdup(pem_key_cert_pairs[i].private_key); 178 } 179 return tsi_pairs; 180 } 181 182 static void ssl_build_server_config( 183 const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, 184 size_t num_key_cert_pairs, 185 grpc_ssl_client_certificate_request_type client_certificate_request, 186 grpc_ssl_server_config* config) { 187 config->client_certificate_request = client_certificate_request; 188 if (pem_root_certs != nullptr) { 189 config->pem_root_certs = gpr_strdup(pem_root_certs); 190 } 191 config->pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( 192 pem_key_cert_pairs, num_key_cert_pairs); 193 config->num_key_cert_pairs = num_key_cert_pairs; 194 } 195 196 grpc_ssl_server_certificate_config* grpc_ssl_server_certificate_config_create( 197 const char* pem_root_certs, 198 const grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, 199 size_t num_key_cert_pairs) { 200 grpc_ssl_server_certificate_config* config = 201 static_cast<grpc_ssl_server_certificate_config*>( 202 gpr_zalloc(sizeof(grpc_ssl_server_certificate_config))); 203 if (pem_root_certs != nullptr) { 204 config->pem_root_certs = gpr_strdup(pem_root_certs); 205 } 206 if (num_key_cert_pairs > 0) { 207 GPR_ASSERT(pem_key_cert_pairs != nullptr); 208 config->pem_key_cert_pairs = static_cast<grpc_ssl_pem_key_cert_pair*>( 209 gpr_zalloc(num_key_cert_pairs * sizeof(grpc_ssl_pem_key_cert_pair))); 210 } 211 config->num_key_cert_pairs = num_key_cert_pairs; 212 for (size_t i = 0; i < num_key_cert_pairs; i++) { 213 GPR_ASSERT(pem_key_cert_pairs[i].private_key != nullptr); 214 GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != nullptr); 215 config->pem_key_cert_pairs[i].cert_chain = 216 gpr_strdup(pem_key_cert_pairs[i].cert_chain); 217 config->pem_key_cert_pairs[i].private_key = 218 gpr_strdup(pem_key_cert_pairs[i].private_key); 219 } 220 return config; 221 } 222 223 void grpc_ssl_server_certificate_config_destroy( 224 grpc_ssl_server_certificate_config* config) { 225 if (config == nullptr) return; 226 for (size_t i = 0; i < config->num_key_cert_pairs; i++) { 227 gpr_free((void*)config->pem_key_cert_pairs[i].private_key); 228 gpr_free((void*)config->pem_key_cert_pairs[i].cert_chain); 229 } 230 gpr_free(config->pem_key_cert_pairs); 231 gpr_free(config->pem_root_certs); 232 gpr_free(config); 233 } 234 235 grpc_ssl_server_credentials_options* 236 grpc_ssl_server_credentials_create_options_using_config( 237 grpc_ssl_client_certificate_request_type client_certificate_request, 238 grpc_ssl_server_certificate_config* config) { 239 grpc_ssl_server_credentials_options* options = nullptr; 240 if (config == nullptr) { 241 gpr_log(GPR_ERROR, "Certificate config must not be NULL."); 242 goto done; 243 } 244 options = static_cast<grpc_ssl_server_credentials_options*>( 245 gpr_zalloc(sizeof(grpc_ssl_server_credentials_options))); 246 options->client_certificate_request = client_certificate_request; 247 options->certificate_config = config; 248 done: 249 return options; 250 } 251 252 grpc_ssl_server_credentials_options* 253 grpc_ssl_server_credentials_create_options_using_config_fetcher( 254 grpc_ssl_client_certificate_request_type client_certificate_request, 255 grpc_ssl_server_certificate_config_callback cb, void* user_data) { 256 if (cb == nullptr) { 257 gpr_log(GPR_ERROR, "Invalid certificate config callback parameter."); 258 return nullptr; 259 } 260 261 grpc_ssl_server_certificate_config_fetcher* fetcher = 262 static_cast<grpc_ssl_server_certificate_config_fetcher*>( 263 gpr_zalloc(sizeof(grpc_ssl_server_certificate_config_fetcher))); 264 fetcher->cb = cb; 265 fetcher->user_data = user_data; 266 267 grpc_ssl_server_credentials_options* options = 268 static_cast<grpc_ssl_server_credentials_options*>( 269 gpr_zalloc(sizeof(grpc_ssl_server_credentials_options))); 270 options->client_certificate_request = client_certificate_request; 271 options->certificate_config_fetcher = fetcher; 272 273 return options; 274 } 275 276 grpc_server_credentials* grpc_ssl_server_credentials_create( 277 const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, 278 size_t num_key_cert_pairs, int force_client_auth, void* reserved) { 279 return grpc_ssl_server_credentials_create_ex( 280 pem_root_certs, pem_key_cert_pairs, num_key_cert_pairs, 281 force_client_auth 282 ? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY 283 : GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, 284 reserved); 285 } 286 287 grpc_server_credentials* grpc_ssl_server_credentials_create_ex( 288 const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, 289 size_t num_key_cert_pairs, 290 grpc_ssl_client_certificate_request_type client_certificate_request, 291 void* reserved) { 292 GRPC_API_TRACE( 293 "grpc_ssl_server_credentials_create_ex(" 294 "pem_root_certs=%s, pem_key_cert_pairs=%p, num_key_cert_pairs=%lu, " 295 "client_certificate_request=%d, reserved=%p)", 296 5, 297 (pem_root_certs, pem_key_cert_pairs, (unsigned long)num_key_cert_pairs, 298 client_certificate_request, reserved)); 299 GPR_ASSERT(reserved == nullptr); 300 301 grpc_ssl_server_certificate_config* cert_config = 302 grpc_ssl_server_certificate_config_create( 303 pem_root_certs, pem_key_cert_pairs, num_key_cert_pairs); 304 grpc_ssl_server_credentials_options* options = 305 grpc_ssl_server_credentials_create_options_using_config( 306 client_certificate_request, cert_config); 307 308 return grpc_ssl_server_credentials_create_with_options(options); 309 } 310 311 grpc_server_credentials* grpc_ssl_server_credentials_create_with_options( 312 grpc_ssl_server_credentials_options* options) { 313 grpc_server_credentials* retval = nullptr; 314 grpc_ssl_server_credentials* c = nullptr; 315 316 if (options == nullptr) { 317 gpr_log(GPR_ERROR, 318 "Invalid options trying to create SSL server credentials."); 319 goto done; 320 } 321 322 if (options->certificate_config == nullptr && 323 options->certificate_config_fetcher == nullptr) { 324 gpr_log(GPR_ERROR, 325 "SSL server credentials options must specify either " 326 "certificate config or fetcher."); 327 goto done; 328 } else if (options->certificate_config_fetcher != nullptr && 329 options->certificate_config_fetcher->cb == nullptr) { 330 gpr_log(GPR_ERROR, "Certificate config fetcher callback must not be NULL."); 331 goto done; 332 } 333 334 c = static_cast<grpc_ssl_server_credentials*>( 335 gpr_zalloc(sizeof(grpc_ssl_server_credentials))); 336 c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL; 337 gpr_ref_init(&c->base.refcount, 1); 338 c->base.vtable = &ssl_server_vtable; 339 340 if (options->certificate_config_fetcher != nullptr) { 341 c->config.client_certificate_request = options->client_certificate_request; 342 c->certificate_config_fetcher = *options->certificate_config_fetcher; 343 } else { 344 ssl_build_server_config(options->certificate_config->pem_root_certs, 345 options->certificate_config->pem_key_cert_pairs, 346 options->certificate_config->num_key_cert_pairs, 347 options->client_certificate_request, &c->config); 348 } 349 350 retval = &c->base; 351 352 done: 353 grpc_ssl_server_credentials_options_destroy(options); 354 return retval; 355 } 356 357 void grpc_ssl_server_credentials_options_destroy( 358 grpc_ssl_server_credentials_options* o) { 359 if (o == nullptr) return; 360 gpr_free(o->certificate_config_fetcher); 361 grpc_ssl_server_certificate_config_destroy(o->certificate_config); 362 gpr_free(o); 363 } 364