grpc 1.17.1 → 1.18.0.pre1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1228 -988
  3. data/etc/roots.pem +242 -30
  4. data/include/grpc/grpc.h +2 -1
  5. data/include/grpc/grpc_security_constants.h +3 -3
  6. data/include/grpc/impl/codegen/atm_gcc_sync.h +2 -0
  7. data/include/grpc/impl/codegen/atm_windows.h +2 -0
  8. data/include/grpc/impl/codegen/compression_types.h +2 -1
  9. data/include/grpc/impl/codegen/grpc_types.h +1 -1
  10. data/include/grpc/impl/codegen/port_platform.h +9 -0
  11. data/src/core/ext/filters/client_channel/client_channel.cc +163 -882
  12. data/src/core/ext/filters/client_channel/health/health_check_client.cc +2 -4
  13. data/src/core/ext/filters/client_channel/health/health_check_client.h +2 -3
  14. data/src/core/ext/filters/client_channel/lb_policy.cc +1 -1
  15. data/src/core/ext/filters/client_channel/lb_policy.h +8 -17
  16. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +176 -216
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h +1 -1
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +20 -23
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +1 -1
  20. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +49 -52
  21. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +13 -35
  22. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +31 -30
  23. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +69 -225
  24. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h +1 -1
  25. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc +20 -23
  26. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h +1 -1
  27. data/src/core/ext/filters/client_channel/lb_policy_factory.h +2 -84
  28. data/src/core/ext/filters/client_channel/request_routing.cc +936 -0
  29. data/src/core/ext/filters/client_channel/request_routing.h +177 -0
  30. data/src/core/ext/filters/client_channel/resolver.cc +1 -1
  31. data/src/core/ext/filters/client_channel/resolver.h +1 -1
  32. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +37 -26
  33. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +30 -18
  34. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +119 -100
  35. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +8 -5
  36. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +5 -4
  37. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +2 -1
  38. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +12 -14
  39. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +5 -9
  40. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +2 -1
  41. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +1 -2
  42. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +17 -17
  43. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +45 -52
  44. data/src/core/ext/filters/client_channel/resolver_result_parsing.h +13 -17
  45. data/src/core/ext/filters/client_channel/server_address.cc +103 -0
  46. data/src/core/ext/filters/client_channel/server_address.h +108 -0
  47. data/src/core/ext/filters/client_channel/subchannel.cc +10 -8
  48. data/src/core/ext/filters/client_channel/subchannel.h +9 -6
  49. data/src/core/ext/filters/client_channel/subchannel_index.cc +20 -27
  50. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +3 -2
  51. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +8 -9
  52. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +1 -1
  53. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +1 -1
  54. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc +8 -11
  55. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +24 -54
  56. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -1
  57. data/src/core/ext/transport/chttp2/transport/context_list.cc +67 -0
  58. data/src/core/ext/transport/chttp2/transport/context_list.h +53 -0
  59. data/src/core/ext/transport/chttp2/transport/internal.h +38 -11
  60. data/src/core/ext/transport/chttp2/transport/writing.cc +5 -0
  61. data/src/core/ext/transport/inproc/inproc_transport.cc +1 -1
  62. data/src/core/lib/channel/channelz.cc +19 -18
  63. data/src/core/lib/channel/channelz.h +7 -1
  64. data/src/core/lib/channel/channelz_registry.cc +3 -2
  65. data/src/core/lib/debug/trace.cc +3 -0
  66. data/src/core/lib/debug/trace.h +5 -3
  67. data/src/core/lib/gpr/sync_posix.cc +96 -4
  68. data/src/core/lib/gprpp/inlined_vector.h +25 -19
  69. data/src/core/lib/gprpp/memory.h +2 -11
  70. data/src/core/lib/gprpp/orphanable.h +18 -82
  71. data/src/core/lib/gprpp/ref_counted.h +75 -84
  72. data/src/core/lib/gprpp/ref_counted_ptr.h +22 -17
  73. data/src/core/lib/http/httpcli_security_connector.cc +101 -94
  74. data/src/core/lib/http/parser.h +5 -5
  75. data/src/core/lib/iomgr/buffer_list.cc +16 -5
  76. data/src/core/lib/iomgr/buffer_list.h +10 -3
  77. data/src/core/lib/iomgr/call_combiner.cc +50 -2
  78. data/src/core/lib/iomgr/call_combiner.h +29 -2
  79. data/src/core/lib/iomgr/dynamic_annotations.h +67 -0
  80. data/src/core/lib/iomgr/endpoint.cc +4 -0
  81. data/src/core/lib/iomgr/endpoint.h +3 -0
  82. data/src/core/lib/iomgr/endpoint_pair_posix.cc +2 -2
  83. data/src/core/lib/iomgr/ev_epoll1_linux.cc +4 -0
  84. data/src/core/lib/iomgr/ev_epollex_linux.cc +4 -0
  85. data/src/core/lib/iomgr/ev_poll_posix.cc +4 -0
  86. data/src/core/lib/iomgr/ev_posix.cc +15 -7
  87. data/src/core/lib/iomgr/ev_posix.h +10 -0
  88. data/src/core/lib/iomgr/exec_ctx.cc +13 -0
  89. data/src/core/lib/iomgr/fork_posix.cc +1 -1
  90. data/src/core/lib/iomgr/internal_errqueue.cc +36 -3
  91. data/src/core/lib/iomgr/internal_errqueue.h +7 -1
  92. data/src/core/lib/iomgr/iomgr.cc +7 -0
  93. data/src/core/lib/iomgr/iomgr.h +4 -0
  94. data/src/core/lib/iomgr/iomgr_custom.cc +3 -1
  95. data/src/core/lib/iomgr/iomgr_internal.cc +4 -0
  96. data/src/core/lib/iomgr/iomgr_internal.h +4 -0
  97. data/src/core/lib/iomgr/iomgr_posix.cc +6 -1
  98. data/src/core/lib/iomgr/iomgr_windows.cc +4 -1
  99. data/src/core/lib/iomgr/port.h +1 -2
  100. data/src/core/lib/iomgr/resource_quota.cc +1 -0
  101. data/src/core/lib/iomgr/sockaddr_utils.cc +1 -0
  102. data/src/core/lib/iomgr/tcp_custom.cc +4 -1
  103. data/src/core/lib/iomgr/tcp_posix.cc +95 -35
  104. data/src/core/lib/iomgr/tcp_windows.cc +4 -1
  105. data/src/core/lib/iomgr/timer_manager.cc +6 -0
  106. data/src/core/lib/security/context/security_context.cc +75 -108
  107. data/src/core/lib/security/context/security_context.h +59 -35
  108. data/src/core/lib/security/credentials/alts/alts_credentials.cc +36 -48
  109. data/src/core/lib/security/credentials/alts/alts_credentials.h +37 -10
  110. data/src/core/lib/security/credentials/composite/composite_credentials.cc +97 -157
  111. data/src/core/lib/security/credentials/composite/composite_credentials.h +60 -24
  112. data/src/core/lib/security/credentials/credentials.cc +18 -142
  113. data/src/core/lib/security/credentials/credentials.h +119 -95
  114. data/src/core/lib/security/credentials/fake/fake_credentials.cc +46 -71
  115. data/src/core/lib/security/credentials/fake/fake_credentials.h +23 -5
  116. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +144 -51
  117. data/src/core/lib/security/credentials/google_default/google_default_credentials.h +28 -5
  118. data/src/core/lib/security/credentials/iam/iam_credentials.cc +27 -35
  119. data/src/core/lib/security/credentials/iam/iam_credentials.h +18 -4
  120. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +60 -69
  121. data/src/core/lib/security/credentials/jwt/jwt_credentials.h +29 -10
  122. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +2 -0
  123. data/src/core/lib/security/credentials/local/local_credentials.cc +19 -32
  124. data/src/core/lib/security/credentials/local/local_credentials.h +32 -11
  125. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +130 -149
  126. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +74 -29
  127. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +59 -77
  128. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +40 -17
  129. data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +66 -83
  130. data/src/core/lib/security/credentials/ssl/ssl_credentials.h +58 -15
  131. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +152 -177
  132. data/src/core/lib/security/security_connector/alts/alts_security_connector.h +12 -10
  133. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +210 -215
  134. data/src/core/lib/security/security_connector/fake/fake_security_connector.h +9 -6
  135. data/src/core/lib/security/security_connector/local/local_security_connector.cc +176 -169
  136. data/src/core/lib/security/security_connector/local/local_security_connector.h +10 -9
  137. data/src/core/lib/security/security_connector/security_connector.cc +41 -124
  138. data/src/core/lib/security/security_connector/security_connector.h +102 -105
  139. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +348 -370
  140. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.h +14 -12
  141. data/src/core/lib/security/security_connector/ssl_utils.cc +13 -9
  142. data/src/core/lib/security/security_connector/ssl_utils.h +3 -1
  143. data/src/core/lib/security/transport/client_auth_filter.cc +50 -50
  144. data/src/core/lib/security/transport/secure_endpoint.cc +7 -1
  145. data/src/core/lib/security/transport/security_handshaker.cc +82 -66
  146. data/src/core/lib/security/transport/server_auth_filter.cc +15 -13
  147. data/src/core/lib/surface/init.cc +1 -0
  148. data/src/core/lib/surface/server.cc +13 -11
  149. data/src/core/lib/surface/server.h +6 -6
  150. data/src/core/lib/surface/version.cc +2 -2
  151. data/src/core/lib/transport/metadata.cc +1 -0
  152. data/src/core/lib/transport/static_metadata.cc +228 -221
  153. data/src/core/lib/transport/static_metadata.h +75 -71
  154. data/src/core/lib/transport/transport.cc +2 -1
  155. data/src/core/lib/transport/transport.h +5 -1
  156. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +9 -2
  157. data/src/core/tsi/ssl_transport_security.cc +35 -24
  158. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
  159. data/src/ruby/lib/grpc/generic/rpc_server.rb +61 -0
  160. data/src/ruby/lib/grpc/generic/service.rb +1 -1
  161. data/src/ruby/lib/grpc/version.rb +1 -1
  162. data/src/ruby/pb/grpc/health/checker.rb +2 -3
  163. data/src/ruby/spec/generic/rpc_server_spec.rb +22 -0
  164. data/src/ruby/spec/support/services.rb +1 -0
  165. metadata +37 -32
  166. data/src/core/ext/filters/client_channel/lb_policy_factory.cc +0 -163
