grpc 1.82.0 → 1.83.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +8 -5
  3. data/etc/roots.pem +10400 -3855
  4. data/include/grpc/grpc_audit_logging.h +2 -2
  5. data/include/grpc/grpc_security_constants.h +2 -0
  6. data/include/grpc/impl/channel_arg_names.h +23 -0
  7. data/src/core/call/call_filters.h +19 -3
  8. data/src/core/call/call_spine.h +4 -4
  9. data/src/core/call/client_call.cc +1 -1
  10. data/src/core/call/metadata.cc +7 -2
  11. data/src/core/call/server_call.cc +13 -3
  12. data/src/core/call/server_call.h +5 -3
  13. data/src/core/client_channel/backup_poller.cc +2 -17
  14. data/src/core/client_channel/client_channel.cc +17 -14
  15. data/src/core/client_channel/client_channel.h +3 -1
  16. data/src/core/client_channel/client_channel_filter.cc +11 -13
  17. data/src/core/client_channel/client_channel_service_config.cc +5 -13
  18. data/src/core/client_channel/direct_channel.cc +5 -1
  19. data/src/core/client_channel/direct_channel.h +3 -1
  20. data/src/core/config/experiment_env_var.cc +30 -0
  21. data/src/core/config/experiment_env_var.h +26 -0
  22. data/src/core/credentials/call/regional_access_boundary_fetcher.cc +6 -6
  23. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +14 -2
  24. data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.cc +172 -0
  25. data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.h +103 -0
  26. data/src/core/credentials/transport/tls/load_system_roots_fallback.cc +3 -2
  27. data/src/core/credentials/transport/tls/load_system_roots_supported.cc +10 -3
  28. data/src/core/credentials/transport/tls/tls_security_connector.cc +14 -2
  29. data/src/core/credentials/transport/xds/xds_credentials.cc +4 -12
  30. data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +2 -1
  31. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +19 -13
  32. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +11 -9
  33. data/src/core/ext/transport/chttp2/transport/flow_control.cc +2 -2
  34. data/src/core/ext/transport/chttp2/transport/flow_control.h +3 -2
  35. data/src/core/ext/transport/chttp2/transport/frame.cc +58 -1
  36. data/src/core/ext/transport/chttp2/transport/frame.h +13 -1
  37. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +2 -4
  38. data/src/core/ext/transport/chttp2/transport/frame_security.cc +10 -1
  39. data/src/core/ext/transport/chttp2/transport/frame_security.h +2 -1
  40. data/src/core/ext/transport/chttp2/transport/goaway.cc +11 -1
  41. data/src/core/ext/transport/chttp2/transport/goaway.h +17 -1
  42. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +9 -0
  43. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +117 -276
  44. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +44 -17
  45. data/src/core/ext/transport/chttp2/transport/http2_server_transport.cc +382 -496
  46. data/src/core/ext/transport/chttp2/transport/http2_server_transport.h +75 -77
  47. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +1 -1
  48. data/src/core/ext/transport/chttp2/transport/http2_settings.h +30 -11
  49. data/src/core/ext/transport/chttp2/transport/http2_settings_promises.h +24 -9
  50. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +26 -0
  51. data/src/core/ext/transport/chttp2/transport/http2_transport.h +2 -0
  52. data/src/core/ext/transport/chttp2/transport/internal.h +4 -0
  53. data/src/core/ext/transport/chttp2/transport/parsing.cc +3 -2
  54. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +1 -1
  55. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +4 -10
  56. data/src/core/ext/transport/chttp2/transport/read_context.h +62 -20
  57. data/src/core/ext/transport/chttp2/transport/security_frame.h +1 -0
  58. data/src/core/ext/transport/chttp2/transport/stream.h +271 -120
  59. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +77 -61
  60. data/src/core/handshaker/security/secure_endpoint.cc +0 -13
  61. data/src/core/lib/channel/promise_based_filter.cc +77 -3
  62. data/src/core/lib/channel/promise_based_filter.h +238 -184
  63. data/src/core/lib/event_engine/extensions/receive_coalescing_extension.h +0 -4
  64. data/src/core/lib/event_engine/extensions/tcp_trace.h +1 -1
  65. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +2 -12
  66. data/src/core/lib/event_engine/shim.cc +2 -16
  67. data/src/core/lib/event_engine/shim.h +0 -4
  68. data/src/core/lib/experiments/experiments.cc +51 -102
  69. data/src/core/lib/experiments/experiments.h +37 -59
  70. data/src/core/lib/iomgr/error.cc +3 -73
  71. data/src/core/lib/iomgr/error.h +8 -6
  72. data/src/core/lib/iomgr/error_cfstream.cc +1 -2
  73. data/src/core/lib/iomgr/ev_epoll1_linux.cc +2 -6
  74. data/src/core/lib/iomgr/ev_poll_posix.cc +2 -6
  75. data/src/core/lib/iomgr/tcp_posix.cc +2 -6
  76. data/src/core/lib/security/authorization/audit_logging.cc +2 -2
  77. data/src/core/lib/security/authorization/audit_logging.h +3 -3
  78. data/src/core/lib/security/authorization/grpc_authorization_engine.cc +11 -13
  79. data/src/core/lib/security/authorization/grpc_authorization_engine.h +1 -1
  80. data/src/core/lib/security/authorization/matchers.cc +20 -20
  81. data/src/core/lib/security/authorization/matchers.h +15 -16
  82. data/src/core/lib/security/authorization/rbac_policy.h +1 -1
  83. data/src/core/lib/security/authorization/stdout_logger.cc +3 -3
  84. data/src/core/lib/security/authorization/stdout_logger.h +6 -5
  85. data/src/core/lib/surface/call.cc +0 -8
  86. data/src/core/lib/surface/call.h +2 -0
  87. data/src/core/lib/surface/channel.cc +21 -2
  88. data/src/core/lib/surface/channel.h +14 -6
  89. data/src/core/lib/surface/filter_stack_call.cc +10 -29
  90. data/src/core/lib/surface/legacy_channel.cc +7 -7
  91. data/src/core/lib/surface/legacy_channel.h +3 -1
  92. data/src/core/lib/surface/version.cc +2 -2
  93. data/src/core/lib/transport/bdp_estimator.cc +13 -13
  94. data/src/core/lib/transport/bdp_estimator.h +9 -5
  95. data/src/core/lib/transport/error_utils.cc +26 -138
  96. data/src/core/lib/transport/promise_endpoint.h +2 -4
  97. data/src/core/load_balancing/grpclb/grpclb.cc +2 -1
  98. data/src/core/load_balancing/pick_first/pick_first.cc +33 -2
  99. data/src/core/load_balancing/pick_first/pick_first.h +6 -0
  100. data/src/core/load_balancing/ring_hash/ring_hash.cc +3 -10
  101. data/src/core/load_balancing/rls/rls.cc +2 -1
  102. data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +2 -7
  103. data/src/core/load_balancing/xds/cds.cc +80 -56
  104. data/src/core/load_balancing/xds/cds.h +21 -0
  105. data/src/core/mitigation_engine/mitigation.h +53 -0
  106. data/src/core/mitigation_engine/mitigation_provider.h +62 -0
  107. data/src/core/resolver/dns/dns_resolver_plugin.cc +1 -6
  108. data/src/core/resolver/xds/xds_resolver.cc +14 -11
  109. data/src/core/server/server.h +1 -4
  110. data/src/core/server/server_config_selector.h +5 -4
  111. data/src/core/server/server_config_selector_filter.cc +67 -80
  112. data/src/core/server/xds_server_config_fetcher.cc +681 -692
  113. data/src/core/server/xds_server_config_fetcher_legacy.cc +15 -12
  114. data/src/core/telemetry/call_tracer.cc +49 -2
  115. data/src/core/telemetry/call_tracer.h +1 -0
  116. data/src/core/telemetry/tcp_tracer.h +38 -0
  117. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  118. data/src/core/tsi/ssl_telemetry_utils.cc +343 -0
  119. data/src/core/tsi/ssl_telemetry_utils.h +74 -0
  120. data/src/core/tsi/ssl_transport_security.cc +577 -301
  121. data/src/core/tsi/ssl_transport_security.h +22 -6
  122. data/src/core/tsi/ssl_transport_security_utils.cc +2 -0
  123. data/src/core/tsi/transport_security.h +7 -0
  124. data/src/core/util/http_client/httpcli.cc +1 -4
  125. data/src/core/util/http_client/httpcli_security_connector.cc +2 -1
  126. data/src/core/util/status_helper.cc +71 -192
  127. data/src/core/util/status_helper.h +16 -21
  128. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +2 -11
  129. data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -7
  130. data/src/core/xds/grpc/xds_cluster_parser.cc +5 -16
  131. data/src/core/xds/grpc/xds_common_types.cc +94 -38
  132. data/src/core/xds/grpc/xds_common_types.h +33 -18
  133. data/src/core/xds/grpc/xds_common_types_parser.cc +168 -100
  134. data/src/core/xds/grpc/xds_common_types_parser.h +18 -1
  135. data/src/core/xds/grpc/xds_endpoint_parser.cc +6 -17
  136. data/src/core/xds/grpc/xds_http_filter_registry.cc +2 -10
  137. data/src/core/xds/grpc/xds_http_rbac_filter.cc +3 -12
  138. data/src/core/xds/grpc/xds_metadata_parser.cc +0 -2
  139. data/src/core/xds/grpc/xds_route_config_parser.cc +7 -11
  140. data/src/core/xds/grpc/xds_routing.cc +113 -82
  141. data/src/core/xds/grpc/xds_routing.h +70 -20
  142. data/src/core/xds/grpc/xds_server_grpc.cc +22 -13
  143. data/src/core/xds/grpc/xds_server_grpc.h +16 -2
  144. data/src/core/xds/grpc/xds_server_grpc_interface.h +10 -0
  145. data/src/core/xds/grpc/xds_transport_grpc.cc +123 -18
  146. data/src/core/xds/grpc/xds_transport_grpc.h +28 -4
  147. data/src/core/xds/xds_client/lrs_client.cc +3 -7
  148. data/src/core/xds/xds_client/xds_bootstrap.cc +4 -16
  149. data/src/core/xds/xds_client/xds_client.cc +2 -15
  150. data/src/core/xds/xds_client/xds_transport.h +3 -0
  151. data/src/ruby/lib/grpc/version.rb +1 -1
  152. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +1 -1
  153. metadata +9 -1
