Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / deps / grpc / src / core / lib / security / security_connector / ssl_utils.cc
1 /*
2  *
3  * Copyright 2015 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/security_connector/ssl_utils.h"
22
23 #include <grpc/slice_buffer.h>
24 #include <grpc/support/alloc.h>
25 #include <grpc/support/log.h>
26 #include <grpc/support/string_util.h>
27
28 #include "src/core/ext/transport/chttp2/alpn/alpn.h"
29 #include "src/core/lib/channel/channel_args.h"
30 #include "src/core/lib/gpr/string.h"
31 #include "src/core/lib/gprpp/host_port.h"
32 #include "src/core/lib/gprpp/ref_counted_ptr.h"
33 #include "src/core/lib/iomgr/load_file.h"
34 #include "src/core/lib/security/context/security_context.h"
35 #include "src/core/lib/security/security_connector/load_system_roots.h"
36 #include "src/core/lib/security/security_connector/ssl_utils_config.h"
37 #include "src/core/tsi/ssl_transport_security.h"
38
39 /* -- Constants. -- */
40
41 #ifndef INSTALL_PREFIX
42 static const char* installed_roots_path = "/usr/share/grpc/roots.pem";
43 #else
44 static const char* installed_roots_path =
45     INSTALL_PREFIX "/share/grpc/roots.pem";
46 #endif
47
48 #ifndef TSI_OPENSSL_ALPN_SUPPORT
49 #define TSI_OPENSSL_ALPN_SUPPORT 1
50 #endif
51
52 /* -- Overridden default roots. -- */
53
54 static grpc_ssl_roots_override_callback ssl_roots_override_cb = nullptr;
55
56 void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) {
57   ssl_roots_override_cb = cb;
58 }
59
60 /* -- Cipher suites. -- */
61
62 static gpr_once cipher_suites_once = GPR_ONCE_INIT;
63 static const char* cipher_suites = nullptr;
64
65 // All cipher suites for default are compliant with HTTP2.
66 GPR_GLOBAL_CONFIG_DEFINE_STRING(
67     grpc_ssl_cipher_suites,
68     "ECDHE-ECDSA-AES128-GCM-SHA256:"
69     "ECDHE-ECDSA-AES256-GCM-SHA384:"
70     "ECDHE-RSA-AES128-GCM-SHA256:"
71     "ECDHE-RSA-AES256-GCM-SHA384",
72     "A colon separated list of cipher suites to use with OpenSSL")
73
74 static void init_cipher_suites(void) {
75   grpc_core::UniquePtr<char> value =
76       GPR_GLOBAL_CONFIG_GET(grpc_ssl_cipher_suites);
77   cipher_suites = value.release();
78 }
79
80 /* --- Util --- */
81
82 const char* grpc_get_ssl_cipher_suites(void) {
83   gpr_once_init(&cipher_suites_once, init_cipher_suites);
84   return cipher_suites;
85 }
86
87 tsi_client_certificate_request_type
88 grpc_get_tsi_client_certificate_request_type(
89     grpc_ssl_client_certificate_request_type grpc_request_type) {
90   switch (grpc_request_type) {
91     case GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE:
92       return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
93
94     case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
95       return TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
96
97     case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
98       return TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY;
99
100     case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
101       return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
102
103     case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
104       return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY;
105
106     default:
107       return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
108   }
109 }
110
111 grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer) {
112 #if TSI_OPENSSL_ALPN_SUPPORT
113   /* Check the ALPN if ALPN is supported. */
114   const tsi_peer_property* p =
115       tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL);
116   if (p == nullptr) {
117     return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
118         "Cannot check peer: missing selected ALPN property.");
119   }
120   if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) {
121     return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
122         "Cannot check peer: invalid ALPN value.");
123   }
124 #endif /* TSI_OPENSSL_ALPN_SUPPORT */
125   return GRPC_ERROR_NONE;
126 }
127
128 grpc_error* grpc_ssl_check_peer_name(grpc_core::StringView peer_name,
129                                      const tsi_peer* peer) {
130   /* Check the peer name if specified. */
131   if (!peer_name.empty() && !grpc_ssl_host_matches_name(peer, peer_name)) {
132     char* msg;
133     gpr_asprintf(&msg, "Peer name %s is not in peer certificate",
134                  peer_name.data());
135     grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
136     gpr_free(msg);
137     return error;
138   }
139   return GRPC_ERROR_NONE;
140 }
141
142 bool grpc_ssl_check_call_host(grpc_core::StringView host,
143                               grpc_core::StringView target_name,
144                               grpc_core::StringView overridden_target_name,
145                               grpc_auth_context* auth_context,
146                               grpc_closure* on_call_host_checked,
147                               grpc_error** error) {
148   grpc_security_status status = GRPC_SECURITY_ERROR;
149   tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context);
150   if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK;
151   if (!overridden_target_name.empty() && host == target_name) {
152     status = GRPC_SECURITY_OK;
153   }
154   if (status != GRPC_SECURITY_OK) {
155     *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
156         "call host does not match SSL server name");
157   }
158   grpc_shallow_peer_destruct(&peer);
159   return true;
160 }
161
162 const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols) {
163   GPR_ASSERT(num_alpn_protocols != nullptr);
164   *num_alpn_protocols = grpc_chttp2_num_alpn_versions();
165   const char** alpn_protocol_strings = static_cast<const char**>(
166       gpr_malloc(sizeof(const char*) * (*num_alpn_protocols)));
167   for (size_t i = 0; i < *num_alpn_protocols; i++) {
168     alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
169   }
170   return alpn_protocol_strings;
171 }
172
173 int grpc_ssl_host_matches_name(const tsi_peer* peer,
174                                grpc_core::StringView peer_name) {
175   grpc_core::StringView allocated_name;
176   grpc_core::StringView ignored_port;
177   grpc_core::SplitHostPort(peer_name, &allocated_name, &ignored_port);
178   if (allocated_name.empty()) return 0;
179
180   // IPv6 zone-id should not be included in comparisons.
181   const size_t zone_id = allocated_name.find('%');
182   if (zone_id != grpc_core::StringView::npos) {
183     allocated_name.remove_suffix(allocated_name.size() - zone_id);
184   }
185   return tsi_ssl_peer_matches_name(peer, allocated_name);
186 }
187
188 int grpc_ssl_cmp_target_name(
189     grpc_core::StringView target_name, grpc_core::StringView other_target_name,
190     grpc_core::StringView overridden_target_name,
191     grpc_core::StringView other_overridden_target_name) {
192   int c = target_name.cmp(other_target_name);
193   if (c != 0) return c;
194   return overridden_target_name.cmp(other_overridden_target_name);
195 }
196
197 grpc_core::RefCountedPtr<grpc_auth_context> grpc_ssl_peer_to_auth_context(
198     const tsi_peer* peer) {
199   size_t i;
200   const char* peer_identity_property_name = nullptr;
201
202   /* The caller has checked the certificate type property. */
203   GPR_ASSERT(peer->property_count >= 1);
204   grpc_core::RefCountedPtr<grpc_auth_context> ctx =
205       grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
206   grpc_auth_context_add_cstring_property(
207       ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
208       GRPC_SSL_TRANSPORT_SECURITY_TYPE);
209   for (i = 0; i < peer->property_count; i++) {
210     const tsi_peer_property* prop = &peer->properties[i];
211     if (prop->name == nullptr) continue;
212     if (strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) {
213       /* If there is no subject alt name, have the CN as the identity. */
214       if (peer_identity_property_name == nullptr) {
215         peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME;
216       }
217       grpc_auth_context_add_property(ctx.get(), GRPC_X509_CN_PROPERTY_NAME,
218                                      prop->value.data, prop->value.length);
219     } else if (strcmp(prop->name,
220                       TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) {
221       peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME;
222       grpc_auth_context_add_property(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME,
223                                      prop->value.data, prop->value.length);
224     } else if (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0) {
225       grpc_auth_context_add_property(ctx.get(),
226                                      GRPC_X509_PEM_CERT_PROPERTY_NAME,
227                                      prop->value.data, prop->value.length);
228     } else if (strcmp(prop->name, TSI_SSL_SESSION_REUSED_PEER_PROPERTY) == 0) {
229       grpc_auth_context_add_property(ctx.get(),
230                                      GRPC_SSL_SESSION_REUSED_PROPERTY,
231                                      prop->value.data, prop->value.length);
232     }
233   }
234   if (peer_identity_property_name != nullptr) {
235     GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
236                    ctx.get(), peer_identity_property_name) == 1);
237   }
238   return ctx;
239 }
240
241 static void add_shallow_auth_property_to_peer(tsi_peer* peer,
242                                               const grpc_auth_property* prop,
243                                               const char* tsi_prop_name) {
244   tsi_peer_property* tsi_prop = &peer->properties[peer->property_count++];
245   tsi_prop->name = const_cast<char*>(tsi_prop_name);
246   tsi_prop->value.data = prop->value;
247   tsi_prop->value.length = prop->value_length;
248 }
249
250 tsi_peer grpc_shallow_peer_from_ssl_auth_context(
251     const grpc_auth_context* auth_context) {
252   size_t max_num_props = 0;
253   grpc_auth_property_iterator it;
254   const grpc_auth_property* prop;
255   tsi_peer peer;
256   memset(&peer, 0, sizeof(peer));
257
258   it = grpc_auth_context_property_iterator(auth_context);
259   while (grpc_auth_property_iterator_next(&it) != nullptr) max_num_props++;
260
261   if (max_num_props > 0) {
262     peer.properties = static_cast<tsi_peer_property*>(
263         gpr_malloc(max_num_props * sizeof(tsi_peer_property)));
264     it = grpc_auth_context_property_iterator(auth_context);
265     while ((prop = grpc_auth_property_iterator_next(&it)) != nullptr) {
266       if (strcmp(prop->name, GRPC_X509_SAN_PROPERTY_NAME) == 0) {
267         add_shallow_auth_property_to_peer(
268             &peer, prop, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY);
269       } else if (strcmp(prop->name, GRPC_X509_CN_PROPERTY_NAME) == 0) {
270         add_shallow_auth_property_to_peer(
271             &peer, prop, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY);
272       } else if (strcmp(prop->name, GRPC_X509_PEM_CERT_PROPERTY_NAME) == 0) {
273         add_shallow_auth_property_to_peer(&peer, prop,
274                                           TSI_X509_PEM_CERT_PROPERTY);
275       }
276     }
277   }
278   return peer;
279 }
280
281 void grpc_shallow_peer_destruct(tsi_peer* peer) {
282   if (peer->properties != nullptr) gpr_free(peer->properties);
283 }
284
285 grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init(
286     tsi_ssl_pem_key_cert_pair* pem_key_cert_pair, const char* pem_root_certs,
287     tsi_ssl_session_cache* ssl_session_cache,
288     tsi_ssl_client_handshaker_factory** handshaker_factory) {
289   const char* root_certs;
290   const tsi_ssl_root_certs_store* root_store;
291   if (pem_root_certs == nullptr) {
292     // Use default root certificates.
293     root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts();
294     if (root_certs == nullptr) {
295       gpr_log(GPR_ERROR, "Could not get default pem root certs.");
296       return GRPC_SECURITY_ERROR;
297     }
298     root_store = grpc_core::DefaultSslRootStore::GetRootStore();
299   } else {
300     root_certs = pem_root_certs;
301     root_store = nullptr;
302   }
303   bool has_key_cert_pair = pem_key_cert_pair != nullptr &&
304                            pem_key_cert_pair->private_key != nullptr &&
305                            pem_key_cert_pair->cert_chain != nullptr;
306   tsi_ssl_client_handshaker_options options;
307   GPR_DEBUG_ASSERT(root_certs != nullptr);
308   options.pem_root_certs = root_certs;
309   options.root_store = root_store;
310   options.alpn_protocols =
311       grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols);
312   if (has_key_cert_pair) {
313     options.pem_key_cert_pair = pem_key_cert_pair;
314   }
315   options.cipher_suites = grpc_get_ssl_cipher_suites();
316   options.session_cache = ssl_session_cache;
317   const tsi_result result =
318       tsi_create_ssl_client_handshaker_factory_with_options(&options,
319                                                             handshaker_factory);
320   gpr_free((void*)options.alpn_protocols);
321   if (result != TSI_OK) {
322     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
323             tsi_result_to_string(result));
324     return GRPC_SECURITY_ERROR;
325   }
326   return GRPC_SECURITY_OK;
327 }
328
329 grpc_security_status grpc_ssl_tsi_server_handshaker_factory_init(
330     tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs, size_t num_key_cert_pairs,
331     const char* pem_root_certs,
332     grpc_ssl_client_certificate_request_type client_certificate_request,
333     tsi_ssl_server_handshaker_factory** handshaker_factory) {
334   size_t num_alpn_protocols = 0;
335   const char** alpn_protocol_strings =
336       grpc_fill_alpn_protocol_strings(&num_alpn_protocols);
337   tsi_ssl_server_handshaker_options options;
338   options.pem_key_cert_pairs = pem_key_cert_pairs;
339   options.num_key_cert_pairs = num_key_cert_pairs;
340   options.pem_client_root_certs = pem_root_certs;
341   options.client_certificate_request =
342       grpc_get_tsi_client_certificate_request_type(client_certificate_request);
343   options.cipher_suites = grpc_get_ssl_cipher_suites();
344   options.alpn_protocols = alpn_protocol_strings;
345   options.num_alpn_protocols = static_cast<uint16_t>(num_alpn_protocols);
346   const tsi_result result =
347       tsi_create_ssl_server_handshaker_factory_with_options(&options,
348                                                             handshaker_factory);
349   gpr_free((void*)alpn_protocol_strings);
350   if (result != TSI_OK) {
351     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
352             tsi_result_to_string(result));
353     return GRPC_SECURITY_ERROR;
354   }
355   return GRPC_SECURITY_OK;
356 }
357
358 /* --- Ssl cache implementation. --- */
359
360 grpc_ssl_session_cache* grpc_ssl_session_cache_create_lru(size_t capacity) {
361   tsi_ssl_session_cache* cache = tsi_ssl_session_cache_create_lru(capacity);
362   return reinterpret_cast<grpc_ssl_session_cache*>(cache);
363 }
364
365 void grpc_ssl_session_cache_destroy(grpc_ssl_session_cache* cache) {
366   tsi_ssl_session_cache* tsi_cache =
367       reinterpret_cast<tsi_ssl_session_cache*>(cache);
368   tsi_ssl_session_cache_unref(tsi_cache);
369 }
370
371 static void* grpc_ssl_session_cache_arg_copy(void* p) {
372   tsi_ssl_session_cache* tsi_cache =
373       reinterpret_cast<tsi_ssl_session_cache*>(p);
374   // destroy call below will unref the pointer.
375   tsi_ssl_session_cache_ref(tsi_cache);
376   return p;
377 }
378
379 static void grpc_ssl_session_cache_arg_destroy(void* p) {
380   tsi_ssl_session_cache* tsi_cache =
381       reinterpret_cast<tsi_ssl_session_cache*>(p);
382   tsi_ssl_session_cache_unref(tsi_cache);
383 }
384
385 static int grpc_ssl_session_cache_arg_cmp(void* p, void* q) {
386   return GPR_ICMP(p, q);
387 }
388
389 grpc_arg grpc_ssl_session_cache_create_channel_arg(
390     grpc_ssl_session_cache* cache) {
391   static const grpc_arg_pointer_vtable vtable = {
392       grpc_ssl_session_cache_arg_copy,
393       grpc_ssl_session_cache_arg_destroy,
394       grpc_ssl_session_cache_arg_cmp,
395   };
396   return grpc_channel_arg_pointer_create(
397       const_cast<char*>(GRPC_SSL_SESSION_CACHE_ARG), cache, &vtable);
398 }
399
400 /* --- Default SSL root store implementation. --- */
401
402 namespace grpc_core {
403
404 tsi_ssl_root_certs_store* DefaultSslRootStore::default_root_store_;
405 grpc_slice DefaultSslRootStore::default_pem_root_certs_;
406
407 const tsi_ssl_root_certs_store* DefaultSslRootStore::GetRootStore() {
408   InitRootStore();
409   return default_root_store_;
410 }
411
412 const char* DefaultSslRootStore::GetPemRootCerts() {
413   InitRootStore();
414   return GRPC_SLICE_IS_EMPTY(default_pem_root_certs_)
415              ? nullptr
416              : reinterpret_cast<const char*>
417                    GRPC_SLICE_START_PTR(default_pem_root_certs_);
418 }
419
420 grpc_slice DefaultSslRootStore::ComputePemRootCerts() {
421   grpc_slice result = grpc_empty_slice();
422   const bool not_use_system_roots =
423       GPR_GLOBAL_CONFIG_GET(grpc_not_use_system_ssl_roots);
424   // First try to load the roots from the configuration.
425   UniquePtr<char> default_root_certs_path =
426       GPR_GLOBAL_CONFIG_GET(grpc_default_ssl_roots_file_path);
427   if (strlen(default_root_certs_path.get()) > 0) {
428     GRPC_LOG_IF_ERROR(
429         "load_file", grpc_load_file(default_root_certs_path.get(), 1, &result));
430   }
431   // Try overridden roots if needed.
432   grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL;
433   if (GRPC_SLICE_IS_EMPTY(result) && ssl_roots_override_cb != nullptr) {
434     char* pem_root_certs = nullptr;
435     ovrd_res = ssl_roots_override_cb(&pem_root_certs);
436     if (ovrd_res == GRPC_SSL_ROOTS_OVERRIDE_OK) {
437       GPR_ASSERT(pem_root_certs != nullptr);
438       result = grpc_slice_from_copied_buffer(
439           pem_root_certs,
440           strlen(pem_root_certs) + 1);  // nullptr terminator.
441     }
442     gpr_free(pem_root_certs);
443   }
444   // Try loading roots from OS trust store if flag is enabled.
445   if (GRPC_SLICE_IS_EMPTY(result) && !not_use_system_roots) {
446     result = LoadSystemRootCerts();
447   }
448   // Fallback to roots manually shipped with gRPC.
449   if (GRPC_SLICE_IS_EMPTY(result) &&
450       ovrd_res != GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY) {
451     GRPC_LOG_IF_ERROR("load_file",
452                       grpc_load_file(installed_roots_path, 1, &result));
453   }
454   return result;
455 }
456
457 void DefaultSslRootStore::InitRootStore() {
458   static gpr_once once = GPR_ONCE_INIT;
459   gpr_once_init(&once, DefaultSslRootStore::InitRootStoreOnce);
460 }
461
462 void DefaultSslRootStore::InitRootStoreOnce() {
463   default_pem_root_certs_ = ComputePemRootCerts();
464   if (!GRPC_SLICE_IS_EMPTY(default_pem_root_certs_)) {
465     default_root_store_ =
466         tsi_ssl_root_certs_store_create(reinterpret_cast<const char*>(
467             GRPC_SLICE_START_PTR(default_pem_root_certs_)));
468   }
469 }
470
471 }  // namespace grpc_core