@@ -35,150 +35,67 @@
35
35
  #include "src/core/lib/security/context/security_context.h"
36
36
  #include "src/core/lib/security/credentials/credentials.h"
37
37
  #include "src/core/lib/security/security_connector/load_system_roots.h"
38
+ #include "src/core/lib/security/security_connector/security_connector.h"
38
39
  #include "src/core/lib/security/transport/security_handshaker.h"
39
40
 
40
41
  grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount(
41
42
  false, "security_connector_refcount");
42
43
 
43
- void grpc_channel_security_connector_add_handshakers(
44
- grpc_channel_security_connector* connector,
45
- grpc_pollset_set* interested_parties,
46
- grpc_handshake_manager* handshake_mgr) {
47
- if (connector != nullptr) {
48
- connector->add_handshakers(connector, interested_parties, handshake_mgr);
49
- }
50
- }
51
-
52
- void grpc_server_security_connector_add_handshakers(
53
- grpc_server_security_connector* connector,
54
- grpc_pollset_set* interested_parties,
55
- grpc_handshake_manager* handshake_mgr) {
56
- if (connector != nullptr) {
57
- connector->add_handshakers(connector, interested_parties, handshake_mgr);
58
- }
59
- }
60
-
61
- void grpc_security_connector_check_peer(grpc_security_connector* sc,
62
- tsi_peer peer,
63
- grpc_auth_context** auth_context,
64
- grpc_closure* on_peer_checked) {
65
- if (sc == nullptr) {
66
- GRPC_CLOSURE_SCHED(on_peer_checked,
67
- GRPC_ERROR_CREATE_FROM_STATIC_STRING(
68
- "cannot check peer -- no security connector"));
69
- tsi_peer_destruct(&peer);
70
- } else {
71
- sc->vtable->check_peer(sc, peer, auth_context, on_peer_checked);
72
- }
73
- }
74
-
75
- int grpc_security_connector_cmp(grpc_security_connector* sc,
76
- grpc_security_connector* other) {
44
+ grpc_server_security_connector::grpc_server_security_connector(
45
+ const char* url_scheme,
46
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
47
+ : grpc_security_connector(url_scheme),
48
+ server_creds_(std::move(server_creds)) {}
49
+
50
+ grpc_channel_security_connector::grpc_channel_security_connector(
51
+ const char* url_scheme,
52
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
53
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds)
54
+ : grpc_security_connector(url_scheme),
55
+ channel_creds_(std::move(channel_creds)),
56
+ request_metadata_creds_(std::move(request_metadata_creds)) {}
57
+ grpc_channel_security_connector::~grpc_channel_security_connector() {}
58
+
59
+ int grpc_security_connector_cmp(const grpc_security_connector* sc,
60
+ const grpc_security_connector* other) {
77
61
  if (sc == nullptr || other == nullptr) return GPR_ICMP(sc, other);
78
- int c = GPR_ICMP(sc->vtable, other->vtable);
79
- if (c != 0) return c;
80
- return sc->vtable->cmp(sc, other);
62
+ return sc->cmp(other);
81
63
  }
82
64
 
83
- int grpc_channel_security_connector_cmp(grpc_channel_security_connector* sc1,
84
- grpc_channel_security_connector* sc2) {
85
- GPR_ASSERT(sc1->channel_creds != nullptr);
86
- GPR_ASSERT(sc2->channel_creds != nullptr);
87
- int c = GPR_ICMP(sc1->channel_creds, sc2->channel_creds);
88
- if (c != 0) return c;
89
- c = GPR_ICMP(sc1->request_metadata_creds, sc2->request_metadata_creds);
90
- if (c != 0) return c;
91
- c = GPR_ICMP((void*)sc1->check_call_host, (void*)sc2->check_call_host);
92
- if (c != 0) return c;
93
- c = GPR_ICMP((void*)sc1->cancel_check_call_host,
94
- (void*)sc2->cancel_check_call_host);
65
+ int grpc_channel_security_connector::channel_security_connector_cmp(
66
+ const grpc_channel_security_connector* other) const {
67
+ const grpc_channel_security_connector* other_sc =
68
+ static_cast<const grpc_channel_security_connector*>(other);
69
+ GPR_ASSERT(channel_creds() != nullptr);
70
+ GPR_ASSERT(other_sc->channel_creds() != nullptr);
71
+ int c = GPR_ICMP(channel_creds(), other_sc->channel_creds());
95
72
  if (c != 0) return c;
96
- return GPR_ICMP((void*)sc1->add_handshakers, (void*)sc2->add_handshakers);
73
+ return GPR_ICMP(request_metadata_creds(), other_sc->request_metadata_creds());
97
74
  }
98
75
 
99
- int grpc_server_security_connector_cmp(grpc_server_security_connector* sc1,
100
- grpc_server_security_connector* sc2) {
101
- GPR_ASSERT(sc1->server_creds != nullptr);
102
- GPR_ASSERT(sc2->server_creds != nullptr);
103
- int c = GPR_ICMP(sc1->server_creds, sc2->server_creds);
104
- if (c != 0) return c;
105
- return GPR_ICMP((void*)sc1->add_handshakers, (void*)sc2->add_handshakers);
106
- }
107
-
108
- bool grpc_channel_security_connector_check_call_host(
109
- grpc_channel_security_connector* sc, const char* host,
110
- grpc_auth_context* auth_context, grpc_closure* on_call_host_checked,
111
- grpc_error** error) {
112
- if (sc == nullptr || sc->check_call_host == nullptr) {
113
- *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
114
- "cannot check call host -- no security connector");
115
- return true;
116
- }
117
- return sc->check_call_host(sc, host, auth_context, on_call_host_checked,
118
- error);
119
- }
120
-
121
- void grpc_channel_security_connector_cancel_check_call_host(
122
- grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked,
123
- grpc_error* error) {
124
- if (sc == nullptr || sc->cancel_check_call_host == nullptr) {
125
- GRPC_ERROR_UNREF(error);
126
- return;
127
- }
128
- sc->cancel_check_call_host(sc, on_call_host_checked, error);
129
- }
130
-
131
- #ifndef NDEBUG
132
- grpc_security_connector* grpc_security_connector_ref(
133
- grpc_security_connector* sc, const char* file, int line,
134
- const char* reason) {
135
- if (sc == nullptr) return nullptr;
136
- if (grpc_trace_security_connector_refcount.enabled()) {
137
- gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count);
138
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
139
- "SECURITY_CONNECTOR:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", sc,
140
- val, val + 1, reason);
141
- }
142
- #else
143
- grpc_security_connector* grpc_security_connector_ref(
144
- grpc_security_connector* sc) {
145
- if (sc == nullptr) return nullptr;
146
- #endif
147
- gpr_ref(&sc->refcount);
148
- return sc;
149
- }
150
-
151
- #ifndef NDEBUG
152
- void grpc_security_connector_unref(grpc_security_connector* sc,
153
- const char* file, int line,
154
- const char* reason) {
155
- if (sc == nullptr) return;
156
- if (grpc_trace_security_connector_refcount.enabled()) {
157
- gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count);
158
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
159
- "SECURITY_CONNECTOR:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", sc,
160
- val, val - 1, reason);
161
- }
162
- #else
163
- void grpc_security_connector_unref(grpc_security_connector* sc) {
164
- if (sc == nullptr) return;
165
- #endif
166
- if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc);
76
+ int grpc_server_security_connector::server_security_connector_cmp(
77
+ const grpc_server_security_connector* other) const {
78
+ const grpc_server_security_connector* other_sc =
79
+ static_cast<const grpc_server_security_connector*>(other);
80
+ GPR_ASSERT(server_creds() != nullptr);
81
+ GPR_ASSERT(other_sc->server_creds() != nullptr);
82
+ return GPR_ICMP(server_creds(), other_sc->server_creds());
167
83
  }