@@ -18,14 +18,18 @@
18
18
 
19
19
  #include "src/core/tsi/ssl_transport_security.h"
20
20
 
21
+ #include <grpc/event_engine/event_engine.h>
21
22
  #include <grpc/private_key_signer.h>
22
23
  #include <grpc/support/port_platform.h>
23
24
  #include <limits.h>
24
25
  #include <string.h>
25
26
 
26
27
  #include <cstddef>
28
+ #include <cstdint>
27
29
  #include <cstdlib>
28
30
  #include <utility>
31
+ #include <variant>
32
+ #include <vector>
29
33
 
30
34
  // TODO(jboeuf): refactor inet_ntop into a portability header.
31
35
  // Note: for whomever reads this and tries to refactor this, this
@@ -55,39 +59,39 @@
55
59
  #include <memory>
56
60
  #include <optional>
57
61
  #include <string>
58
- #include <vector>
59
62
 
63
+ #include "src/core/credentials/transport/tls/grpc_tls_certificate_selector.h"
60
64
  #include "src/core/credentials/transport/tls/grpc_tls_crl_provider.h"
65
+ #include "src/core/credentials/transport/tls/spiffe_utils.h"
61
66
  #include "src/core/credentials/transport/tls/ssl_utils.h"
62
- #include "src/core/lib/event_engine/default_event_engine.h"
67
+ #include "src/core/lib/debug/trace_impl.h"
63
68
  #include "src/core/lib/iomgr/exec_ctx.h"
64
69
  #include "src/core/lib/surface/init.h"
65
70
  #include "src/core/tsi/ssl/key_logging/ssl_key_logging.h"
71
+ #include "src/core/tsi/ssl/session_cache/ssl_session.h"
66
72
  #include "src/core/tsi/ssl/session_cache/ssl_session_cache.h"
67
73
  #include "src/core/tsi/ssl_transport_security_utils.h"
68
74
  #include "src/core/tsi/ssl_types.h"
69
75
  #include "src/core/tsi/transport_security.h"
70
76
  #include "src/core/tsi/transport_security_interface.h"
71
- #include "src/core/util/env.h"
72
77
  #include "src/core/util/grpc_check.h"
73
78
  #include "src/core/util/match.h"
79
+ #include "src/core/util/memory.h"
74
80
  #include "src/core/util/ref_counted.h"
75
81
  #include "src/core/util/ref_counted_ptr.h"
82
+ #include "src/core/util/status_helper.h"
76
83
  #include "src/core/util/sync.h"
77
84
  #include "src/core/util/useful.h"
78
85
  #include "absl/base/thread_annotations.h"
79
86
  #include "absl/functional/bind_front.h"
80
87
  #include "absl/log/log.h"
88
+ #include "absl/status/status.h"
81
89
  #include "absl/strings/match.h"
82
- #include "absl/strings/numbers.h"
83
90
  #include "absl/strings/str_cat.h"
91
+ #include "absl/strings/str_format.h"
84
92
  #include "absl/strings/str_join.h"
85
93
  #include "absl/strings/string_view.h"
86
-
87
- // Name of the environment variable controlling OpenSSL cleanup timeout.
88
- // This variable allows users to specify the timeout (in seconds) for OpenSSL
89
- // resource cleanup during gRPC shutdown. If not set, a default timeout is used.
90
- #define GRPC_ARG_OPENSSL_CLEANUP_TIMEOUT_ENV "grpc.openssl_cleanup_timeout"
94
+ #include "absl/time/time.h"
91
95
 
92
96
  // --- Constants. ---
93
97
 
@@ -96,6 +100,12 @@
96
100
  #define TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND 1024
97
101
  #define TSI_SSL_HANDSHAKER_OUTGOING_BUFFER_INITIAL_SIZE 1024
98
102
  const size_t kMaxChainLength = 100;
103
+ const char kDefaultBoringSSLKeyExchangeGroups[] =
104
+ "X25519MLKEM768:X25519:P-256:P-384:P-521";
105
+ [[maybe_unused]] const char kDefaultOpenSSL1_1_1KeyExchangeGroups[] =
106
+ "X25519:P-256:P-384:P-521";
107
+ [[maybe_unused]] const char kDefaultOpenSSL1_0_2KeyExchangeGroups[] =
108
+ "P-256:P-384:P-521";
99
109
 
100
110
  // Putting a macro like this and littering the source file with #if is really
101
111
  // bad practice.
@@ -109,7 +119,14 @@ const size_t kMaxChainLength = 100;
109
119
  #define TSI_SSL_MAX_PROTECTION_OVERHEAD 100
110
120
 
111
121
  using TlsSessionKeyLogger = tsi::TlsSessionKeyLoggerCache::TlsSessionKeyLogger;
112
-
122
+ #if defined(OPENSSL_IS_BORINGSSL)
123
+ using SelectCertificateInfo =
124
+ grpc_core::CertificateSelector::SelectCertificateInfo;
125
+ using SelectCertificateResult =
126
+ grpc_core::CertificateSelector::SelectCertificateResult;
127
+ using AsyncCertificateSelectionHandle =
128
+ grpc_core::CertificateSelector::AsyncCertificateSelectionHandle;
129
+ #endif
113
130
  using tsi::PrivateKey;
114
131
  using tsi::RootCertInfo;
115
132
 
@@ -169,6 +186,9 @@ struct tsi_ssl_server_handshaker_factory {
169
186
  size_t alpn_protocol_list_length;
170
187
  grpc_core::RefCountedPtr<TlsSessionKeyLogger> key_logger;
171
188
  std::shared_ptr<tsi::RootCertInfo> root_cert_info;
189
+ #if defined(OPENSSL_IS_BORINGSSL)
190
+ std::shared_ptr<grpc_core::CertificateSelector> certificate_selector;
191
+ #endif // defined(OPENSSL_IS_BORINGSSL)
172
192
  };
173
193
 
174
194
  // Tracks the arguments for a pending call to tsi_handshaker_next().
@@ -188,7 +208,27 @@ struct HandshakerNextArgs {
188
208
 
189
209
  struct tsi_ssl_handshaker : public tsi_handshaker,
190
210
  public grpc_core::RefCounted<tsi_ssl_handshaker> {
191
- tsi_ssl_handshaker() = default;
211
+ tsi_ssl_handshaker(
212
+ const tsi_handshaker_vtable* handshaker_vtable, SSL* ssl, BIO* network_io,
213
+ tsi_ssl_handshaker_factory* factory_ref,
214
+ grpc_core::RefCountedPtr<grpc_core::CollectionScope> collection_scope,
215
+ bool is_client, std::shared_ptr<grpc_core::PrivateKeySigner> signer)
216
+ : tsi_handshaker(handshaker_vtable),
217
+ ssl(ssl),
218
+ network_io(network_io),
219
+ result(TSI_HANDSHAKE_IN_PROGRESS),
220
+ outgoing_bytes_buffer_size(
221
+ TSI_SSL_HANDSHAKER_OUTGOING_BUFFER_INITIAL_SIZE),
222
+ outgoing_bytes_buffer(static_cast<unsigned char*>(
223
+ gpr_zalloc(outgoing_bytes_buffer_size))),
224
+ factory_ref(factory_ref),
225
+ collection_scope(std::move(collection_scope)),
226
+ is_client(is_client) {
227
+ #if defined(OPENSSL_IS_BORINGSSL)
228
+ key_signer = std::move(signer);
229
+ #endif
230
+ }
231
+
192
232
  ~tsi_ssl_handshaker() override {
193
233
  SSL_free(ssl);
194
234
  BIO_free(network_io);
@@ -199,9 +239,10 @@ struct tsi_ssl_handshaker : public tsi_handshaker,
199
239
  SSL* ssl;
200
240
  BIO* network_io;
201
241
  tsi_result result;
202
- unsigned char* outgoing_bytes_buffer;
203
242
  size_t outgoing_bytes_buffer_size;
243
+ unsigned char* outgoing_bytes_buffer;
204
244
  tsi_ssl_handshaker_factory* factory_ref;
245
+ grpc_core::RefCountedPtr<grpc_core::CollectionScope> collection_scope;
205
246
  grpc_core::Mutex mu;
206
247
  bool is_shutdown ABSL_GUARDED_BY(mu) = false;
207
248
 
@@ -214,8 +255,16 @@ struct tsi_ssl_handshaker : public tsi_handshaker,
214
255
  if (handshaker_next_args->error_ptr == nullptr) return;
215
256
  *handshaker_next_args->error_ptr = std::move(error);
216
257
  }
258
+ bool is_client = false;
217
259
  #if defined(OPENSSL_IS_BORINGSSL)
218
- std::shared_ptr<grpc_core::PrivateKeySigner> key_signer;
260
+ std::shared_ptr<AsyncCertificateSelectionHandle> cert_selection_handle
261
+ ABSL_GUARDED_BY(mu);
262
+ // Will be set if the certificate selector is used and the asynchronous cert
263
+ // selection is done.
264
+ std::optional<absl::Status> cert_selection_status ABSL_GUARDED_BY(mu);
265
+ // This may be from the factory, or from the certificate selection result when
266
+ // the certificate selector is used.
267
+ std::shared_ptr<grpc_core::PrivateKeySigner> key_signer ABSL_GUARDED_BY(mu);
219
268
  // The signed_bytes are populated when the signature process is completed if
220
269
  // the Private Key offload was successful. If there was an error during the
221
270
  // signature, the status will be returned.
@@ -367,6 +416,73 @@ int ServerHandshakerFactoryAlpnCallback(SSL* /*ssl*/, const unsigned char** out,
367
416
  factory->alpn_protocol_list_length);
368
417
  }
369
418
  #endif // TSI_OPENSSL_ALPN_SUPPORT
419
+
420
+ // Populates the key exchange groups.
421
+ // Prefers the key exchange groups (input argument) configured by the user,
422
+ // otherwise uses the following defaults:
423
+ // - BoringSSL: {X25519MLKEM768, X25519, P-256, P-384, P-521}
424
+ // - OpenSSL < 3.0: {X25519, P-256, P-384, P-521}
425
+ // - OpenSSL >= 3: OpenSSL Defaults (prefers X25519MLKEM768 in OpenSSL 3.5+)
426
+ tsi_result SetKeyExchangeGroups(
427
+ SSL_CTX* context,
428
+ const std::vector<grpc_tls_key_exchange_group>& key_exchange_groups) {
429
+ // Explicitly set the key exchange groups based on user-provided preferences.
430
+ if (!key_exchange_groups.empty()) {
431
+ std::vector<absl::string_view> group_names;
432
+ group_names.reserve(key_exchange_groups.size());
433
+ for (const auto& group : key_exchange_groups) {
434
+ auto group_name = tsi::ConvertKeyExchangeGroupToString(group);
435
+ if (!group_name.ok()) {
436
+ LOG(ERROR) << "Could not convert key exchange group to string: "
437
+ << group;
438
+ return TSI_INVALID_ARGUMENT;
439
+ }
440
+ group_names.push_back(*group_name);
441
+ }
442
+ #if OPENSSL_VERSION_NUMBER >= 0x10101000L
443
+ std::string group_list_str = absl::StrJoin(group_names, ":");
444
+ if (!SSL_CTX_set1_groups_list(context, group_list_str.c_str())) {
445
+ LOG(ERROR) << "Could not set key exchange groups: " << group_list_str;
446
+ return TSI_INTERNAL_ERROR;
447
+ }
448
+ SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
449
+ #else
450
+
451
+ LOG(ERROR) << "Setting TLS key exchange groups is not supported when "
452
+ "building against OpenSSL versions < 1.1.1.";
453
+ return TSI_FAILED_PRECONDITION;
454
+ #endif // OPENSSL_VERSION_NUMBER >= 0x10100000
455
+ } else {
456
+ // Use defaults
457
+ #if defined(OPENSSL_IS_BORINGSSL)
458
+ if (!SSL_CTX_set1_groups_list(context,
459
+ kDefaultBoringSSLKeyExchangeGroups)) {
460
+ LOG(ERROR) << "Could not set default key exchange groups for BoringSSL.";
461
+ return TSI_INTERNAL_ERROR;
462
+ }
463
+ #elif OPENSSL_VERSION_NUMBER < 0x30000000L && \
464
+ OPENSSL_VERSION_NUMBER >= 0x10101000L
465
+ if (!SSL_CTX_set1_groups_list(context,
466
+ kDefaultOpenSSL1_1_1KeyExchangeGroups)) {
467
+ LOG(ERROR)
468
+ << "Could not set default key exchange groups for OpenSSL 1.1.1.";
469
+ return TSI_INTERNAL_ERROR;
470
+ }
471
+ #elif OPENSSL_VERSION_NUMBER < 0x10101000L
472
+ if (!SSL_CTX_set1_curves_list(context,
473
+ kDefaultOpenSSL1_0_2KeyExchangeGroups)) {
474
+ LOG(ERROR)
475
+ << "Could not set default key exchange groups for OpenSSL 1.0.2.";
476
+ return TSI_INTERNAL_ERROR;
477
+ }
478
+ if (!SSL_CTX_set_ecdh_auto(context, /*onoff=*/1)) {
479
+ LOG(ERROR) << "Could not set ecdh auto for OpenSSL 1.0.2.";
480
+ return TSI_INTERNAL_ERROR;
481
+ }
482
+ #endif
483
+ }
484
+ return TSI_OK;
485
+ }
370
486
  } // namespace
371
487
 
372
488
  static gpr_once g_init_openssl_once = GPR_ONCE_INIT;
@@ -487,13 +603,174 @@ const SSL_PRIVATE_KEY_METHOD TlsOffloadPrivateKeyMethod = {
487
603
  TlsPrivateKeySignWrapper,
488
604
  nullptr, // decrypt not implemented for this use case
489
605
  TlsPrivateKeyOffloadComplete};
606
+
607
+ SelectCertificateInfo PrepareSelectCertificateInfo(
608
+ const SSL_CLIENT_HELLO* client_hello) {
609
+ SelectCertificateInfo select_cert_info;
610
+ const char* sni =
611
+ SSL_get_servername(client_hello->ssl, TLSEXT_NAMETYPE_host_name);
612
+ if (sni != nullptr) {
613
+ select_cert_info.sni = sni;
614
+ } else {
615
+ VLOG(2) << "Client did not provide SNI for cert selection.";
616
+ }
617
+ return select_cert_info;
618
+ }
619
+
620
+ absl::Status ProcessSelectCertificateResult(tsi_ssl_handshaker* handshaker,
621
+ SelectCertificateResult result)
622
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&tsi_ssl_handshaker::mu) {
623
+ if (result.certificate_chain.empty()) {
624
+ return absl::InvalidArgumentError("The cert chain is empty.");
625
+ }
626
+ std::vector<CRYPTO_BUFFER*> cert_chain;
627
+ cert_chain.reserve(result.certificate_chain.size());
628
+ for (auto& raw_cert : result.certificate_chain) {
629
+ cert_chain.push_back(raw_cert.get());
630
+ }
631
+ return grpc_core::MatchMutable(
632
+ &result.private_key,
633
+ [&](bssl::UniquePtr<EVP_PKEY>* key) {
634
+ VLOG(2) << "Select cert result returned a static private key.";
635
+ if (!SSL_set_chain_and_key(handshaker->ssl, cert_chain.data(),
636
+ cert_chain.size(), key->get(),
637
+ /*privkey_method=*/nullptr)) {
638
+ return absl::InternalError(
639
+ absl::StrFormat("Failed to set chain and key: %s",
640
+ tsi::SslErrorString(SSL_get_error(
641
+ handshaker->ssl, /*ret_code=*/0))));
642
+ }
643
+ return absl::OkStatus();
644
+ },
645
+ [&](std::shared_ptr<grpc_core::PrivateKeySigner>* signer)
646
+ ABSL_NO_THREAD_SAFETY_ANALYSIS {
647
+ VLOG(2) << "Select cert result returned a private key signer.";
648
+ handshaker->key_signer = std::move(*signer);
649
+ if (!SSL_set_chain_and_key(
650
+ handshaker->ssl, cert_chain.data(), cert_chain.size(),
651
+ /*privkey=*/nullptr, &TlsOffloadPrivateKeyMethod)) {
652
+ return absl::InternalError(
653
+ absl::StrFormat("Failed to set chain and key: %s",
654
+ tsi::SslErrorString(SSL_get_error(
655
+ handshaker->ssl, /*ret_code=*/0))));
656
+ }
657
+ return absl::OkStatus();
658
+ });
659
+ }
660
+
661
+ // Invoked by the cert selector when it runs asynchronously.
662
+ void OnSelectCertificateDone(
663
+ grpc_core::RefCountedPtr<tsi_ssl_handshaker> handshaker,
664
+ absl::StatusOr<SelectCertificateResult> result) {
665
+ grpc_core::ExecCtx exec_ctx;
666
+ tsi_result next_result;
667
+ std::optional<HandshakerNextArgs> next_args;
668
+ {
669
+ grpc_core::MutexLock lock(&handshaker->mu);
670
+ if (handshaker->is_shutdown) return;
671
+ if (!result.ok()) {
672
+ VLOG(2) << "SelectCertificate failed " << result.status();
673
+ handshaker->cert_selection_status = std::move(result).status();
674
+ } else {
675
+ handshaker->cert_selection_status =
676
+ ProcessSelectCertificateResult(handshaker.get(), *std::move(result));
677
+ }
678
+ handshaker->cert_selection_handle.reset();
679
+ auto async_result = ssl_handshaker_next_async(handshaker.get());
680
+ next_result = async_result.first;
681
+ next_args = std::move(async_result.second);
682
+ }
683
+ // If result is not TSI_ASYNC and there are args, we are ready to flush.
684
+ if (next_result != TSI_ASYNC && next_args.has_value() &&
685
+ next_args->cb != nullptr) {
686
+ next_args->cb(next_result, next_args->user_data, next_args->bytes_to_send,
687
+ next_args->bytes_to_send_size, next_args->handshaker_result);
688
+ }
689
+ }
690
+
691
+ grpc_core::CertificateSelector* GetCertificateSelector(
692
+ tsi_ssl_handshaker* handshaker) {
693
+ if (handshaker->is_client) {
694
+ return nullptr;
695
+ }
696
+ return reinterpret_cast<tsi_ssl_server_handshaker_factory*>(
697
+ handshaker->factory_ref)
698
+ ->certificate_selector.get();
699
+ }
700
+
701
+ // Invoked by BoringSSL to get the result of cert selection.
702
+ ssl_select_cert_result_t SelectCertificateCallback(
703
+ const SSL_CLIENT_HELLO* client_hello)
704
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&tsi_ssl_handshaker::mu) {
705
+ tsi_ssl_handshaker* handshaker = GetHandshaker(client_hello->ssl);
706
+ // Sanity check. Should never happen.
707
+ if (handshaker == nullptr || client_hello == nullptr) {
708
+ handshaker->MaybeSetError(
709
+ "SelectCertificateCallback failed because handshaker or client_hello "
710
+ "is nullptr; this should never happen.");
711
+ return ssl_select_cert_error;
712
+ }
713
+ grpc_core::CertificateSelector* cert_selector =
714
+ GetCertificateSelector(handshaker);
715
+ if (cert_selector == nullptr) {
716
+ handshaker->MaybeSetError(
717
+ "SelectCertificateCallback failed because certificate selector "
718
+ "is nullptr; this should never happen.");
719
+ return ssl_select_cert_error;
720
+ }
721
+ // The async cert selection is finished.
722
+ if (handshaker->cert_selection_status.has_value()) {
723
+ if (!handshaker->cert_selection_status->ok()) {
724
+ VLOG(2) << "Async cert selection failed: "
725
+ << *handshaker->cert_selection_status;
726
+ handshaker->MaybeSetError(handshaker->cert_selection_status->ToString());
727
+ return ssl_select_cert_error;
728
+ }
729
+ // The cert selection is done.
730
+ return ssl_select_cert_success;
731
+ }
732
+ // The callback holds a ref to the handshaker to ensure it's not destroyed
733
+ // when the callback is invoked asynchronously.
734
+ std::variant<absl::StatusOr<SelectCertificateResult>,
735
+ std::shared_ptr<AsyncCertificateSelectionHandle>>
736
+ result = cert_selector->SelectCertificate(
737
+ PrepareSelectCertificateInfo(client_hello),
738
+ absl::bind_front(OnSelectCertificateDone, handshaker->Ref()));
739
+ // The outer function guarantees the mutex lock, and we have to disable the
740
+ // absl thread safety analysis because the use of MatchMutable.
741
+ return grpc_core::MatchMutable(
742
+ &result,
743
+ [&](absl::StatusOr<SelectCertificateResult>* select_cert_result)
744
+ ABSL_NO_THREAD_SAFETY_ANALYSIS {
745
+ if (!select_cert_result->ok()) {
746
+ VLOG(2) << "Sync select cert failed: "
747
+ << select_cert_result->status();
748
+ handshaker->MaybeSetError(
749
+ select_cert_result->status().ToString());
750
+ return ssl_select_cert_error;
751
+ }
752
+ absl::Status status = ProcessSelectCertificateResult(
753
+ handshaker, *std::move(*select_cert_result));
754
+ if (!status.ok()) {
755
+ LOG(INFO) << "Sync select cert failed: " << status;
756
+ handshaker->MaybeSetError(status.ToString());
757
+ return ssl_select_cert_error;
758
+ }
759
+ return ssl_select_cert_success;
760
+ },
761
+ [&](std::shared_ptr<AsyncCertificateSelectionHandle>* async_handle)
762
+ ABSL_NO_THREAD_SAFETY_ANALYSIS {
763
+ handshaker->cert_selection_handle = std::move(*async_handle);
764
+ return ssl_select_cert_retry;
765
+ });
766
+ }
490
767
  #endif // defined(OPENSSL_IS_BORINGSSL)