168
84
 
169
85
  static void connector_arg_destroy(void* p) {
170
- GRPC_SECURITY_CONNECTOR_UNREF((grpc_security_connector*)p,
171
- "connector_arg_destroy");
86
+ static_cast<grpc_security_connector*>(p)->Unref(DEBUG_LOCATION,
87
+ "connector_arg_destroy");
172
88
  }
173
89
 
174
90
  static void* connector_arg_copy(void* p) {
175
- return GRPC_SECURITY_CONNECTOR_REF((grpc_security_connector*)p,
176
- "connector_arg_copy");
91
+ return static_cast<grpc_security_connector*>(p)
92
+ ->Ref(DEBUG_LOCATION, "connector_arg_copy")
93
+ .release();
177
94
  }
178
95
 
179
96
  static int connector_cmp(void* a, void* b) {
180
- return grpc_security_connector_cmp(static_cast<grpc_security_connector*>(a),
181
- static_cast<grpc_security_connector*>(b));
97
+ return static_cast<grpc_security_connector*>(a)->cmp(
98
+ static_cast<grpc_security_connector*>(b));
182
99
  }
183
100
 
184
101
  static const grpc_arg_pointer_vtable connector_arg_vtable = {
@@ -26,6 +26,7 @@
26
26
  #include <grpc/grpc_security.h>
27
27
 
28
28
  #include "src/core/lib/channel/handshaker.h"
29
+ #include "src/core/lib/gprpp/ref_counted.h"
29
30
  #include "src/core/lib/iomgr/endpoint.h"
30
31
  #include "src/core/lib/iomgr/pollset.h"
31
32
  #include "src/core/lib/iomgr/tcp_server.h"
@@ -34,8 +35,6 @@
34
35
 
35
36
  extern grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount;
36
37
 
37
- /* --- status enum. --- */
38
-
39
38
  typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status;
40
39
 
41
40
  /* --- security_connector object. ---
@@ -43,54 +42,34 @@ typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status;
43
42
  A security connector object represents away to configure the underlying
44
43
  transport security mechanism and check the resulting trusted peer. */
45
44
 
46
- typedef struct grpc_security_connector grpc_security_connector;
47
-
48
45
  #define GRPC_ARG_SECURITY_CONNECTOR "grpc.security_connector"
49
46
 
50
- typedef struct {
51
- void (*destroy)(grpc_security_connector* sc);
52
- void (*check_peer)(grpc_security_connector* sc, tsi_peer peer,
53
- grpc_auth_context** auth_context,
54
- grpc_closure* on_peer_checked);
55
- int (*cmp)(grpc_security_connector* sc, grpc_security_connector* other);
56
- } grpc_security_connector_vtable;
57
-
58
- struct grpc_security_connector {
59
- const grpc_security_connector_vtable* vtable;
60
- gpr_refcount refcount;
61
- const char* url_scheme;
62
- };
47
+ class grpc_security_connector
48
+ : public grpc_core::RefCounted<grpc_security_connector> {
49
+ public:
50
+ explicit grpc_security_connector(const char* url_scheme)
51
+ : grpc_core::RefCounted<grpc_security_connector>(
52
+ &grpc_trace_security_connector_refcount),
53
+ url_scheme_(url_scheme) {}
54
+ virtual ~grpc_security_connector() = default;
55
+
56
+ /* Check the peer. Callee takes ownership of the peer object.
57
+ When done, sets *auth_context and invokes on_peer_checked. */
58
+ virtual void check_peer(
59
+ tsi_peer peer, grpc_endpoint* ep,
60
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
61
+ grpc_closure* on_peer_checked) GRPC_ABSTRACT;
62
+
63
+ /* Compares two security connectors. */
64
+ virtual int cmp(const grpc_security_connector* other) const GRPC_ABSTRACT;
65
+
66
+ const char* url_scheme() const { return url_scheme_; }
63
67
 
64
- /* Refcounting. */
65
- #ifndef NDEBUG
66
- #define GRPC_SECURITY_CONNECTOR_REF(p, r) \
67
- grpc_security_connector_ref((p), __FILE__, __LINE__, (r))
68
- #define GRPC_SECURITY_CONNECTOR_UNREF(p, r) \
69
- grpc_security_connector_unref((p), __FILE__, __LINE__, (r))
70
- grpc_security_connector* grpc_security_connector_ref(
71
- grpc_security_connector* policy, const char* file, int line,
72
- const char* reason);
73
- void grpc_security_connector_unref(grpc_security_connector* policy,
74
- const char* file, int line,
75
- const char* reason);
76
- #else
77
- #define GRPC_SECURITY_CONNECTOR_REF(p, r) grpc_security_connector_ref((p))
78
- #define GRPC_SECURITY_CONNECTOR_UNREF(p, r) grpc_security_connector_unref((p))
79
- grpc_security_connector* grpc_security_connector_ref(
80
- grpc_security_connector* policy);
81
- void grpc_security_connector_unref(grpc_security_connector* policy);
82
- #endif
83
-
84
- /* Check the peer. Callee takes ownership of the peer object.
85
- When done, sets *auth_context and invokes on_peer_checked. */
86
- void grpc_security_connector_check_peer(grpc_security_connector* sc,
87
- tsi_peer peer,
88
- grpc_auth_context** auth_context,
89
- grpc_closure* on_peer_checked);
90
-
91
- /* Compares two security connectors. */
92
- int grpc_security_connector_cmp(grpc_security_connector* sc,
93
- grpc_security_connector* other);
68
+ GRPC_ABSTRACT_BASE_CLASS
69
+
70
+ private:
71
+ const char* url_scheme_;
72
+ };
94
73
 
95
74
  /* Util to encapsulate the connector in a channel arg. */
96
75
  grpc_arg grpc_security_connector_to_arg(grpc_security_connector* sc);
@@ -107,71 +86,89 @@ grpc_security_connector* grpc_security_connector_find_in_args(
107
86
  A channel security connector object represents a way to configure the
108
87
  underlying transport security mechanism on the client side. */
109
88
 
110
- typedef struct grpc_channel_security_connector grpc_channel_security_connector;
111
-
112
- struct grpc_channel_security_connector {
113
- grpc_security_connector base;
114
- grpc_channel_credentials* channel_creds;
115
- grpc_call_credentials* request_metadata_creds;
116
- bool (*check_call_host)(grpc_channel_security_connector* sc, const char* host,
117
- grpc_auth_context* auth_context,
118
- grpc_closure* on_call_host_checked,
119
- grpc_error** error);
120
- void (*cancel_check_call_host)(grpc_channel_security_connector* sc,
121
- grpc_closure* on_call_host_checked,
122
- grpc_error* error);
123
- void (*add_handshakers)(grpc_channel_security_connector* sc,
124
- grpc_pollset_set* interested_parties,
125
- grpc_handshake_manager* handshake_mgr);
89
+ class grpc_channel_security_connector : public grpc_security_connector {
90
+ public:
91
+ grpc_channel_security_connector(
92
+ const char* url_scheme,
93
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
94
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds);
95
+ ~grpc_channel_security_connector() override;
96
+
97
+ /// Checks that the host that will be set for a call is acceptable.
98
+ /// Returns true if completed synchronously, in which case \a error will
99
+ /// be set to indicate the result. Otherwise, \a on_call_host_checked
100
+ /// will be invoked when complete.
101
+ virtual bool check_call_host(const char* host,
102
+ grpc_auth_context* auth_context,
103
+ grpc_closure* on_call_host_checked,
104
+ grpc_error** error) GRPC_ABSTRACT;
105
+ /// Cancels a pending asychronous call to
106
+ /// grpc_channel_security_connector_check_call_host() with
107
+ /// \a on_call_host_checked as its callback.
108
+ virtual void cancel_check_call_host(grpc_closure* on_call_host_checked,
109
+ grpc_error* error) GRPC_ABSTRACT;
110
+ /// Registers handshakers with \a handshake_mgr.
111
+ virtual void add_handshakers(grpc_pollset_set* interested_parties,
112
+ grpc_handshake_manager* handshake_mgr)
113
+ GRPC_ABSTRACT;
114
+
115
+ const grpc_channel_credentials* channel_creds() const {
116
+ return channel_creds_.get();
117
+ }
118
+ grpc_channel_credentials* mutable_channel_creds() {
119
+ return channel_creds_.get();
120
+ }
121
+ const grpc_call_credentials* request_metadata_creds() const {
122
+ return request_metadata_creds_.get();
123
+ }
124
+ grpc_call_credentials* mutable_request_metadata_creds() {
125
+ return request_metadata_creds_.get();
126
+ }
127
+
128
+ GRPC_ABSTRACT_BASE_CLASS
129
+
130
+ protected:
131
+ // Helper methods to be used in subclasses.
132
+ int channel_security_connector_cmp(
133
+ const grpc_channel_security_connector* other) const;
134
+
135
+ private:
136
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds_;
137
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds_;
126
138
  };
127
139
 
128
- /// A helper function for use in grpc_security_connector_cmp() implementations.
129
- int grpc_channel_security_connector_cmp(grpc_channel_security_connector* sc1,
130
- grpc_channel_security_connector* sc2);
131
-
132
- /// Checks that the host that will be set for a call is acceptable.
133
- /// Returns true if completed synchronously, in which case \a error will
134
- /// be set to indicate the result. Otherwise, \a on_call_host_checked
135
- /// will be invoked when complete.
136
- bool grpc_channel_security_connector_check_call_host(
137
- grpc_channel_security_connector* sc, const char* host,
138
- grpc_auth_context* auth_context, grpc_closure* on_call_host_checked,
139
- grpc_error** error);
140
-
141
- /// Cancels a pending asychronous call to
142
- /// grpc_channel_security_connector_check_call_host() with
143
- /// \a on_call_host_checked as its callback.
144
- void grpc_channel_security_connector_cancel_check_call_host(
145
- grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked,
146
- grpc_error* error);
147
-
148
- /* Registers handshakers with \a handshake_mgr. */
149
- void grpc_channel_security_connector_add_handshakers(
150
- grpc_channel_security_connector* connector,
151
- grpc_pollset_set* interested_parties,
152
- grpc_handshake_manager* handshake_mgr);
153
-
154
140
  /* --- server_security_connector object. ---
155
141
 
156
142
  A server security connector object represents a way to configure the
157
143
  underlying transport security mechanism on the server side. */
158
144
 
159
- typedef struct grpc_server_security_connector grpc_server_security_connector;
160
-
161
- struct grpc_server_security_connector {
162
- grpc_security_connector base;
163
- grpc_server_credentials* server_creds;
164
- void (*add_handshakers)(grpc_server_security_connector* sc,
165
- grpc_pollset_set* interested_parties,
166
- grpc_handshake_manager* handshake_mgr);
145
+ class grpc_server_security_connector : public grpc_security_connector {
146
+ public:
147
+ grpc_server_security_connector(
148
+ const char* url_scheme,
149
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds);
150
+ ~grpc_server_security_connector() override = default;
151
+
152
+ virtual void add_handshakers(grpc_pollset_set* interested_parties,
153
+ grpc_handshake_manager* handshake_mgr)
154
+ GRPC_ABSTRACT;
155
+
156
+ const grpc_server_credentials* server_creds() const {
157
+ return server_creds_.get();
158
+ }
159
+ grpc_server_credentials* mutable_server_creds() {
160
+ return server_creds_.get();
161
+ }
162
+
163
+ GRPC_ABSTRACT_BASE_CLASS
164
+
165
+ protected:
166
+ // Helper methods to be used in subclasses.
167
+ int server_security_connector_cmp(
168
+ const grpc_server_security_connector* other) const;
169
+
170
+ private:
171
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds_;
167
172
  };
168
173
 
169
- /// A helper function for use in grpc_security_connector_cmp() implementations.
170
- int grpc_server_security_connector_cmp(grpc_server_security_connector* sc1,
171
- grpc_server_security_connector* sc2);
172
-
173
- void grpc_server_security_connector_add_handshakers(
174
- grpc_server_security_connector* sc, grpc_pollset_set* interested_parties,
175
- grpc_handshake_manager* handshake_mgr);
176
-
177
174
  #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SECURITY_CONNECTOR_H */
@@ -30,6 +30,7 @@
30
30
  #include "src/core/lib/channel/handshaker.h"
31
31
  #include "src/core/lib/gpr/host_port.h"
32
32
  #include "src/core/lib/gpr/string.h"
33
+ #include "src/core/lib/gprpp/ref_counted_ptr.h"
33
34
  #include "src/core/lib/security/context/security_context.h"
34
35
  #include "src/core/lib/security/credentials/credentials.h"
35
36
  #include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
@@ -39,172 +40,10 @@
39
40
  #include "src/core/tsi/ssl_transport_security.h"
40
41
  #include "src/core/tsi/transport_security.h"
41
42
 
42
- typedef struct {
43
- grpc_channel_security_connector base;
44
- tsi_ssl_client_handshaker_factory* client_handshaker_factory;
45
- char* target_name;
46
- char* overridden_target_name;
47
- const verify_peer_options* verify_options;
48
- } grpc_ssl_channel_security_connector;
49
-
50
- typedef struct {
51
- grpc_server_security_connector base;
52
- tsi_ssl_server_handshaker_factory* server_handshaker_factory;
53
- } grpc_ssl_server_security_connector;
54
-
55
- static bool server_connector_has_cert_config_fetcher(
56
- grpc_ssl_server_security_connector* c) {
57
- GPR_ASSERT(c != nullptr);
58
- grpc_ssl_server_credentials* server_creds =
59
- reinterpret_cast<grpc_ssl_server_credentials*>(c->base.server_creds);
60
- GPR_ASSERT(server_creds != nullptr);
61
- return server_creds->certificate_config_fetcher.cb != nullptr;
62
- }
63
-
64
- static void ssl_channel_destroy(grpc_security_connector* sc) {
65
- grpc_ssl_channel_security_connector* c =
66
- reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
67
- grpc_channel_credentials_unref(c->base.channel_creds);
68
- grpc_call_credentials_unref(c->base.request_metadata_creds);
69
- tsi_ssl_client_handshaker_factory_unref(c->client_handshaker_factory);
70
- c->client_handshaker_factory = nullptr;
71
- if (c->target_name != nullptr) gpr_free(c->target_name);
72
- if (c->overridden_target_name != nullptr) gpr_free(c->overridden_target_name);
73
- gpr_free(sc);
74
- }
75
-
76
- static void ssl_server_destroy(grpc_security_connector* sc) {
77
- grpc_ssl_server_security_connector* c =
78
- reinterpret_cast<grpc_ssl_server_security_connector*>(sc);
79
- grpc_server_credentials_unref(c->base.server_creds);
80
- tsi_ssl_server_handshaker_factory_unref(c->server_handshaker_factory);
81
- c->server_handshaker_factory = nullptr;
82
- gpr_free(sc);
83
- }
84
-
85
- static void ssl_channel_add_handshakers(grpc_channel_security_connector* sc,
86
- grpc_pollset_set* interested_parties,
87
- grpc_handshake_manager* handshake_mgr) {
88
- grpc_ssl_channel_security_connector* c =
89
- reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
90
- // Instantiate TSI handshaker.
91
- tsi_handshaker* tsi_hs = nullptr;
92
- tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
93
- c->client_handshaker_factory,
94
- c->overridden_target_name != nullptr ? c->overridden_target_name
95
- : c->target_name,
96
- &tsi_hs);
97
- if (result != TSI_OK) {
98
- gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
99
- tsi_result_to_string(result));
100
- return;
101
- }
102
- // Create handshakers.
103
- grpc_handshake_manager_add(
104
- handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base));
105
- }
106
-
107
- /* Attempts to replace the server_handshaker_factory with a new factory using
108
- * the provided grpc_ssl_server_certificate_config. Should new factory creation
109
- * fail, the existing factory will not be replaced. Returns true on success (new
110
- * factory created). */
111
- static bool try_replace_server_handshaker_factory(
112
- grpc_ssl_server_security_connector* sc,
113
- const grpc_ssl_server_certificate_config* config) {
114
- if (config == nullptr) {
115
- gpr_log(GPR_ERROR,
116
- "Server certificate config callback returned invalid (NULL) "
117
- "config.");
118
- return false;
119
- }
120
- gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config);
121
-
122
- size_t num_alpn_protocols = 0;
123
- const char** alpn_protocol_strings =
124
- grpc_fill_alpn_protocol_strings(&num_alpn_protocols);
125
- tsi_ssl_pem_key_cert_pair* cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs(
126
- config->pem_key_cert_pairs, config->num_key_cert_pairs);
127
- tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr;
128
- grpc_ssl_server_credentials* server_creds =
129
- reinterpret_cast<grpc_ssl_server_credentials*>(sc->base.server_creds);
130
- tsi_result result = tsi_create_ssl_server_handshaker_factory_ex(
131
- cert_pairs, config->num_key_cert_pairs, config->pem_root_certs,
132
- grpc_get_tsi_client_certificate_request_type(
133
- server_creds->config.client_certificate_request),
134
- grpc_get_ssl_cipher_suites(), alpn_protocol_strings,
135
- static_cast<uint16_t>(num_alpn_protocols), &new_handshaker_factory);
136
- gpr_free(cert_pairs);
137
- gpr_free((void*)alpn_protocol_strings);
138
-
139
- if (result != TSI_OK) {
140
- gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
141
- tsi_result_to_string(result));
142
- return false;
143
- }
144
- tsi_ssl_server_handshaker_factory_unref(sc->server_handshaker_factory);
145
- sc->server_handshaker_factory = new_handshaker_factory;
146
- return true;
147
- }
148
-
149
- /* Attempts to fetch the server certificate config if a callback is available.
150
- * Current certificate config will continue to be used if the callback returns
151
- * an error. Returns true if new credentials were sucessfully loaded. */
152
- static bool try_fetch_ssl_server_credentials(
153
- grpc_ssl_server_security_connector* sc) {
154
- grpc_ssl_server_certificate_config* certificate_config = nullptr;
155
- bool status;
156
-
157
- GPR_ASSERT(sc != nullptr);
158
- if (!server_connector_has_cert_config_fetcher(sc)) return false;
159
-
160
- grpc_ssl_server_credentials* server_creds =
161
- reinterpret_cast<grpc_ssl_server_credentials*>(sc->base.server_creds);
162
- grpc_ssl_certificate_config_reload_status cb_result =
163
- server_creds->certificate_config_fetcher.cb(
164
- server_creds->certificate_config_fetcher.user_data,
165
- &certificate_config);
166
- if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) {
167
- gpr_log(GPR_DEBUG, "No change in SSL server credentials.");
168
- status = false;
169
- } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) {
170
- status = try_replace_server_handshaker_factory(sc, certificate_config);
171
- } else {
172
- // Log error, continue using previously-loaded credentials.
173
- gpr_log(GPR_ERROR,
174
- "Failed fetching new server credentials, continuing to "
175
- "use previously-loaded credentials.");
176
- status = false;
177
- }
178
-
179
- if (certificate_config != nullptr) {
180
- grpc_ssl_server_certificate_config_destroy(certificate_config);
181
- }
182
- return status;
183
- }
184
-
185
- static void ssl_server_add_handshakers(grpc_server_security_connector* sc,
186
- grpc_pollset_set* interested_parties,
187
- grpc_handshake_manager* handshake_mgr) {
188
- grpc_ssl_server_security_connector* c =
189
- reinterpret_cast<grpc_ssl_server_security_connector*>(sc);
190
- // Instantiate TSI handshaker.
191
- try_fetch_ssl_server_credentials(c);
192
- tsi_handshaker* tsi_hs = nullptr;
193
- tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
194
- c->server_handshaker_factory, &tsi_hs);
195
- if (result != TSI_OK) {
196
- gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
197
- tsi_result_to_string(result));
198
- return;
199
- }
200
- // Create handshakers.
201
- grpc_handshake_manager_add(
202
- handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base));
203
- }
204
-
205
- static grpc_error* ssl_check_peer(grpc_security_connector* sc,
206
- const char* peer_name, const tsi_peer* peer,
207
- grpc_auth_context** auth_context) {
43
+ namespace {
44
+ grpc_error* ssl_check_peer(
45
+ const char* peer_name, const tsi_peer* peer,
46
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context) {
208
47
  #if TSI_OPENSSL_ALPN_SUPPORT
209
48
  /* Check the ALPN if ALPN is supported. */
210
49
  const tsi_peer_property* p =
@@ -230,245 +69,384 @@ static grpc_error* ssl_check_peer(grpc_security_connector* sc,
230
69
  return GRPC_ERROR_NONE;
231
70
  }
232
71
 
233
- static void ssl_channel_check_peer(grpc_security_connector* sc, tsi_peer peer,
234
- grpc_auth_context** auth_context,
235
- grpc_closure* on_peer_checked) {
236
- grpc_ssl_channel_security_connector* c =
237
- reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
238
- const char* target_name = c->overridden_target_name != nullptr
239
- ? c->overridden_target_name
240
- : c->target_name;
241
- grpc_error* error = ssl_check_peer(sc, target_name, &peer, auth_context);
242
- if (error == GRPC_ERROR_NONE &&
243
- c->verify_options->verify_peer_callback != nullptr) {
244
- const tsi_peer_property* p =
245
- tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY);
246
- if (p == nullptr) {
247
- error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
248
- "Cannot check peer: missing pem cert property.");
249
- } else {
250
- char* peer_pem = static_cast<char*>(gpr_malloc(p->value.length + 1));
251
- memcpy(peer_pem, p->value.data, p->value.length);
252
- peer_pem[p->value.length] = '\0';
253
- int callback_status = c->verify_options->verify_peer_callback(
254
- target_name, peer_pem,
255
- c->verify_options->verify_peer_callback_userdata);
256
- gpr_free(peer_pem);
257
- if (callback_status) {
258
- char* msg;
259
- gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)",
260
- callback_status);
261
- error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
262
- gpr_free(msg);
263
- }
264
- }
72
+ class grpc_ssl_channel_security_connector final
73
+ : public grpc_channel_security_connector {
74
+ public:
75
+ grpc_ssl_channel_security_connector(
76
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
77
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
78
+ const grpc_ssl_config* config, const char* target_name,
79
+ const char* overridden_target_name)
80
+ : grpc_channel_security_connector(GRPC_SSL_URL_SCHEME,
81
+ std::move(channel_creds),
82
+ std::move(request_metadata_creds)),
83
+ overridden_target_name_(overridden_target_name == nullptr
84
+ ? nullptr
85
+ : gpr_strdup(overridden_target_name)),
86
+ verify_options_(&config->verify_options) {
87
+ char* port;
88
+ gpr_split_host_port(target_name, &target_name_, &port);
89
+ gpr_free(port);
265
90
  }
266
- GRPC_CLOSURE_SCHED(on_peer_checked, error);
267
- tsi_peer_destruct(&peer);
268
- }
269
91
 
270
- static void ssl_server_check_peer(grpc_security_connector* sc, tsi_peer peer,
271
- grpc_auth_context** auth_context,
272
- grpc_closure* on_peer_checked) {
273
- grpc_error* error = ssl_check_peer(sc, nullptr, &peer, auth_context);
274
- tsi_peer_destruct(&peer);
275
- GRPC_CLOSURE_SCHED(on_peer_checked, error);
276
- }
92
+ ~grpc_ssl_channel_security_connector() override {
93
+ tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_);
94
+ if (target_name_ != nullptr) gpr_free(target_name_);
95
+ if (overridden_target_name_ != nullptr) gpr_free(overridden_target_name_);
96
+ }
277
97
 