491
768
 
492
769
  #if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_NO_ENGINE)
493
770
  static const char kSslEnginePrefix[] = "engine:";
494
771
  #endif
495
772
 
496
- #if OPENSSL_VERSION_NUMBER < 0x10100000
773
+ #if OPENSSL_VERSION_NUMBER < 0x10101000L
497
774
  static gpr_mu* g_openssl_mutexes = nullptr;
498
775
  static void openssl_locking_cb(int mode, int type, const char* file,
499
776
  int line) GRPC_UNUSED;
@@ -519,39 +796,14 @@ static void verified_root_cert_free(void* /*parent*/, void* ptr,
519
796
  }
520
797
 
521
798
  static void init_openssl(void) {
522
- #if OPENSSL_VERSION_NUMBER >= 0x10100000
523
- OPENSSL_init_ssl(0, nullptr);
524
- // Ensure OPENSSL global clean up happens after gRPC shutdown completes.
525
- // OPENSSL registers an exit handler to clean up global objects, which
526
- // otherwise may happen before gRPC removes all references to OPENSSL. Below
527
- // exit handler is guaranteed to run after OPENSSL's.
528
- std::atexit([]() {
529
- // Retrieve the OpenSSL cleanup timeout from the environment variable.
530
- // This allows users to override the default cleanup timeout for OpenSSL
531
- // resource deallocation during gRPC shutdown.
532
- std::optional<std::string> env =
533
- grpc_core::GetEnv(GRPC_ARG_OPENSSL_CLEANUP_TIMEOUT_ENV);
534
- int timeout_sec = 2;
535
- if (env.has_value()) {
536
- int parsed_timeout_sec = 0;
537
- if (absl::SimpleAtoi(*env, &parsed_timeout_sec)) {
538
- timeout_sec = parsed_timeout_sec;
539
- } else {
540
- GRPC_TRACE_LOG(tsi, ERROR)
541
- << "Invalid value [" << (*env) << "] for "
542
- << GRPC_ARG_OPENSSL_CLEANUP_TIMEOUT_ENV
543
- << " environment variable. Using default value of 2 seconds.";
544
- }
545
- }
546
-
547
- grpc_wait_for_shutdown_with_timeout(absl::Seconds(timeout_sec));
548
- });
799
+ #if OPENSSL_VERSION_NUMBER >= 0x10101000L
800
+ OPENSSL_init_ssl(OPENSSL_INIT_NO_ATEXIT, nullptr);
549
801
  #else
550
802
  SSL_library_init();
551
803
  SSL_load_error_strings();
552
804
  OpenSSL_add_all_algorithms();
553
805
  #endif
554
- #if OPENSSL_VERSION_NUMBER < 0x10100000
806
+ #if OPENSSL_VERSION_NUMBER < 0x10101000L
555
807
  if (!CRYPTO_get_locking_callback()) {
556
808
  int num_locks = CRYPTO_num_locks();
557
809
  GRPC_CHECK_GT(num_locks, 0);
@@ -1195,40 +1447,9 @@ static tsi_result populate_ssl_context(
1195
1447
  LOG(ERROR) << "Invalid cipher list: " << cipher_list;
1196
1448
  return TSI_INVALID_ARGUMENT;
1197
1449
  }
1198
- if (!key_exchange_groups.empty()) {
1199
- std::vector<absl::string_view> group_names;
1200
- group_names.reserve(key_exchange_groups.size());
1201
- for (const auto& group : key_exchange_groups) {
1202
- auto group_name = tsi::ConvertKeyExchangeGroupToString(group);
1203
- if (!group_name.ok()) {
1204
- LOG(ERROR) << "Could not convert key exchange group to string.";
1205
- return TSI_INVALID_ARGUMENT;
1206
- }
1207
- group_names.push_back(*group_name);
1208
- }
1209
- #if OPENSSL_VERSION_NUMBER >= 0x10101000L
1210
- std::string group_list_str = absl::StrJoin(group_names, ":");
1211
- if (!SSL_CTX_set1_groups_list(context, group_list_str.c_str())) {
1212
- LOG(ERROR) << "Could not set key exchange groups: " << group_list_str;
1213
- return TSI_INTERNAL_ERROR;
1214
- }
1215
- SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
1216
- #else
1217
- LOG(ERROR) << "SSL_CTX_set1_groups is not supported in OpenSSL < 1.1.1 "
1218
- "version.";
1219
- return TSI_FAILED_PRECONDITION;
1220
- #endif // OPENSSL_VERSION_NUMBER >= 0x10100000
1221
- } else {
1222
- #if OPENSSL_VERSION_NUMBER < 0x30000000L
1223
- EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
1224
- if (!SSL_CTX_set_tmp_ecdh(context, ecdh)) {
1225
- LOG(ERROR) << "Could not set ephemeral ECDH key.";
1226
- EC_KEY_free(ecdh);
1227
- return TSI_INTERNAL_ERROR;
1228
- }
1229
- SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
1230
- EC_KEY_free(ecdh);
1231
- #endif
1450
+ result = SetKeyExchangeGroups(context, key_exchange_groups);
1451
+ if (result != TSI_OK) {
1452
+ return result;
1232
1453
  }
1233
1454
  return TSI_OK;
1234
1455
  }
@@ -1934,6 +2155,12 @@ static tsi_result ssl_handshaker_result_extract_peer(
1934
2155
  if (alpn_selected != nullptr) new_property_count++;
1935
2156
  if (peer_chain != nullptr) new_property_count++;
1936
2157
  if (verified_root_cert != nullptr) new_property_count++;
2158
+ #if defined(OPENSSL_IS_BORINGSSL) || OPENSSL_VERSION_NUMBER >= 0x30000000L
2159
+ int nid = SSL_get_negotiated_group(impl->ssl);
2160
+ const char* negotiated_group_name =
2161
+ (nid != NID_undef && nid != 0) ? OBJ_nid2sn(nid) : nullptr;
2162
+ if (negotiated_group_name != nullptr) new_property_count++;
2163
+ #endif
1937
2164
  tsi_peer_property* new_properties = static_cast<tsi_peer_property*>(
1938
2165
  gpr_zalloc(sizeof(*new_properties) * new_property_count));
1939
2166
  for (size_t i = 0; i < peer->property_count; i++) {
@@ -1980,6 +2207,16 @@ static tsi_result ssl_handshaker_result_extract_peer(
1980
2207
  peer->property_count++;
1981
2208
  }
1982
2209
 
2210
+ #if defined(OPENSSL_IS_BORINGSSL) || OPENSSL_VERSION_NUMBER >= 0x30000000L
2211
+ if (negotiated_group_name != nullptr) {
2212
+ result = tsi_construct_string_peer_property_from_cstring(
2213
+ TSI_SSL_NEGOTIATED_KEY_EXCHANGE_GROUP, negotiated_group_name,
2214
+ &peer->properties[peer->property_count]);
2215
+ if (result != TSI_OK) return result;
2216
+ peer->property_count++;
2217
+ }
2218
+ #endif
2219
+
1983
2220
  return result;
1984
2221
  }
1985
2222
 
@@ -2147,6 +2384,8 @@ static tsi_result ssl_handshaker_do_handshake(tsi_ssl_handshaker* impl)
2147
2384
  #if defined(OPENSSL_IS_BORINGSSL)
2148
2385
  case SSL_ERROR_WANT_PRIVATE_KEY_OPERATION:
2149
2386
  return TSI_ASYNC;
2387
+ case SSL_ERROR_PENDING_CERTIFICATE:
2388
+ return TSI_ASYNC;
2150
2389
  #endif
2151
2390
  default: {
2152
2391
  char err_str[256];
@@ -2308,10 +2547,11 @@ static tsi_result ssl_handshaker_next_impl(tsi_ssl_handshaker* self)
2308
2547
  self->handshaker_next_args->received_bytes.clear();
2309
2548
  }
2310
2549
  #if defined(OPENSSL_IS_BORINGSSL)
2311
- } else if (self->key_signer != nullptr) {
2312
- // During the PrivateKeyOffload signature, an empty call to
2313
- // ssl_handshaker_do_handshake needs to be forced after the async offload
2314
- // has completed.
2550
+ } else if (self->key_signer != nullptr ||
2551
+ GetCertificateSelector(self) != nullptr) {
2552
+ // After an asynchronous certificate selection offload or private key
2553
+ // offload, another call to ssl_handshaker_do_handshake needs to be
2554
+ // triggered to continue the SSL handshake.
2315
2555
  status = ssl_handshaker_do_handshake(self);
2316
2556
  #endif
2317
2557
  }
@@ -2434,23 +2674,41 @@ static tsi_result ssl_handshaker_next(
2434
2674
  static void ssl_handshaker_shutdown(tsi_handshaker* self) {
2435
2675
  #if defined(OPENSSL_IS_BORINGSSL)
2436
2676
  tsi_ssl_handshaker* impl = static_cast<tsi_ssl_handshaker*>(self);
2677
+ std::shared_ptr<grpc_core::PrivateKeySigner> key_signer;
2437
2678
  std::shared_ptr<grpc_core::PrivateKeySigner::AsyncSigningHandle>
2438
2679
  signing_handle;
2680
+ std::shared_ptr<AsyncCertificateSelectionHandle> cert_selection_handle;
2439
2681
  std::optional<HandshakerNextArgs> next_args;
2440
2682
  {
2441
2683
  grpc_core::MutexLock lock(&impl->mu);
2442
2684
  if (impl->ssl == nullptr) return;
2443
2685
  impl->is_shutdown = true;
2444
2686
  if (impl->key_signer != nullptr && impl->signing_handle != nullptr) {
2687
+ key_signer = std::move(impl->key_signer);
2445
2688
  signing_handle = std::move(impl->signing_handle);
2446
2689
  }
2690
+ if (GetCertificateSelector(impl) != nullptr &&
2691
+ impl->cert_selection_handle != nullptr) {
2692
+ cert_selection_handle = std::move(impl->cert_selection_handle);
2693
+ }
2447
2694
  if (impl->handshaker_next_args.has_value()) {
2448
2695
  next_args = std::move(*impl->handshaker_next_args);
2449
2696
  impl->handshaker_next_args.reset();
2450
2697
  }
2451
2698
  }
2452
- if (signing_handle != nullptr) {
2453
- impl->key_signer->Cancel(signing_handle);
2699
+ // We must not invoke these Cancel functions while holding the mutex because
2700
+ // this could lead to a deadlock due to mutexes being acquired in reverse
2701
+ // order in different threads. In one thread, the key signer or cert selector
2702
+ // plugin may be holding its own mutex while it invokes the on_complete
2703
+ // callback, which will then acquire the mutex here. So we can't also be
2704
+ // holding the mutex here while calling the plugin's Cancel method, which may
2705
+ // need to acquire its own mutex.
2706
+ if (key_signer != nullptr) {
2707
+ key_signer->Cancel(signing_handle);
2708
+ }
2709
+ if (cert_selection_handle != nullptr) {
2710
+ reinterpret_cast<tsi_ssl_server_handshaker_factory*>(impl->factory_ref)
2711
+ ->certificate_selector->Cancel(cert_selection_handle);
2454
2712
  }
2455
2713
  if (next_args.has_value()) {
2456
2714
  grpc_event_engine::experimental::GetDefaultEventEngine()->Run(
@@ -2494,15 +2752,16 @@ static void tsi_ssl_handshaker_resume_session(
2494
2752
  }
2495
2753
 
2496
2754
  static tsi_result create_tsi_ssl_handshaker(
2497
- SSL_CTX* ctx, int is_client, const char* server_name_indication,
2755
+ SSL_CTX* ctx, bool is_client, const char* server_name_indication,
2498
2756
  size_t network_bio_buf_size, size_t ssl_bio_buf_size,
2499
2757
  std::optional<std::string> alpn_preferred_protocol_raw_list,
2500
2758
  std::shared_ptr<grpc_core::PrivateKeySigner> key_signer,
2501
- tsi_ssl_handshaker_factory* factory, tsi_handshaker** handshaker) {
2759
+ tsi_ssl_handshaker_factory* factory,
2760
+ grpc_core::RefCountedPtr<grpc_core::CollectionScope> collection_scope,
2761
+ tsi_handshaker** handshaker) {
2502
2762
  SSL* ssl = SSL_new(ctx);
2503
2763
  BIO* network_io = nullptr;
2504
2764
  BIO* ssl_io = nullptr;
2505
- tsi_ssl_handshaker* impl = nullptr;
2506
2765
  *handshaker = nullptr;
2507
2766
  if (ctx == nullptr) {
2508
2767
  LOG(ERROR) << "SSL Context is null. Should never happen.";
@@ -2592,20 +2851,10 @@ static tsi_result create_tsi_ssl_handshaker(
2592
2851
  SSL_set_accept_state(ssl);
2593
2852
  }
2594
2853
 
2595
- impl = new tsi_ssl_handshaker();
2596
- impl->ssl = ssl;
2597
- impl->network_io = network_io;
2598
- impl->result = TSI_HANDSHAKE_IN_PROGRESS;
2599
- impl->outgoing_bytes_buffer_size =
2600
- TSI_SSL_HANDSHAKER_OUTGOING_BUFFER_INITIAL_SIZE;
2601
- impl->outgoing_bytes_buffer =
2602
- static_cast<unsigned char*>(gpr_zalloc(impl->outgoing_bytes_buffer_size));
2603
- impl->vtable = &handshaker_vtable;
2604
- impl->factory_ref = tsi_ssl_handshaker_factory_ref(factory);
2605
- #if defined(OPENSSL_IS_BORINGSSL)
2606
- impl->key_signer = std::move(key_signer);
2607
- #endif
2608
-
2854
+ tsi_ssl_handshaker* impl = new tsi_ssl_handshaker(
2855
+ &handshaker_vtable, ssl, network_io,
2856
+ tsi_ssl_handshaker_factory_ref(factory), std::move(collection_scope),
2857
+ is_client, std::move(key_signer));
2609
2858
  *handshaker = impl;
2610
2859
 
2611
2860
  if (!SSL_set_ex_data(ssl, g_ssl_ex_handshaker_index, impl)) {
@@ -2650,20 +2899,19 @@ tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
2650
2899
  const char* server_name_indication, size_t network_bio_buf_size,
2651
2900
  size_t ssl_bio_buf_size,
2652
2901
  std::optional<std::string> alpn_preferred_protocol_list,
2902
+ grpc_core::RefCountedPtr<grpc_core::CollectionScope> collection_scope,
2653
2903
  tsi_handshaker** handshaker) {
2654
2904
  GRPC_TRACE_LOG(tsi, INFO)
2655
2905
  << "Creating SSL handshaker with SNI " << server_name_indication;
2906
+ std::shared_ptr<grpc_core::PrivateKeySigner> key_signer;
2656
2907
  #if defined(OPENSSL_IS_BORINGSSL)
2657
- return create_tsi_ssl_handshaker(
2658
- factory->ssl_context, 1, server_name_indication, network_bio_buf_size,
2659
- ssl_bio_buf_size, alpn_preferred_protocol_list, factory->key_signer,
2660
- &factory->base, handshaker);
2661
- #else
2662
- return create_tsi_ssl_handshaker(
2663
- factory->ssl_context, 1, server_name_indication, network_bio_buf_size,
2664
- ssl_bio_buf_size, alpn_preferred_protocol_list, /*key_signer=*/nullptr,
2665
- &factory->base, handshaker);
2908
+ key_signer = factory->key_signer;
2666
2909
  #endif
2910
+ return create_tsi_ssl_handshaker(
2911
+ factory->ssl_context, /*is_client=*/true, server_name_indication,
2912
+ network_bio_buf_size, ssl_bio_buf_size, alpn_preferred_protocol_list,
2913
+ std::move(key_signer), &factory->base, std::move(collection_scope),
2914
+ handshaker);
2667
2915
  }
2668
2916
 
2669
2917
  void tsi_ssl_client_handshaker_factory_unref(
@@ -2703,23 +2951,23 @@ static int client_handshaker_factory_npn_callback(
2703
2951
 
2704
2952
  tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
2705
2953
  tsi_ssl_server_handshaker_factory* factory, size_t network_bio_buf_size,
2706
- size_t ssl_bio_buf_size, tsi_handshaker** handshaker) {
2954
+ size_t ssl_bio_buf_size,
2955
+ grpc_core::RefCountedPtr<grpc_core::CollectionScope> collection_scope,
2956
+ tsi_handshaker** handshaker) {
2707
2957
  if (factory->ssl_contexts.empty()) return TSI_INVALID_ARGUMENT;
2708
- #if defined(OPENSSL_IS_BORINGSSL)
2709
2958
  // Create the handshaker with the first context. We will switch if needed
2710
2959
  // because of SNI in ssl_server_handshaker_factory_servername_callback.
2711
2960
  // Likewise, we pass the private key signer corresponding to the first
2712
2961
  // context.
2713
- return create_tsi_ssl_handshaker(
2714
- factory->ssl_contexts[0].ssl_ctx, 0, nullptr, network_bio_buf_size,
2715
- ssl_bio_buf_size, std::nullopt, factory->ssl_contexts[0].key_signer,
2716
- &factory->base, handshaker);
2717
- #else
2718
- return create_tsi_ssl_handshaker(factory->ssl_contexts[0].ssl_ctx, 0, nullptr,
2719
- network_bio_buf_size, ssl_bio_buf_size,
2720
- std::nullopt, /*key_signer=*/nullptr,
2721
- &factory->base, handshaker);
2962
+ std::shared_ptr<grpc_core::PrivateKeySigner> key_signer;
2963
+ #if defined(OPENSSL_IS_BORINGSSL)
2964
+ key_signer = factory->ssl_contexts[0].key_signer;
2722
2965
  #endif
2966
+ return create_tsi_ssl_handshaker(
2967
+ factory->ssl_contexts[0].ssl_ctx, /*is_client=*/false, nullptr,
2968
+ network_bio_buf_size, ssl_bio_buf_size, std::nullopt,
2969
+ std::move(key_signer), &factory->base, std::move(collection_scope),
2970
+ handshaker);
2723
2971
  }
2724
2972
 
2725
2973
  void tsi_ssl_server_handshaker_factory_unref(
@@ -2779,7 +3027,8 @@ static int does_entry_match_name(absl::string_view entry,
2779
3027
 
2780
3028
  static int ssl_server_handshaker_factory_servername_callback(SSL* ssl,
2781
3029
  int* /*ap*/,
2782
- void* arg) {
3030
+ void* arg)
3031
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&tsi_ssl_handshaker::mu) {
2783
3032
  tsi_ssl_server_handshaker_factory* impl =
2784
3033
  static_cast<tsi_ssl_server_handshaker_factory*>(arg);
2785
3034
  const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
@@ -3058,19 +3307,19 @@ static tsi_ssl_handshaker_factory_vtable server_handshaker_factory_vtable = {
3058
3307
  tsi_ssl_server_handshaker_factory_destroy};
3059
3308
 
3060
3309
  tsi_result tsi_create_ssl_server_handshaker_factory(
3061
- std::vector<tsi_ssl_pem_key_cert_pair> pem_key_cert_pairs,
3310
+ tsi_ssl_key_cert_pairs pem_key_cert_pairs,
3062
3311
  const char* pem_client_root_certs, int force_client_auth,
3063
3312
  const char* cipher_suites, const char** alpn_protocols,
3064
3313
  uint16_t num_alpn_protocols, tsi_ssl_server_handshaker_factory** factory) {
3065
3314
  return tsi_create_ssl_server_handshaker_factory_ex(
3066
- pem_key_cert_pairs, pem_client_root_certs,
3315
+ std::move(pem_key_cert_pairs), pem_client_root_certs,
3067
3316
  force_client_auth ? TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
3068
3317
  : TSI_DONT_REQUEST_CLIENT_CERTIFICATE,
3069
3318
  cipher_suites, alpn_protocols, num_alpn_protocols, factory);
3070
3319
  }
3071
3320
 
3072
3321
  tsi_result tsi_create_ssl_server_handshaker_factory_ex(
3073
- std::vector<tsi_ssl_pem_key_cert_pair> pem_key_cert_pairs,
3322
+ tsi_ssl_key_cert_pairs pem_key_cert_pairs,
3074
3323
  const char* pem_client_root_certs,
3075
3324
  tsi_client_certificate_request_type client_certificate_request,
3076
3325
  const char* cipher_suites, const char** alpn_protocols,
@@ -3089,219 +3338,246 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
3089
3338
  factory);
3090
3339
  }
3091
3340
 
3092
- tsi_result tsi_create_ssl_server_handshaker_factory_with_options(
3341
+ tsi_result tsi_configure_server_ssl_context(
3093
3342
  const tsi_ssl_server_handshaker_options* options,
3094
- tsi_ssl_server_handshaker_factory** factory) {
3095
- tsi_ssl_server_handshaker_factory* impl = nullptr;
3096
- tsi_result result = TSI_OK;
3097
- size_t i = 0;
3343
+ const tsi_ssl_pem_key_cert_pair* pem_key_cert_pair,
3344
+ tsi_ssl_server_handshaker_factory* impl, SslContext& ssl_context) {
3345
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000
3346
+ ssl_context.ssl_ctx = SSL_CTX_new(TLS_method());
3347
+ #else
3348
+ ssl_context.ssl_ctx = SSL_CTX_new(TLSv1_2_method());
3349
+ #endif
3350
+ #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
3351
+ SSL_CTX_set_options(ssl_context.ssl_ctx, SSL_OP_NO_RENEGOTIATION);
3352
+ #endif
3353
+ if (ssl_context.ssl_ctx == nullptr) {
3354
+ tsi::LogSslErrorStack();
3355
+ LOG(ERROR) << "Could not create ssl context.";
3356
+ return TSI_OUT_OF_RESOURCES;
3357
+ }
3098
3358
 
3099
- gpr_once_init(&g_init_openssl_once, init_openssl);
3359
+ tsi_result result = tsi_set_min_and_max_tls_versions(
3360
+ ssl_context.ssl_ctx, options->min_tls_version, options->max_tls_version);
3361
+ if (result != TSI_OK) return result;
3100
3362
 
3101
- if (factory == nullptr) return TSI_INVALID_ARGUMENT;
3102
- *factory = nullptr;
3103
- if (options->pem_key_cert_pairs.empty()) {
3104
- return TSI_INVALID_ARGUMENT;
3363
+ result = populate_ssl_context(ssl_context.ssl_ctx, pem_key_cert_pair,
3364
+ options->cipher_suites,
3365
+ options->key_exchange_groups);
3366
+ #if defined(OPENSSL_IS_BORINGSSL)
3367
+ if (pem_key_cert_pair != nullptr) {
3368
+ grpc_core::Match(
3369
+ pem_key_cert_pair->private_key, [](const std::string&) {},
3370
+ [&](const std::shared_ptr<grpc_core::PrivateKeySigner>& key_signer) {
3371
+ ssl_context.key_signer = key_signer;
3372
+ });
3105
3373
  }
3374
+ #endif
3375
+ if (result != TSI_OK) return result;
3106
3376
 
3107
- impl = new tsi_ssl_server_handshaker_factory();
3108
- tsi_ssl_handshaker_factory_init(&impl->base);
3109
- impl->base.vtable = &server_handshaker_factory_vtable;
3377
+ // TODO(elessar): Provide ability to disable session ticket keys.
3110
3378
 
3111
- if (options->root_cert_info != nullptr) {
3112
- impl->root_cert_info = options->root_cert_info;
3379
+ // Allow client cache sessions (it's needed for OpenSSL only).
3380
+ int set_sid_ctx_result =
3381
+ SSL_CTX_set_session_id_context(ssl_context.ssl_ctx, kSslSessionIdContext,
3382
+ GPR_ARRAY_SIZE(kSslSessionIdContext));
3383
+ if (set_sid_ctx_result == 0) {
3384
+ LOG(ERROR) << "Failed to set session id context.";
3385
+ return TSI_INTERNAL_ERROR;
3113
3386
  }
3114
3387
 
3115
- if (options->num_alpn_protocols > 0) {
3116
- result = BuildAlpnProtocolNameList(
3117
- options->alpn_protocols, options->num_alpn_protocols,
3118
- &impl->alpn_protocol_list, &impl->alpn_protocol_list_length);
3388
+ if (options->session_ticket_key != nullptr) {
3389
+ if (SSL_CTX_set_tlsext_ticket_keys(
3390
+ ssl_context.ssl_ctx, const_cast<char*>(options->session_ticket_key),
3391
+ options->session_ticket_key_size) == 0) {
3392
+ LOG(ERROR) << "Invalid STEK size.";
3393
+ return TSI_INVALID_ARGUMENT;
3394
+ }
3395
+ }
3396
+ if (options->root_cert_info != nullptr) {
3397
+ grpc_core::Match(
3398
+ *options->root_cert_info,
3399
+ [&](const std::string& pem_root_certs) {
3400
+ STACK_OF(X509_NAME)* root_names = nullptr;
3401
+ result = ssl_ctx_load_verification_certs(
3402
+ ssl_context.ssl_ctx, pem_root_certs.c_str(),
3403
+ pem_root_certs.size(), nullptr);
3404
+ if (result != TSI_OK) {
3405
+ LOG(ERROR) << "Invalid verification certs.";
3406
+ }
3407
+ if (options->send_client_ca_list) {
3408
+ SSL_CTX_set_client_CA_list(ssl_context.ssl_ctx, root_names);
3409
+ }
3410
+ },
3411
+ [&](const grpc_core::SpiffeBundleMap& spiffe_bundle_map) {
3412
+ X509_STORE* cert_store = SSL_CTX_get_cert_store(ssl_context.ssl_ctx);
3413
+ X509_STORE_set_flags(cert_store, X509_V_FLAG_PARTIAL_CHAIN |
3414
+ X509_V_FLAG_TRUSTED_FIRST);
3415
+ const void* p = &spiffe_bundle_map;
3416
+ void* map = const_cast<void*>(p);
3417
+ SSL_CTX_set_ex_data(ssl_context.ssl_ctx,
3418
+ g_ssl_ctx_ex_spiffe_bundle_map_index, map);
3419
+ });
3119
3420
  if (result != TSI_OK) {
3120
- tsi_ssl_handshaker_factory_unref(&impl->base);
3121
3421
  return result;
3122
3422
  }
3123
3423
  }
3124
-
3125
- if (options->key_logger != nullptr) {
3126
- impl->key_logger = options->key_logger->Ref();
3424
+ switch (options->client_certificate_request) {
3425
+ case TSI_DONT_REQUEST_CLIENT_CERTIFICATE:
3426
+ SSL_CTX_set_verify(ssl_context.ssl_ctx, SSL_VERIFY_NONE, nullptr);
3427
+ break;
3428
+ case TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
3429
+ SSL_CTX_set_verify(ssl_context.ssl_ctx, SSL_VERIFY_PEER, nullptr);
3430
+ SSL_CTX_set_cert_verify_callback(ssl_context.ssl_ctx, NullVerifyCallback,
3431
+ nullptr);
3432
+ break;
3433
+ case TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
3434
+ SSL_CTX_set_verify(ssl_context.ssl_ctx, SSL_VERIFY_PEER, nullptr);
3435
+ SSL_CTX_set_cert_verify_callback(ssl_context.ssl_ctx,
3436
+ CustomVerificationFunction, nullptr);
3437
+ break;
3438
+ case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
3439
+ SSL_CTX_set_verify(ssl_context.ssl_ctx,
3440
+ SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3441
+ nullptr);
3442
+ SSL_CTX_set_cert_verify_callback(ssl_context.ssl_ctx, NullVerifyCallback,
3443
+ nullptr);
3444
+ break;
3445
+ case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
3446
+ SSL_CTX_set_verify(ssl_context.ssl_ctx,
3447
+ SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3448
+ nullptr);
3449
+ SSL_CTX_set_cert_verify_callback(ssl_context.ssl_ctx,
3450
+ CustomVerificationFunction, nullptr);
3451
+ break;
3127
3452
  }
3128
3453
 
3129
- impl->ssl_contexts.reserve(options->pem_key_cert_pairs.size());
3130
- for (i = 0; i < options->pem_key_cert_pairs.size(); i++) {
3131
- SslContext& ssl_context = impl->ssl_contexts.emplace_back();
3132
- do {
3133
- #if OPENSSL_VERSION_NUMBER >= 0x10100000
3134
- ssl_context.ssl_ctx = SSL_CTX_new(TLS_method());
3135
- #else
3136
- ssl_context.ssl_ctx = SSL_CTX_new(TLSv1_2_method());
3454
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
3455
+ if (options->crl_provider != nullptr) {
3456
+ SSL_CTX_set_ex_data(ssl_context.ssl_ctx, g_ssl_ctx_ex_crl_provider_index,
3457
+ options->crl_provider.get());
3458
+ } else if (options->crl_directory != nullptr &&
3459
+ strcmp(options->crl_directory, "") != 0) {
3460
+ X509_STORE* cert_store = SSL_CTX_get_cert_store(ssl_context.ssl_ctx);
3461
+ X509_STORE_set_verify_cb(cert_store, verify_cb);
3462
+ if (!X509_STORE_load_locations(cert_store, nullptr,
3463
+ options->crl_directory)) {
3464
+ LOG(ERROR) << "Failed to load CRL File from directory.";
3465
+ } else {
3466
+ X509_VERIFY_PARAM* param = X509_STORE_get0_param(cert_store);
3467
+ X509_VERIFY_PARAM_set_flags(
3468
+ param, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
3469
+ }
3470
+ }
3137
3471
  #endif
3472
+
3473
+ if (pem_key_cert_pair != nullptr) {
3474
+ result = tsi_ssl_extract_x509_subject_names_from_pem_cert(
3475
+ pem_key_cert_pair->cert_chain.c_str(), &ssl_context.x509_subject_name);
3476
+ if (result != TSI_OK) return result;
3477
+ SSL_CTX_set_tlsext_servername_callback(
3478
+ ssl_context.ssl_ctx, ssl_server_handshaker_factory_servername_callback);
3479
+ SSL_CTX_set_tlsext_servername_arg(ssl_context.ssl_ctx, impl);
3480
+ }
3481
+ #if TSI_OPENSSL_ALPN_SUPPORT
3482
+ SSL_CTX_set_alpn_select_cb(ssl_context.ssl_ctx,
3483
+ ServerHandshakerFactoryAlpnCallback, impl);
3484
+ #endif // TSI_OPENSSL_ALPN_SUPPORT
3485
+ SSL_CTX_set_next_protos_advertised_cb(
3486
+ ssl_context.ssl_ctx, server_handshaker_factory_npn_advertised_callback,
3487
+ impl);
3488
+
3138
3489
  #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
3139
- SSL_CTX_set_options(ssl_context.ssl_ctx, SSL_OP_NO_RENEGOTIATION);
3490
+ // Register factory at index
3491
+ if (options->key_logger != nullptr) {
3492
+ // Need to set factory at g_ssl_ctx_ex_factory_index
3493
+ SSL_CTX_set_ex_data(ssl_context.ssl_ctx, g_ssl_ctx_ex_factory_index, impl);
3494
+ // SSL_CTX_set_keylog_callback is set here to register callback
3495
+ // when ssl/tls handshakes complete.
3496
+ SSL_CTX_set_keylog_callback(
3497
+ ssl_context.ssl_ctx,
3498
+ ssl_keylogging_callback<tsi_ssl_server_handshaker_factory>);
3499
+ }
3140
3500
  #endif
3141
- if (ssl_context.ssl_ctx == nullptr) {
3142
- tsi::LogSslErrorStack();
3143
- LOG(ERROR) << "Could not create ssl context.";
3144
- result = TSI_OUT_OF_RESOURCES;
3145
- break;
3146
- }
3147
3501
 
3148
- result = tsi_set_min_and_max_tls_versions(ssl_context.ssl_ctx,
3149
- options->min_tls_version,
3150
- options->max_tls_version);
3151
- if (result != TSI_OK) return result;
3502
+ return result;
3503
+ }
3152
3504
 
3153
- result = populate_ssl_context(
3154
- ssl_context.ssl_ctx, &options->pem_key_cert_pairs[i],
3155
- options->cipher_suites, options->key_exchange_groups);
3156
- if (result != TSI_OK) break;
3505
+ tsi_result tsi_create_ssl_server_handshaker_factory_with_options(
3506
+ const tsi_ssl_server_handshaker_options* options,
3507
+ tsi_ssl_server_handshaker_factory** factory) {
3508
+ tsi_ssl_server_handshaker_factory* impl = nullptr;
3157
3509
 
3158
- #if defined(OPENSSL_IS_BORINGSSL)
3159
- grpc_core::Match(
3160
- options->pem_key_cert_pairs[i].private_key, [](const std::string&) {},
3161
- [&](const std::shared_ptr<grpc_core::PrivateKeySigner>& key_signer) {
3162
- ssl_context.key_signer = key_signer;
3163
- });
3164
- #endif
3510
+ gpr_once_init(&g_init_openssl_once, init_openssl);
3165
3511
 
3166
- // TODO(elessar): Provide ability to disable session ticket keys.
3512
+ if (factory == nullptr) return TSI_INVALID_ARGUMENT;
3513
+ *factory = nullptr;
3167
3514
 
3168
- // Allow client cache sessions (it's needed for OpenSSL only).
3169
- int set_sid_ctx_result = SSL_CTX_set_session_id_context(
3170
- ssl_context.ssl_ctx, kSslSessionIdContext,
3171
- GPR_ARRAY_SIZE(kSslSessionIdContext));
3172
- if (set_sid_ctx_result == 0) {
3173
- LOG(ERROR) << "Failed to set session id context.";
3174
- result = TSI_INTERNAL_ERROR;
3175
- break;
3176
- }
3515
+ impl = new tsi_ssl_server_handshaker_factory();
3516
+ tsi_ssl_handshaker_factory_init(&impl->base);
3517
+ impl->base.vtable = &server_handshaker_factory_vtable;
3177
3518
 
3178
- if (options->session_ticket_key != nullptr) {
3179
- if (SSL_CTX_set_tlsext_ticket_keys(
3180
- ssl_context.ssl_ctx,
3181
- const_cast<char*>(options->session_ticket_key),
3182
- options->session_ticket_key_size) == 0) {
3183
- LOG(ERROR) << "Invalid STEK size.";
3184
- result = TSI_INVALID_ARGUMENT;
3185
- break;
3519
+ tsi_result result = grpc_core::Match(
3520
+ options->pem_key_cert_pairs,
3521
+ [&](const std::vector<tsi_ssl_pem_key_cert_pair>& pem_key_cert_pairs) {
3522
+ if (pem_key_cert_pairs.empty()) {
3523
+ return TSI_INVALID_ARGUMENT;
3186
3524
  }
3187
- }
3188
- if (options->root_cert_info != nullptr) {
3189
- Match(
3190
- *options->root_cert_info,
3191
- [&](const std::string& pem_root_certs) {
3192
- STACK_OF(X509_NAME)* root_names = nullptr;
3193
- result = ssl_ctx_load_verification_certs(
3194
- ssl_context.ssl_ctx, pem_root_certs.c_str(),
3195
- pem_root_certs.size(), nullptr);
3196
- if (result != TSI_OK) {
3197
- LOG(ERROR) << "Invalid verification certs.";
3198
- }
3199
- if (options->send_client_ca_list) {
3200
- SSL_CTX_set_client_CA_list(ssl_context.ssl_ctx, root_names);
3201
- }
3202
- },
3203
- [&](const grpc_core::SpiffeBundleMap& spiffe_bundle_map) {
3204
- X509_STORE* cert_store =
3205
- SSL_CTX_get_cert_store(ssl_context.ssl_ctx);
3206
- X509_STORE_set_flags(cert_store, X509_V_FLAG_PARTIAL_CHAIN |
3207
- X509_V_FLAG_TRUSTED_FIRST);
3208
- const void* p = &spiffe_bundle_map;
3209
- void* map = const_cast<void*>(p);
3210
- SSL_CTX_set_ex_data(ssl_context.ssl_ctx,
3211
- g_ssl_ctx_ex_spiffe_bundle_map_index, map);
3212
- });
3213
- if (result != TSI_OK) {
3214
- break;
3525
+ impl->ssl_contexts.reserve(pem_key_cert_pairs.size());
3526
+ for (size_t i = 0; i < pem_key_cert_pairs.size(); ++i) {
3527
+ SslContext& ssl_context = impl->ssl_contexts.emplace_back();
3528
+ tsi_result result = tsi_configure_server_ssl_context(
3529
+ options, &pem_key_cert_pairs[i], impl, ssl_context);
3530
+ if (result != TSI_OK) {
3531
+ return result;
3532
+ }
3215
3533
  }
3216
- }
3217
- switch (options->client_certificate_request) {
3218
- case TSI_DONT_REQUEST_CLIENT_CERTIFICATE:
3219
- SSL_CTX_set_verify(ssl_context.ssl_ctx, SSL_VERIFY_NONE, nullptr);
3220
- break;
3221
- case TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
3222
- SSL_CTX_set_verify(ssl_context.ssl_ctx, SSL_VERIFY_PEER, nullptr);
3223
- SSL_CTX_set_cert_verify_callback(ssl_context.ssl_ctx,
3224
- NullVerifyCallback, nullptr);
3225
- break;
3226
- case TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
3227
- SSL_CTX_set_verify(ssl_context.ssl_ctx, SSL_VERIFY_PEER, nullptr);
3228
- SSL_CTX_set_cert_verify_callback(ssl_context.ssl_ctx,
3229
- CustomVerificationFunction, nullptr);
3230
- break;
3231
- case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
3232
- SSL_CTX_set_verify(ssl_context.ssl_ctx,
3233
- SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3234
- nullptr);
3235
- SSL_CTX_set_cert_verify_callback(ssl_context.ssl_ctx,
3236
- NullVerifyCallback, nullptr);
3237
- break;
3238
- case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
3239
- SSL_CTX_set_verify(ssl_context.ssl_ctx,
3240
- SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3241
- nullptr);
3242
- SSL_CTX_set_cert_verify_callback(ssl_context.ssl_ctx,
3243
- CustomVerificationFunction, nullptr);
3244
- break;
3245
- }
3246
-
3247
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
3248
- if (options->crl_provider != nullptr) {
3249
- SSL_CTX_set_ex_data(ssl_context.ssl_ctx,
3250
- g_ssl_ctx_ex_crl_provider_index,
3251
- options->crl_provider.get());
3252
- } else if (options->crl_directory != nullptr &&
3253
- strcmp(options->crl_directory, "") != 0) {
3254
- X509_STORE* cert_store = SSL_CTX_get_cert_store(ssl_context.ssl_ctx);
3255
- X509_STORE_set_verify_cb(cert_store, verify_cb);
3256
- if (!X509_STORE_load_locations(cert_store, nullptr,
3257
- options->crl_directory)) {
3258
- LOG(ERROR) << "Failed to load CRL File from directory.";
3259
- } else {
3260
- X509_VERIFY_PARAM* param = X509_STORE_get0_param(cert_store);
3261
- X509_VERIFY_PARAM_set_flags(
3262
- param, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
3534
+ return TSI_OK;
3535
+ },
3536
+ [&](const std::shared_ptr<grpc_core::CertificateSelector>&
3537
+ cert_selector) {
3538
+ #if defined(OPENSSL_IS_BORINGSSL)
3539
+ if (cert_selector == nullptr) {
3540
+ return TSI_INVALID_ARGUMENT;
3263
3541
  }
3264
- }
3542
+ SslContext& ssl_context = impl->ssl_contexts.emplace_back();
3543
+ tsi_result result = tsi_configure_server_ssl_context(
3544
+ options, /*pem_key_cert_pair=*/nullptr, impl, ssl_context);
3545
+ if (result != TSI_OK) {
3546
+ return result;
3547
+ }
3548
+ impl->certificate_selector = cert_selector;
3549
+ SSL_CTX_set_select_certificate_cb(ssl_context.ssl_ctx,
3550
+ SelectCertificateCallback);
3551
+ return TSI_OK;
3552
+ #else
3553
+ VLOG(2) << "CertificateSelector is not supported with this SSL "
3554
+ "implementation.";
3555
+ return TSI_UNIMPLEMENTED;
3265
3556
  #endif
3557
+ });
3558
+ if (result != TSI_OK) {
3559
+ tsi_ssl_handshaker_factory_unref(&impl->base);
3560
+ return result;
3561
+ }
3266
3562
 
3267
- result = tsi_ssl_extract_x509_subject_names_from_pem_cert(
3268
- options->pem_key_cert_pairs[i].cert_chain.c_str(),
3269
- &ssl_context.x509_subject_name);
3270
- if (result != TSI_OK) break;
3271
-
3272
- SSL_CTX_set_tlsext_servername_callback(
3273
- ssl_context.ssl_ctx,
3274
- ssl_server_handshaker_factory_servername_callback);
3275
- SSL_CTX_set_tlsext_servername_arg(ssl_context.ssl_ctx, impl);
3276
- #if TSI_OPENSSL_ALPN_SUPPORT
3277
- SSL_CTX_set_alpn_select_cb(ssl_context.ssl_ctx,
3278
- ServerHandshakerFactoryAlpnCallback, impl);
3279
- #endif // TSI_OPENSSL_ALPN_SUPPORT
3280
- SSL_CTX_set_next_protos_advertised_cb(
3281
- ssl_context.ssl_ctx,
3282
- server_handshaker_factory_npn_advertised_callback, impl);
3283
-
3284
- #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
3285
- // Register factory at index
3286
- if (options->key_logger != nullptr) {
3287
- // Need to set factory at g_ssl_ctx_ex_factory_index
3288
- SSL_CTX_set_ex_data(ssl_context.ssl_ctx, g_ssl_ctx_ex_factory_index,
3289
- impl);
3290
- // SSL_CTX_set_keylog_callback is set here to register callback
3291
- // when ssl/tls handshakes complete.
3292
- SSL_CTX_set_keylog_callback(
3293
- ssl_context.ssl_ctx,
3294
- ssl_keylogging_callback<tsi_ssl_server_handshaker_factory>);
3295
- }
3296
- #endif
3297
- } while (false);
3563
+ if (options->root_cert_info != nullptr) {
3564
+ impl->root_cert_info = options->root_cert_info;
3565
+ }
3298
3566
 
3567
+ if (options->num_alpn_protocols > 0) {
3568
+ result = BuildAlpnProtocolNameList(
3569
+ options->alpn_protocols, options->num_alpn_protocols,
3570
+ &impl->alpn_protocol_list, &impl->alpn_protocol_list_length);
3299
3571
  if (result != TSI_OK) {
3300
3572
  tsi_ssl_handshaker_factory_unref(&impl->base);
3301
3573
  return result;
3302
3574
  }
3303
3575
  }
3304
3576
 
3577
+ if (options->key_logger != nullptr) {
3578
+ impl->key_logger = options->key_logger->Ref();
3579
+ }
3580
+
3305
3581
  *factory = impl;
3306
3582
  return TSI_OK;
3307
3583
  }