278
- static int ssl_channel_cmp(grpc_security_connector* sc1,
279
- grpc_security_connector* sc2) {
280
- grpc_ssl_channel_security_connector* c1 =
281
- reinterpret_cast<grpc_ssl_channel_security_connector*>(sc1);
282
- grpc_ssl_channel_security_connector* c2 =
283
- reinterpret_cast<grpc_ssl_channel_security_connector*>(sc2);
284
- int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base);
285
- if (c != 0) return c;
286
- c = strcmp(c1->target_name, c2->target_name);
287
- if (c != 0) return c;
288
- return (c1->overridden_target_name == nullptr ||
289
- c2->overridden_target_name == nullptr)
290
- ? GPR_ICMP(c1->overridden_target_name, c2->overridden_target_name)
291
- : strcmp(c1->overridden_target_name, c2->overridden_target_name);
292
- }
98
+ grpc_security_status InitializeHandshakerFactory(
99
+ const grpc_ssl_config* config, const char* pem_root_certs,
100
+ const tsi_ssl_root_certs_store* root_store,
101
+ tsi_ssl_session_cache* ssl_session_cache) {
102
+ bool has_key_cert_pair =
103
+ config->pem_key_cert_pair != nullptr &&
104
+ config->pem_key_cert_pair->private_key != nullptr &&
105
+ config->pem_key_cert_pair->cert_chain != nullptr;
106
+ tsi_ssl_client_handshaker_options options;
107
+ memset(&options, 0, sizeof(options));
108
+ GPR_DEBUG_ASSERT(pem_root_certs != nullptr);
109
+ options.pem_root_certs = pem_root_certs;
110
+ options.root_store = root_store;
111
+ options.alpn_protocols =
112
+ grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols);
113
+ if (has_key_cert_pair) {
114
+ options.pem_key_cert_pair = config->pem_key_cert_pair;
115
+ }
116
+ options.cipher_suites = grpc_get_ssl_cipher_suites();
117
+ options.session_cache = ssl_session_cache;
118
+ const tsi_result result =
119
+ tsi_create_ssl_client_handshaker_factory_with_options(
120
+ &options, &client_handshaker_factory_);
121
+ gpr_free((void*)options.alpn_protocols);
122
+ if (result != TSI_OK) {
123
+ gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
124
+ tsi_result_to_string(result));
125
+ return GRPC_SECURITY_ERROR;
126
+ }
127
+ return GRPC_SECURITY_OK;
128
+ }
293
129
 
294
- static int ssl_server_cmp(grpc_security_connector* sc1,
295
- grpc_security_connector* sc2) {
296
- return grpc_server_security_connector_cmp(
297
- reinterpret_cast<grpc_server_security_connector*>(sc1),
298
- reinterpret_cast<grpc_server_security_connector*>(sc2));
299
- }
130
+ void add_handshakers(grpc_pollset_set* interested_parties,
131
+ grpc_handshake_manager* handshake_mgr) override {
132
+ // Instantiate TSI handshaker.
133
+ tsi_handshaker* tsi_hs = nullptr;
134
+ tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
135
+ client_handshaker_factory_,
136
+ overridden_target_name_ != nullptr ? overridden_target_name_
137
+ : target_name_,
138
+ &tsi_hs);
139
+ if (result != TSI_OK) {
140
+ gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
141
+ tsi_result_to_string(result));
142
+ return;
143
+ }
144
+ // Create handshakers.
145
+ grpc_handshake_manager_add(handshake_mgr,
146
+ grpc_security_handshaker_create(tsi_hs, this));
147
+ }
300
148
 
301
- static bool ssl_channel_check_call_host(grpc_channel_security_connector* sc,
302
- const char* host,
303
- grpc_auth_context* auth_context,
304
- grpc_closure* on_call_host_checked,
305
- grpc_error** error) {
306
- grpc_ssl_channel_security_connector* c =
307
- reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
308
- grpc_security_status status = GRPC_SECURITY_ERROR;
309
- tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context);
310
- if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK;
311
- /* If the target name was overridden, then the original target_name was
312
- 'checked' transitively during the previous peer check at the end of the
313
- handshake. */
314
- if (c->overridden_target_name != nullptr &&
315
- strcmp(host, c->target_name) == 0) {
316
- status = GRPC_SECURITY_OK;
149
+ void check_peer(tsi_peer peer, grpc_endpoint* ep,
150
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
151
+ grpc_closure* on_peer_checked) override {
152
+ const char* target_name = overridden_target_name_ != nullptr
153
+ ? overridden_target_name_
154
+ : target_name_;
155
+ grpc_error* error = ssl_check_peer(target_name, &peer, auth_context);
156
+ if (error == GRPC_ERROR_NONE &&
157
+ verify_options_->verify_peer_callback != nullptr) {
158
+ const tsi_peer_property* p =
159
+ tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY);
160
+ if (p == nullptr) {
161
+ error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
162
+ "Cannot check peer: missing pem cert property.");
163
+ } else {
164
+ char* peer_pem = static_cast<char*>(gpr_malloc(p->value.length + 1));
165
+ memcpy(peer_pem, p->value.data, p->value.length);
166
+ peer_pem[p->value.length] = '\0';
167
+ int callback_status = verify_options_->verify_peer_callback(
168
+ target_name, peer_pem,
169
+ verify_options_->verify_peer_callback_userdata);
170
+ gpr_free(peer_pem);
171
+ if (callback_status) {
172
+ char* msg;
173
+ gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)",
174
+ callback_status);
175
+ error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
176
+ gpr_free(msg);
177
+ }
178
+ }
179
+ }
180
+ GRPC_CLOSURE_SCHED(on_peer_checked, error);
181
+ tsi_peer_destruct(&peer);
317
182
  }
318
- if (status != GRPC_SECURITY_OK) {
319
- *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
320
- "call host does not match SSL server name");
183
+
184
+ int cmp(const grpc_security_connector* other_sc) const override {
185
+ auto* other =
186
+ reinterpret_cast<const grpc_ssl_channel_security_connector*>(other_sc);
187
+ int c = channel_security_connector_cmp(other);
188
+ if (c != 0) return c;
189
+ c = strcmp(target_name_, other->target_name_);
190
+ if (c != 0) return c;
191
+ return (overridden_target_name_ == nullptr ||
192
+ other->overridden_target_name_ == nullptr)
193
+ ? GPR_ICMP(overridden_target_name_,
194
+ other->overridden_target_name_)
195
+ : strcmp(overridden_target_name_,
196
+ other->overridden_target_name_);
321
197
  }
322
- grpc_shallow_peer_destruct(&peer);
323
- return true;
324
- }
325
198
 
326
- static void ssl_channel_cancel_check_call_host(
327
- grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked,
328
- grpc_error* error) {
329
- GRPC_ERROR_UNREF(error);
330
- }
199
+ bool check_call_host(const char* host, grpc_auth_context* auth_context,
200
+ grpc_closure* on_call_host_checked,
201
+ grpc_error** error) override {
202
+ grpc_security_status status = GRPC_SECURITY_ERROR;
203
+ tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context);
204
+ if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK;
205
+ /* If the target name was overridden, then the original target_name was
206
+ 'checked' transitively during the previous peer check at the end of the
207
+ handshake. */
208
+ if (overridden_target_name_ != nullptr && strcmp(host, target_name_) == 0) {
209
+ status = GRPC_SECURITY_OK;
210
+ }
211
+ if (status != GRPC_SECURITY_OK) {
212
+ *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
213
+ "call host does not match SSL server name");
214
+ }
215
+ grpc_shallow_peer_destruct(&peer);
216
+ return true;
217
+ }
331
218
 
332
- static grpc_security_connector_vtable ssl_channel_vtable = {
333
- ssl_channel_destroy, ssl_channel_check_peer, ssl_channel_cmp};
219
+ void cancel_check_call_host(grpc_closure* on_call_host_checked,
220
+ grpc_error* error) override {
221
+ GRPC_ERROR_UNREF(error);
222
+ }
334
223
 
335
- static grpc_security_connector_vtable ssl_server_vtable = {
336
- ssl_server_destroy, ssl_server_check_peer, ssl_server_cmp};
224
+ private:
225
+ tsi_ssl_client_handshaker_factory* client_handshaker_factory_;
226
+ char* target_name_;
227
+ char* overridden_target_name_;
228
+ const verify_peer_options* verify_options_;
229
+ };
230
+
231
+ class grpc_ssl_server_security_connector
232
+ : public grpc_server_security_connector {
233
+ public:
234
+ grpc_ssl_server_security_connector(
235
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
236
+ : grpc_server_security_connector(GRPC_SSL_URL_SCHEME,
237
+ std::move(server_creds)) {}
238
+
239
+ ~grpc_ssl_server_security_connector() override {
240
+ tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_);
241
+ }
337
242
 
338
- grpc_security_status grpc_ssl_channel_security_connector_create(
339
- grpc_channel_credentials* channel_creds,
340
- grpc_call_credentials* request_metadata_creds,
341
- const grpc_ssl_config* config, const char* target_name,
342
- const char* overridden_target_name,
343
- tsi_ssl_session_cache* ssl_session_cache,
344
- grpc_channel_security_connector** sc) {
345
- tsi_result result = TSI_OK;
346
- grpc_ssl_channel_security_connector* c;
347
- char* port;
348
- bool has_key_cert_pair;
349
- tsi_ssl_client_handshaker_options options;
350
- memset(&options, 0, sizeof(options));
351
- options.alpn_protocols =
352
- grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols);
243
+ bool has_cert_config_fetcher() const {
244
+ return static_cast<const grpc_ssl_server_credentials*>(server_creds())
245
+ ->has_cert_config_fetcher();
246
+ }
353
247
 
354
- if (config == nullptr || target_name == nullptr) {
355
- gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name.");
356
- goto error;
248
+ const tsi_ssl_server_handshaker_factory* server_handshaker_factory() const {
249
+ return server_handshaker_factory_;
357
250
  }
358
- if (config->pem_root_certs == nullptr) {
359
- // Use default root certificates.
360
- options.pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts();
361
- options.root_store = grpc_core::DefaultSslRootStore::GetRootStore();
362
- if (options.pem_root_certs == nullptr) {
363
- gpr_log(GPR_ERROR, "Could not get default pem root certs.");
364
- goto error;
251
+
252
+ grpc_security_status InitializeHandshakerFactory() {
253
+ if (has_cert_config_fetcher()) {
254
+ // Load initial credentials from certificate_config_fetcher:
255
+ if (!try_fetch_ssl_server_credentials()) {
256
+ gpr_log(GPR_ERROR,
257
+ "Failed loading SSL server credentials from fetcher.");
258
+ return GRPC_SECURITY_ERROR;
259
+ }
260
+ } else {
261
+ auto* server_credentials =
262
+ static_cast<const grpc_ssl_server_credentials*>(server_creds());
263
+ size_t num_alpn_protocols = 0;
264
+ const char** alpn_protocol_strings =
265
+ grpc_fill_alpn_protocol_strings(&num_alpn_protocols);
266
+ const tsi_result result = tsi_create_ssl_server_handshaker_factory_ex(
267
+ server_credentials->config().pem_key_cert_pairs,
268
+ server_credentials->config().num_key_cert_pairs,
269
+ server_credentials->config().pem_root_certs,
270
+ grpc_get_tsi_client_certificate_request_type(
271
+ server_credentials->config().client_certificate_request),
272
+ grpc_get_ssl_cipher_suites(), alpn_protocol_strings,
273
+ static_cast<uint16_t>(num_alpn_protocols),
274
+ &server_handshaker_factory_);
275
+ gpr_free((void*)alpn_protocol_strings);
276
+ if (result != TSI_OK) {
277
+ gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
278
+ tsi_result_to_string(result));
279
+ return GRPC_SECURITY_ERROR;
280
+ }
365
281
  }
366
- } else {
367
- options.pem_root_certs = config->pem_root_certs;
368
- }
369
- c = static_cast<grpc_ssl_channel_security_connector*>(
370
- gpr_zalloc(sizeof(grpc_ssl_channel_security_connector)));
371
-
372
- gpr_ref_init(&c->base.base.refcount, 1);
373
- c->base.base.vtable = &ssl_channel_vtable;
374
- c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
375
- c->base.channel_creds = grpc_channel_credentials_ref(channel_creds);
376
- c->base.request_metadata_creds =
377
- grpc_call_credentials_ref(request_metadata_creds);
378
- c->base.check_call_host = ssl_channel_check_call_host;
379
- c->base.cancel_check_call_host = ssl_channel_cancel_check_call_host;
380
- c->base.add_handshakers = ssl_channel_add_handshakers;
381
- gpr_split_host_port(target_name, &c->target_name, &port);
382
- gpr_free(port);
383
- if (overridden_target_name != nullptr) {
384
- c->overridden_target_name = gpr_strdup(overridden_target_name);
282
+ return GRPC_SECURITY_OK;
385
283
  }
386
- c->verify_options = &config->verify_options;
387
284
 
388
- has_key_cert_pair = config->pem_key_cert_pair != nullptr &&
389
- config->pem_key_cert_pair->private_key != nullptr &&
390
- config->pem_key_cert_pair->cert_chain != nullptr;
391
- if (has_key_cert_pair) {
392
- options.pem_key_cert_pair = config->pem_key_cert_pair;
285
+ void add_handshakers(grpc_pollset_set* interested_parties,
286
+ grpc_handshake_manager* handshake_mgr) override {
287
+ // Instantiate TSI handshaker.
288
+ try_fetch_ssl_server_credentials();
289
+ tsi_handshaker* tsi_hs = nullptr;
290
+ tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
291
+ server_handshaker_factory_, &tsi_hs);
292
+ if (result != TSI_OK) {
293
+ gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
294
+ tsi_result_to_string(result));
295
+ return;
296
+ }
297
+ // Create handshakers.
298
+ grpc_handshake_manager_add(handshake_mgr,
299
+ grpc_security_handshaker_create(tsi_hs, this));
393
300
  }
394
- options.cipher_suites = grpc_get_ssl_cipher_suites();
395
- options.session_cache = ssl_session_cache;
396
- result = tsi_create_ssl_client_handshaker_factory_with_options(
397
- &options, &c->client_handshaker_factory);
398
- if (result != TSI_OK) {
399
- gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
400
- tsi_result_to_string(result));
401
- ssl_channel_destroy(&c->base.base);
402
- *sc = nullptr;
403
- goto error;
301
+
302
+ void check_peer(tsi_peer peer, grpc_endpoint* ep,
303
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
304
+ grpc_closure* on_peer_checked) override {
305
+ grpc_error* error = ssl_check_peer(nullptr, &peer, auth_context);
306
+ tsi_peer_destruct(&peer);
307
+ GRPC_CLOSURE_SCHED(on_peer_checked, error);
404
308
  }
405
- *sc = &c->base;
406
- gpr_free((void*)options.alpn_protocols);
407
- return GRPC_SECURITY_OK;
408
309
 
409
- error:
410
- gpr_free((void*)options.alpn_protocols);
411
- return GRPC_SECURITY_ERROR;
412
- }
310
+ int cmp(const grpc_security_connector* other) const override {
311
+ return server_security_connector_cmp(
312
+ static_cast<const grpc_server_security_connector*>(other));
313
+ }
413
314
 
414
- static grpc_ssl_server_security_connector*
415
- grpc_ssl_server_security_connector_initialize(
416
- grpc_server_credentials* server_creds) {
417
- grpc_ssl_server_security_connector* c =
418
- static_cast<grpc_ssl_server_security_connector*>(
419
- gpr_zalloc(sizeof(grpc_ssl_server_security_connector)));
420
- gpr_ref_init(&c->base.base.refcount, 1);
421
- c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
422
- c->base.base.vtable = &ssl_server_vtable;
423
- c->base.add_handshakers = ssl_server_add_handshakers;
424
- c->base.server_creds = grpc_server_credentials_ref(server_creds);
425
- return c;
426
- }
315
+ private:
316
+ /* Attempts to fetch the server certificate config if a callback is available.
317
+ * Current certificate config will continue to be used if the callback returns
318
+ * an error. Returns true if new credentials were sucessfully loaded. */
319
+ bool try_fetch_ssl_server_credentials() {
320
+ grpc_ssl_server_certificate_config* certificate_config = nullptr;
321
+ bool status;
322
+
323
+ if (!has_cert_config_fetcher()) return false;
324
+
325
+ grpc_ssl_server_credentials* server_creds =
326
+ static_cast<grpc_ssl_server_credentials*>(this->mutable_server_creds());
327
+ grpc_ssl_certificate_config_reload_status cb_result =
328
+ server_creds->FetchCertConfig(&certificate_config);
329
+ if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) {
330
+ gpr_log(GPR_DEBUG, "No change in SSL server credentials.");
331
+ status = false;
332
+ } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) {
333
+ status = try_replace_server_handshaker_factory(certificate_config);
334
+ } else {
335
+ // Log error, continue using previously-loaded credentials.
336
+ gpr_log(GPR_ERROR,
337
+ "Failed fetching new server credentials, continuing to "
338
+ "use previously-loaded credentials.");
339
+ status = false;
340
+ }
427
341
 
428
- grpc_security_status grpc_ssl_server_security_connector_create(
429
- grpc_server_credentials* gsc, grpc_server_security_connector** sc) {
430
- tsi_result result = TSI_OK;
431
- grpc_ssl_server_credentials* server_credentials =
432
- reinterpret_cast<grpc_ssl_server_credentials*>(gsc);
433
- grpc_security_status retval = GRPC_SECURITY_OK;
342
+ if (certificate_config != nullptr) {
343
+ grpc_ssl_server_certificate_config_destroy(certificate_config);
344
+ }
345
+ return status;
346
+ }
434
347
 
435
- GPR_ASSERT(server_credentials != nullptr);
436
- GPR_ASSERT(sc != nullptr);
437
-
438
- grpc_ssl_server_security_connector* c =
439
- grpc_ssl_server_security_connector_initialize(gsc);
440
- if (server_connector_has_cert_config_fetcher(c)) {
441
- // Load initial credentials from certificate_config_fetcher:
442
- if (!try_fetch_ssl_server_credentials(c)) {
443
- gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher.");
444
- retval = GRPC_SECURITY_ERROR;
348
+ /* Attempts to replace the server_handshaker_factory with a new factory using
349
+ * the provided grpc_ssl_server_certificate_config. Should new factory
350
+ * creation fail, the existing factory will not be replaced. Returns true on
351
+ * success (new factory created). */
352
+ bool try_replace_server_handshaker_factory(
353
+ const grpc_ssl_server_certificate_config* config) {
354
+ if (config == nullptr) {
355
+ gpr_log(GPR_ERROR,
356
+ "Server certificate config callback returned invalid (NULL) "
357
+ "config.");
358
+ return false;
445
359
  }
446
- } else {
360
+ gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config);
361
+
447
362
  size_t num_alpn_protocols = 0;
448
363
  const char** alpn_protocol_strings =
449
364
  grpc_fill_alpn_protocol_strings(&num_alpn_protocols);
450
- result = tsi_create_ssl_server_handshaker_factory_ex(
451
- server_credentials->config.pem_key_cert_pairs,
452
- server_credentials->config.num_key_cert_pairs,
453
- server_credentials->config.pem_root_certs,
365
+ tsi_ssl_pem_key_cert_pair* cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs(
366
+ config->pem_key_cert_pairs, config->num_key_cert_pairs);
367
+ tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr;
368
+ const grpc_ssl_server_credentials* server_creds =
369
+ static_cast<const grpc_ssl_server_credentials*>(this->server_creds());
370
+ GPR_DEBUG_ASSERT(config->pem_root_certs != nullptr);
371
+ tsi_result result = tsi_create_ssl_server_handshaker_factory_ex(
372
+ cert_pairs, config->num_key_cert_pairs, config->pem_root_certs,
454
373
  grpc_get_tsi_client_certificate_request_type(
455
- server_credentials->config.client_certificate_request),
374
+ server_creds->config().client_certificate_request),
456
375
  grpc_get_ssl_cipher_suites(), alpn_protocol_strings,
457
- static_cast<uint16_t>(num_alpn_protocols),
458
- &c->server_handshaker_factory);
376
+ static_cast<uint16_t>(num_alpn_protocols), &new_handshaker_factory);
377
+ gpr_free(cert_pairs);
459
378
  gpr_free((void*)alpn_protocol_strings);
379
+
460
380
  if (result != TSI_OK) {
461
381
  gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
462
382
  tsi_result_to_string(result));
463
- retval = GRPC_SECURITY_ERROR;
383
+ return false;
464
384
  }
385
+ set_server_handshaker_factory(new_handshaker_factory);
386
+ return true;
387
+ }
388
+
389
+ void set_server_handshaker_factory(
390
+ tsi_ssl_server_handshaker_factory* new_factory) {
391
+ if (server_handshaker_factory_) {
392
+ tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_);
393
+ }
394
+ server_handshaker_factory_ = new_factory;
395
+ }
396
+
397
+ tsi_ssl_server_handshaker_factory* server_handshaker_factory_ = nullptr;
398
+ };
399
+ } // namespace
400
+
401
+ grpc_core::RefCountedPtr<grpc_channel_security_connector>
402
+ grpc_ssl_channel_security_connector_create(
403
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
404
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
405
+ const grpc_ssl_config* config, const char* target_name,
406
+ const char* overridden_target_name,
407
+ tsi_ssl_session_cache* ssl_session_cache) {
408
+ if (config == nullptr || target_name == nullptr) {
409
+ gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name.");
410
+ return nullptr;
465
411
  }
466
412
 
467
- if (retval == GRPC_SECURITY_OK) {
468
- *sc = &c->base;
413
+ const char* pem_root_certs;
414
+ const tsi_ssl_root_certs_store* root_store;
415
+ if (config->pem_root_certs == nullptr) {
416
+ // Use default root certificates.
417
+ pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts();
418
+ if (pem_root_certs == nullptr) {
419
+ gpr_log(GPR_ERROR, "Could not get default pem root certs.");
420
+ return nullptr;
421
+ }
422
+ root_store = grpc_core::DefaultSslRootStore::GetRootStore();
469
423
  } else {
470
- if (c != nullptr) ssl_server_destroy(&c->base.base);
471
- if (sc != nullptr) *sc = nullptr;
424
+ pem_root_certs = config->pem_root_certs;
425
+ root_store = nullptr;
426
+ }
427
+
428
+ grpc_core::RefCountedPtr<grpc_ssl_channel_security_connector> c =
429
+ grpc_core::MakeRefCounted<grpc_ssl_channel_security_connector>(
430
+ std::move(channel_creds), std::move(request_metadata_creds), config,
431
+ target_name, overridden_target_name);
432
+ const grpc_security_status result = c->InitializeHandshakerFactory(
433
+ config, pem_root_certs, root_store, ssl_session_cache);
434
+ if (result != GRPC_SECURITY_OK) {
435
+ return nullptr;
472
436
  }
473
- return retval;
437
+ return c;
438
+ }
439
+
440
+ grpc_core::RefCountedPtr<grpc_server_security_connector>
441
+ grpc_ssl_server_security_connector_create(
442
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_credentials) {
443
+ GPR_ASSERT(server_credentials != nullptr);
444
+ grpc_core::RefCountedPtr<grpc_ssl_server_security_connector> c =
445
+ grpc_core::MakeRefCounted<grpc_ssl_server_security_connector>(
446
+ std::move(server_credentials));
447
+ const grpc_security_status retval = c->InitializeHandshakerFactory();
448
+ if (retval != GRPC_SECURITY_OK) {
449
+ return nullptr;
450
+ }
451
+ return c;
474
452
  }